Component Getting Rendered Infinite times in Nextjs - javascript

I am trying to render the TEXT CLOUD in my Nextjs app, but it is getting rendered infinite time.I am using Next JS. Please help
Here is the code and screenshots:
import dynamic from "next/dynamic";
import { useRef} from "react";
const container = '.tagcloud';
const texts = [
'3D', 'TagCloud', 'JavaScript',
'CSS3', 'Animation', 'Interactive',
'Mouse', 'Rolling', 'Sphere',
'6KB', 'v2.x',
];
const tag = {
radius: 100,
maxSpeed: 'normal',
initSpeed: 'fast',
direction: 135,
keep: true
}
const Text_cloud=dynamic(
() => {
const refTag=useRef();
return <span ref={refTag}>{TagCloud(container,texts,tag)}</span>;
},
{ ssr: false }
);
export default Text_cloud;
I am exporting this Component and using it in another page skills:
import React, { useState,useRef } from "react";
import Web from "../Component/web";
import Programming from "../Component/programming";
import Editing from "../Component/Editing";
import styles from "../styles/skill.module.css"
import Btn from "../Component/btn";
import Text_cloud from "../Component/text_cloud";
function Skill() {
const [skill, setskill] = useState("Web")
return (<>
<div className={styles.main}>
<ul className={styles.ruler}>
<a onClick={() => setskill("Web")} className={styles.skilla}><Btn name="Web Dev" /></a>
<a onClick={() => setskill("Programming")} className={styles.skilla}><Btn name="Programming" /></a>
<a onClick={() => setskill("Editing")} className={styles.skilla}><Btn name="Editing" /></a>
</ul>
<div className={styles.cld} >
<div className="tagcloud" >
<Text_cloud />
</div>
</div>
</div>
{skill === "Web" && <Web />}
{skill === "Programming" && <Programming />}
{skill === "Editing" && <Editing />}
</>)
}
export default Skill;
After running the server I get this output and error:
It get render two times
And the error it shows is:
Here is the error Screenshot
Please help me out here

Related

Display image from another js file

I've got a problem with showing image from js file. I really dont know what i can do with that. Can someone help me?
Code for main component:
import React from 'react'
import {jetData} from '../jetData'
const MainBar = () => {
return (
<div className='text-white'>
{jetData.map((data, key) => {
return (
<div key={key}>
{<img src={data.image} /> + data.name}
</div>
);
})}
</div>
)
}
export default MainBar
Code for js file with data:
import f18 from './assets/jets/f-18cd-hornet.png'
import f22 from './assets/jets/f-22-raptor.png'
import mig29 from './assets/jets/mig-29.png'
import su27 from './assets/jets/Sukhoi_Su-27SKM.png'
export const jetData = [
{
image: {f18},
name: 'F/A-18 Hornet'
},
{
image: {f22},
name: 'F-22 Raptor'
},
{
image: {mig29},
name: 'MiG-29'
},
{
image: {su27},
name: 'Su-27'
},
]
Check if this works i hope it will work sorry at this point i can not run it for you
return (
<div className="text-white">
{jetData.map((jet) => (
<div key={jet.id}>
<img src={jet.image} alt={jet.name} />
</div>
))}
</div>
);
I think what you are trying to do is this:
import logo from './logo.svg';
<img src={logo} className="App-logo" alt="logo" />
Which works fine with .svg files, but not with .jpg and .png. The reason seems to be that import logo from './logo.svg'; stores the path in the variable, but import f18 from './assets/jets/f-18cd-hornet.png stores a, what to me looks like, a string representation of the image.
I think this is the way to go:
export const jetData = [
{
image: './assets/jets/f-18cd-hornet.png',
name: 'F/A-18 Hornet'
}]
Your imports do not need to be in curly braces:
import f18 from './assets/jets/f-18cd-hornet.png'
import f22 from './assets/jets/f-22-raptor.png'
import mig29 from './assets/jets/mig-29.png'
import su27 from './assets/jets/Sukhoi_Su-27SKM.png'
export const jetData = [
{
image: f18,
name: 'F/A-18 Hornet'
},
{
image: f22,
name: 'F-22 Raptor'
},
{
image: mig29,
name: 'MiG-29'
},
{
image: su27,
name: 'Su-27'
},
]
Your map key will likely throw an error because you are using the index as a key. I would change it to the following
{jetData.map((data) => {
return (
<div key={data.name}>
<img src={data.image} alt={data.name} />
</div>
);
})}

axios doesnt fetch on refresh, only on first render

So I've been struggling for a while with retrieving data from APIs and or retrieving local json files. I am using React axios but even with the normal fetch method I am having the same issues. When I fetch the endpoint and save the code, my jsx refreshes and the data appears on the screen but then when I refresh the page, it's no longer there and doesn't appear when I refresh again and again. I have no idea what I am doing wrong. I tried to retrieve the data on the parent and set it as props but still the same problem.
My child component:
import React, { useEffect, useState } from 'react';
import './Card.scss';
import axios from 'axios';
import { ellipsisIcon } from '../../constants/images';
import dataJson from './data.json';
const Card = ({ name, color, icon, currentTime }) => {
const [data, setData] = useState([]);
const [daily, setDaily] = useState([]);
const [weekly, setWeekly] = useState([]);
const [monthly, setMonthly] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await axios.get('data.json');
setData(result.data);
setData(
data.filter((item) => {
return item.title === name;
}),
);
setDaily(data[0].timeframes.daily);
setWeekly(data[0].timeframes.weekly);
setMonthly(data[0].timeframes.monthly);
};
fetchData();
}, []);
return (
<div className="card" style={{ backgroundColor: `${color}` }}>
<img src={icon} alt={`${name} icon`} />
<div className="card__container bg-blue">
<div className="card__top-container flex">
<p className="text-white ">{name}</p>
<div className="card__top__elipse-container">
<img src={ellipsisIcon} alt="ellipsis" />
</div>
</div>
<div className="card__bottom-container">
{currentTime === 0 && (
<>
<h1 className="fs-900 text-white">{daily.current}hrs</h1>
<div className="card__bottom__prev-container">
<p className="text-accent ">
Yesterday -<span>{daily.previous}hrs</span>
</p>
</div>
</>
)}
{currentTime === 1 && (
<>
<h1 className="fs-900 text-white">{weekly.current}hrs</h1>
<div className="card__bottom__prev-container">
<p className="text-accent ">
Last Week -<span>{weekly.previous}hrs</span>
</p>
</div>
</>
)}
{currentTime === 2 && (
<>
<h1 className="fs-900 text-white">{monthly.current}hrs</h1>
<div className="card__bottom__prev-container">
<p className="text-accent">
Last Month -<span>{monthly.previous}hrs</span>
</p>
</div>
</>
)}
</div>
</div>
</div>
);
};
export default Card;
My App (Parent):
import { useState, useEffect } from 'react';
import Card from './components/Card/Card';
import {
pbImage,
ellipsisIcon,
exerciseIcon,
playIcon,
careIcon,
socialIcon,
studyIcon,
workIcon,
} from './constants/images';
const cards = [
{
name: 'Exercise',
color: 'hsl(var(--clr-exercise))',
icon: exerciseIcon,
},
{
name: 'Play',
color: 'hsl(var(--clr-play))',
icon: playIcon,
},
{
name: 'Self Care',
color: 'hsl(var(--clr-care))',
icon: careIcon,
},
{
name: 'Social',
color: 'hsl(var(--clr-social))',
icon: socialIcon,
},
{
name: 'Study',
color: 'hsl(var(--clr-study))',
icon: studyIcon,
},
{
name: 'Work',
color: 'hsl(var(--clr-work))',
icon: workIcon,
},
];
function App() {
const [selectedTime, setSelectedTime] = useState(2);
return (
<div className="app bg-dark">
<div className="main__container grid">
<div className="side__card-container">
<div className="side__card__top flex">
<div className="side__card__top__pb-container">
<img
src={pbImage}
alt="pb"
className="side__card__top__pb-image pb-image"
/>
</div>
<div className="side__card__top__person-container">
<p className="fs-600 text-accent">Report for</p>
<h2 className="fs-800 text-white">Jeremy Robson</h2>
</div>
</div>
<div className="side__card__bottom">
<div>Daily</div>
<div>Weekly</div>
<div>Monthly</div>
</div>
</div>
{cards.map((card, _index) => (
<Card
key={_index}
name={card.name}
color={card.color}
icon={card.icon}
currentTime={selectedTime}
/>
))}
</div>
</div>
);
}
export default App;
As I mentioned in the comments, states are updated asynchronously. So, you should be careful when you use a state immediately after setting its value. In your case, you shouldn’t use the data state because you are not sure that it has a value. Try changing to this.
useEffect(() => {
const fetchData = async () => {
const result = await axios.get('data.json');
const filteredData = result.data.filter((item) => {
return item.title === name;
})
setData(filteredData);
// make sure result data isn’t empty
setDaily(result.data[0].timeframes.daily);
setWeekly(result.data[0].timeframes.weekly);
setMonthly(result.data[0].timeframes.monthly);
};
fetchData();
}, []); // "[]" makes the useEffect callback only run after the first render

React js Active Menu Item with useState

I've been trying to add a menu with an active styling by using useState in React js but for some reasons it only stays in active state, does not go back to inactive when you click on the other menu item. On the other hand, it works perfectly when I pass down my active state as props from Sidebar.js
React version: "react": "^17.0.2"
Node version: v16.0.0
Here is my code:
SideLink.js
import React, {useState} from "react";
const SideLink = ({ name, Icon}) => {
const [active, setactive] = useState("Home")
return (
<li className="group" onClick={() => setactive(name)}>
<a href={name.toLowerCase()} className="cursor-pointer block mb-2 pointer-events-none">
<div className="inline-block">
<div
className={`
flex items-center
group-hover:bg-blue-50
group-hover:text-red-500
rounded-full pl-2 py-3 pr-6
${active === name ? "text-red-400" : ""}
`}
>
<Icon />
<span className="ml-2 font-bold text-xl">{name}</span>
</div>
</div>
</a>
</li>
);
};
export default SideLink;
Sidebar.js
import React, {useState} from "react";
import SideLink from "../../assets/components/SideLink";
import {
BookmarksIcon,
ExploreIcon,
HomeIcon,
ListsIcon,
MessagesIcon,
MoreIcon,
NotificationsIcon,
ProfileIcon,
} from "../../assets/icons/Icon";
const sideLinks = [
{
name: "Home",
icon: HomeIcon,
},
{
name: "Explore",
icon: ExploreIcon,
},
{
name: "Notifications",
icon: NotificationsIcon,
},
{
name: "Messages",
icon: MessagesIcon,
},
{
name: "Bookmarks",
icon: BookmarksIcon,
},
{
name: "Lists",
icon: ListsIcon,
},
{
name: "Profile",
icon: ProfileIcon,
},
{
name: "More",
icon: MoreIcon,
},
];
const Sidebar = () => {
return (
<div className="w-72 flex flex-col justify-between px-2">
<div>
<nav>
<ul>
{sideLinks.map(({ name, icon }) => (
<SideLink key={name} name={name} Icon={icon}/>
))}
</ul>
</nav>
</div>
<div>bottom</div>
</div>
);
};
export default Sidebar;
Thank you!
Keep in mind that in your example each SideLink maintain their own independent state. When one of those call its own setactive, it doesn't have any effect on any other.
What I think you really want is one piece of state that live in a central location, the parent component, Sidebar, and forward to SideLink that value and the means to change that it.

NextJS error message: Failed prop type: The prop `href` expects a `string` or `object` in `<Link>`, but got `undefined` instead

I'm implementing a header from a GatsbyJS project into NextJS project and get the following error message:
"Error: Failed prop type: The prop href expects a string or object in <Link>, but got undefined instead."
When removing the following from the header.jsx it does not provide any error messages:
<MenuButton item={{ icon: "/images/icons/hamburger.svg" }} />
Can you guide me on what I'm doing wrong?
This is my header.jsx file:
import React, { useEffect, useRef, useState } from "react";
import styled from "styled-components";
import Link from "next/link";
import { menuData } from "../../data/menuData";
import MenuButton from "../buttons/MenuButton.jsx";
import Image from "next/image";
import MenuTooltip from "../tooltips/MenuTooltip";
export default function Header() {
const [isOpen, setIsOpen] = useState(false);
const ref = useRef();
const tooltipRef = useRef();
function handleClick(event) {
setIsOpen(!isOpen);
event.preventDefault();
}
function handleClickOutside(event) {
if (
ref.current &&
!ref.current.contains(event.target) &&
!tooltipRef.current.contains(event.target)
) {
setIsOpen(false);
}
}
useEffect(() => {
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);
return (
<Wrapper>
<Link href="/">
<Logo>
<Image
src="/images/logos/logo.png"
alt="Logo"
width={120}
height={100}
/>
</Logo>
</Link>
<MenuWrapper count={menuData.length} ref={ref}>
{menuData.map((item, index) => (
<MenuButton key={index} item={item} />
))}
<HamburgerWrapper onClick={(event) => handleClick(event)}>
<MenuButton item={{ icon: "/images/icons/hamburger.svg" }} />
</HamburgerWrapper>
</MenuWrapper>
<div ref={tooltipRef}>
<MenuTooltip isOpen={isOpen} />
</div>
</Wrapper>
);
}
This is my menuTooltip.jsx file:
import React from "react";
import styled from "styled-components";
import { tooltipData } from "../../data/menuData";
import MenuButton from "../buttons/MenuButton";
export default function MenuTooltip(props) {
const { isOpen } = props;
return (
<Wrapper isOpen={isOpen}>
{tooltipData.map((item, index) => (
<MenuButton key={index} item={item} />
))}
</Wrapper>
);
}
This is my MenuButton.jsx file:
import React from "react";
import styled from "styled-components";
import Link from "next/link";
import { Caption } from "../styles/TextStyles";
export default function MenuButton(props) {
const { item } = props;
return (
<Link href={item.link} onClick={props.onClick} key={props}>
<MenuItem hasTitle={!item.title ? false : true}>
<img src={item.icon} />
{item.title}
</MenuItem>
</Link>
);
}
This is my menuData.jsx file:
export const menuData = [
{ title: "Learn", icon: "/images/icons/learner02_dm.svg", link: "/learn" },
{
title: "Articles",
icon: "/images/icons/article_light.svg",
link: "/articles",
},
{
title: "Community",
icon: "/images/icons/community_light.svg",
link: "/community",
},
{
title: "Entrepreneurs",
icon: "/images/icons/business02_light.svg",
link: "/entrepreneurs",
},
];
export const footerMenuData = [
{ title: "Learn", icon: "/images/icons/learner02_dm.svg", link: "/learn" },
{
title: "Articles",
icon: "/images/icons/article_light.svg",
link: "/articles",
},
{
title: "Community",
icon: "/images/icons/community_light.svg",
link: "/community",
},
{
title: "Entrepreneurs",
icon: "/images/icons/business02_light.svg",
link: "/entrepreneurs",
},
{
title: "Updates",
icon: "/images/icons/calendar_light.svg",
link: "/updates",
},
{
title: "Help",
icon: "/images/icons/help_light.svg",
link: "/help",
},
];
export const tooltipData = [
{ title: "Learn", icon: "/images/icons/learner02_dm.svg", link: "/learn" },
{
title: "Articles",
icon: "/images/icons/article_light.svg",
link: "/articles",
},
{
title: "Community",
icon: "/images/icons/community_light.svg",
link: "/community",
},
{
title: "Entrepreneurs",
icon: "/images/icons/business02_light.svg",
link: "/entrepreneurs",
},
];
You add a tag a in the link like that :
<link href....>
<a>
<image>
<p> text </p>
</a>
</link>
I often get this error too...
Oh gosh! I was stuck with this problem for so long and finally managed to fix it. While I am happy that the accepted answer worked for you, sadly it didn't for me. So, I am leaving here the fix that I found on the discussion thread of NextJS's official GitHub repo.
Instead of passing the link key directly into the Link's href prop:
<Link href={item.link} {...other props}>...</Link>
Pass it in string literals like this:
<Link href={`${item.link}`} {...other props}>...</Link>
You may wrap the children of the Link component in a <a> tag if you want but that's not required, and mine is working without that. FYI, I had some SVG icons inside the Link components that were creating all this fuss. Sigh!
for anyone else who is migrating from react-router-dom to next.js built-in Link component.
this error happened to me because I was migrating from react-router-dom to the built-in Link component in Next.js, and I forgot to change the to="" property in <Link></Link> component to href=""

ReactJS - element type is invalid expected a string but got undefined

I am trying to use this package to use scroll lock on a react component.
When I run a build I get the following error:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.
I'm importing the package as suggested, I've checked the source file of the package to make sure it's not named something else and as it is exported:
exports.default = ScrollLock;
How can I resolve this?
Here is my component code:
import React from 'react';
import PropTypes from 'prop-types';
import ReactSVG from 'react-svg';
import Slider from 'react-slick';
import ScrollLock from 'react-scroll-lock-component';
import MobileSVG from '../../../assets/svg/icons/Mobile_Icon_Option2.svg';
import TabletSVG from '../../../assets/svg/icons/Tablet_Icon_Option2.svg';
import DesktopSVG from '../../../assets/svg/icons/Desktop_Icon_Option2.svg';
import styles from './styles.css';
const deviceIcons = {'mobile': MobileSVG, 'tablet': TabletSVG, 'desktop': DesktopSVG};
import BackToTopButton from '../BackToTopButton';
export default class ProductComponent extends React.Component {
constructor(props) {
super(props);
this.scroll = this.scroll.bind(this);
}
scroll(y){
y > 0 ? (
this.slider.slickNext()
) : (
this.slider.slickPrev()
)
}
componentWillMount(){
window.addEventListener('wheel', function(e){
//this.scroll(e.wheelDelta);
})
}
render() {
const {productData} = this.props
//Slider settings
const settings = {
dots: true,
infinite: false,
speed: 500,
fade: true,
arrows: false,
centerMode: true,
slidesToShow: 1,
slidesToScroll: 1
}
//Slider items
const sliderItems = productData.map((obj, i) => {
return (
<div className="product-component row" key={i}>
<div className="product-component-image-wrap col-xs-12 col-sm-8">
<span className="product-heading">{obj.category}</span>
<div className="product-detail-wrap">
<img className="product-component-image" src={`${process.env.DB_URL}${obj.image}`} />
<ul className="list-device-support">
{obj.categoryDeviceSupport.map((obj, i) => {
return (<li key={i}>
<span className="svg-icon">
<ReactSVG path={deviceIcons[obj.value]} />
</span>
<span className="product-label">{obj.label}</span>
</li>)
})}
</ul>
</div>
</div>
<div className="product-component-info col-xs-12 col-sm-3">
<span className="align-bottom">{obj.title}</span>
<p className="align-bottom">{obj.categoryBrief}</p>
</div>
</div>
)
});
return (
<div className="product-component-wrap col-xs-12">
<ScrollLock>
<Slider {...settings} ref={slider => this.slider = slider}>
{sliderItems}
</Slider>
<BackToTopButton scrollStepInPx="50" delayInMs="7" />
</ScrollLock>
</div>
)
}
}
ProductComponent.propTypes = {
productData: PropTypes.array
};
ProductComponent.defaultProps = {
productData: []
};

Categories