Home > Blockchain >  While creating item from parent to child component, going to infinite loop in React
While creating item from parent to child component, going to infinite loop in React

Time:02-10

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,
      }}
      onm ouseEnter={() => setIsHovered(true)}
      onm ouseLeave={() => 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>
  );
}

CodePudding user response:

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>
  );
}
  • Related