在从父组件到子组件创建项目时,在 React 中进入无限循环

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

这是我的主页,获取列表数据然后根据需要创建列表组件。 然后转到列表组件并创建列表项。所以使用 map 函数创建新组件。我尝试了不同的方法,但我无法弄清楚。无论我做什么,它都会无限循环。

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

在List组件中,根据需要创建List item组件。

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

这里是最后一个组成部分。

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

尝试从 List 组件中删除 useEffect 并直接从 list.content 中删除 map

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