我陷入了 react.js 的无限循环。如何解决这个问题?

I Got Stuck in infinite loop in react.js. How to resolve this?

我陷入了 react.js 的无限循环。如何解决?

useEffect(() => {
    fetch("https://react-http-d55a9-default-rtdb.firebaseio.com/todo.json")
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        console.log(data);
        setUsersList((prev) => [...prev]);           //cause of infinite loop
      });
  }, [usersList]);

传递给 useEffect 的依赖列表决定了效果何时再次 运行。无限循环正在发生,因为此效果会导致 usersList 发生变化,从而再次触发效果 运行。

由于此效果不使用任何其他变量,因此它的依赖列表中不需要任何内容​​:

useEffect(() => {
  fetch(...)
  // ...
}, []); // leave this empty, so the effect only runs when the component mounts

如果你的 URL 依赖于道具或其他东西,那么你希望它在依赖列表中:

useEffect(() => {
  fetch(`https://example.com/todo/${props.id}`)
    .then(...)

  // Since the URL depends on the id prop, the effect should re-run if it changes
}, [props.id]);

你有一个无限循环,因为你的 useEffect 依赖数组有 usersList 并且同时你在你的 useEffect 函数中更新这个变量。所以当组件安装时你的 useEffect 运行s 更新你的 usersList 这使得 useEffect 运行 再次更新你的 usersList 这使得再次 运行 等等...
要解决此问题,请从依赖项数组中删除 usersList 并使用一个空数组:[]。如果你这样做,你的 useEffect 将 运行 一次,当你的组件安装时。

根据提出的问题,您希望 userList 每次更新时都被监视。我们可以做的是再定义一个状态变量,如代码中提到的 isFetched,或者如果您使用的是 redux,则可以将其放在那儿,因为如果我们只观察 userList 变量,那么它会陷入无限循环,因为设置 userList 是发生在 useEffect 本身。在 isFetched 的帮助下,我们可以管理何时调用 api 以及每当标志为 false 时调用 api.

现在在代码中我又添加了一个状态变量作为 setCount,因为我不知道你想调用你的 api 多少次。所以你可以把你的条件放在那里,当你的条件满足时停止调用。

function App() {
  const [userList, setUserList] = useState([]);
  const [isFetched, setIsFetched] = useState(false);
  const [, setCount] = useState(3);

  const callApiPending = useCallback(()=>{
    fetch("https://react-http-d55a9-default-rtdb.firebaseio.com/todo.json")
    .then((response) => response.json())
    .then((json) => {
      setUserList((prev) => [...prev, ...json]);
      setCount((cnt) => {
        if(cnt - 1 === 0){
          setIsFetched(true);
        }
        return cnt - 1;
      });
      
    });
  }, []);

  useEffect(() => {
    if (!isFetched) {
      callApiPending();
    }
  }, [isFetched, userList, callApiPending]);

  return <div>Executing....</div>;
}

如果 usersList 发生变化,您 运行 获取。即使 userList 的内容与之前的内容相同,javascript 也会按其更改进行解释。试试这个。

[1,2,3] == [1,2,3]

可能 return 错误。您可以使用用于检查是否获取数据的标志而不是使用数组。