This is my home page and getting list data then creating List component as much as need. Then going to List component and creating list item. so creating new component using map function. I tried different ways for it but I can’t figure out. It goes infinite loop whatever I did.
Home.jsx
const [lists, setLists] = useState([]); useEffect(() => { const getRandomList = async () => { try { const res = await axios.get(`/lists${type ? "?type=" + type : ""}`, { headers: { "Content-Type": "application/json;charset=UTF-8", token: token, }, }); setLists(res.data); } catch (error) { console.log(error); } }; getRandomList(); }, [type]); return ( <div className="home"> <Navbar /> <Featured type={type} /> {lists.map((list, index) => { return <List key={index} list={list}/>; })} </div> ); }
in List component, creating List item component as much as need.
List.jsx
export default function List({ list }) { const [isMoved, setIsMoved] = useState(false); const [slideNumber, setSlideNumber] = useState(0); const [clickLimit, setClickLimit] = useState(window.innerWidth / 230); const [lists, setLists] = useState([]) const listRef = useRef(); useEffect( () =>{ const getList = ()=>{ setLists(list.content) } getList() },[list]) const handleClick = (direction) => { setIsMoved(true); let distance = listRef.current.getBoundingClientRect().x - 50; if (direction === "left" && slideNumber > 0) { setSlideNumber(slideNumber - 1); listRef.current.style.transform = `translateX(${230 + distance}px)`; } if (direction === "right" && slideNumber < 10 - clickLimit) { setSlideNumber(slideNumber + 1); listRef.current.style.transform = `translateX(${-230 + distance}px)`; } }; return ( <div className="list"> <span className="listTitle">Continue to watch</span> <div className="listWrapper"> <ArrowBackIosOutlined className="sliderArrow left" onClick={() => handleClick("left")} style={{ display: !isMoved && "none" }} /> <div className="listContainer" ref={listRef}> {lists.map((item, index) => { return <ListItem key={index} index={index} item={item} />; })} </div> <ArrowForwardIosOutlined className="sliderArrow right" onClick={() => handleClick("right")} /> </div> </div> ); }
last component here.
ListItem.jsx
export default function ListItem({ index, item }) { const [isHovered, setIsHovered] = useState(false); const [movie, setMovie] = useState({}); useEffect(() => { const getMovie = async (item) => { try { const res = await axios.get("/movies/find/" + item, { headers: { "Content-Type": "application/json;charset=UTF-8", token: token, }, }); setMovie(res.data); } catch (error) { console.log(error); } }; getMovie() }, [item]); return ( <div className="listItem" style={{ left: isHovered && Object.values(index) * 225 - 50 + Object.values(index) * 2.5, }} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} > <img src={movie.img} alt="" /> {isHovered && ( <> <video src={movie.trailer} autoPlay loop></video> <div className="itemInfo"> <div className="itemIcons"> <PlayArrow className="itemIcon" /> <Add className="itemIcon" /> <ThumbUpAltOutlined className="itemIcon" /> <ThumbDownAltOutlined className="itemIcon" /> </div> <div className="itemInfoTop"> <span>1 hour 14 mins</span> <span className="limit">{movie.limit}</span> <span>{movie.year}</span> </div> <div className="itemDescription">{movie.description}</div> <div className="itemGenre">{movie.genre}</div> </div> </> )} </div> ); }
Advertisement
Answer
Try to remove the useEffect
from the List
component and map
on the list.content
directly:
export default function List({ list }) { const [isMoved, setIsMoved] = useState(false); const [slideNumber, setSlideNumber] = useState(0); const [clickLimit, setClickLimit] = useState(window.innerWidth / 230); const listRef = useRef(); const handleClick = (direction) => { setIsMoved(true); let distance = listRef.current.getBoundingClientRect().x - 50; if (direction === "left" && slideNumber > 0) { setSlideNumber(slideNumber - 1); listRef.current.style.transform = `translateX(${230 + distance}px)`; } if (direction === "right" && slideNumber < 10 - clickLimit) { setSlideNumber(slideNumber + 1); listRef.current.style.transform = `translateX(${-230 + distance}px)`; } }; return ( <div className="list"> <span className="listTitle">Continue to watch</span> <div className="listWrapper"> <ArrowBackIosOutlined className="sliderArrow left" onClick={() => handleClick("left")} style={{ display: !isMoved && "none" }} /> <div className="listContainer" ref={listRef}> {list.content.map((item, index) => { return <ListItem key={index} index={index} item={item} />; })} </div> <ArrowForwardIosOutlined className="sliderArrow right" onClick={() => handleClick("right")} /> </div> </div> ); }