简体   繁体   English

反应 useEffect() 无限循环

[英]React useEffect() Infinite loop

I was trying to replicate a personal project to set a Spinner loader while the data fetch is being load but I got another error before.我试图复制一个个人项目以在加载数据时设置 Spinner 加载器,但我之前遇到了另一个错误。

I was reading in other questions like this one , that in order to avoid a useEffect() infinite loop I have to add an empty array to the end, but still it doesn't work.我正在阅读类似这样的其他问题,为了避免useEffect()无限循环,我必须在最后添加一个空数组,但它仍然不起作用。

This is my code, it just re-renders infinitely despite the empty array added.这是我的代码,尽管添加了空数组,但它只是无限地重新渲染。

src/components/Users.js src/components/Users.js

import React, { useState, useEffect, useContext } from "react";
import GlobalContext from "../context/Global/context";

export default () => {
  const context = useContext(GlobalContext);
  const [users, setUsers] = useState([]);

  async function getUsers() {
    context.setLoading(true);
    const response = await fetch("https://jsonplaceholder.typicode.com/users");
    if (response.ok) {
        context.setLoading(false);
        const data = await response.json();
        setUsers(data);
    } else {
        console.error('Fetch error');
    }
  }

  useEffect(() => {
    getUsers();
  }, []);

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
};

This is the non-working Sandbox , I am not sure why this is happening, any comments are appreciated.这是非工作沙箱,我不确定为什么会发生这种情况,任何意见表示赞赏。

The problem is you keep mounting and then umounting the Users component.问题是您继续安装然后卸载用户组件。 The <App> renders, and loading is false, so it renders <Users> . <App>呈现,并且加载为假,因此它呈现<Users> Since Users rendered its effect gets run which immediately sets loading to true.由于用户渲染它的效果得到运行,它立即将加载设置为 true。

Since loading is now true, <App> rerenders, and no longer has a <Users> component.由于加载现在为真, <App>渲染,并且不再具有<Users>组件。 You have no teardown logic in your effect, so the fetch continues, and when it's done, it sets loading to false and sets users to the data it got.您的效果中没有拆卸逻辑,因此提取继续进行,完成后,它将加载设置为 false 并将用户设置为它获得的数据。 Trying to set users actually results in this error in the console, which points out that Users is unmounted:尝试设置用户实际上会在控制台中导致此错误,它指出用户已卸载:

proxyConsole.js:64 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
    in _default (at App.js:25)

And now that loading has been set to false, the process repeats.现在加载已设置为 false,重复该过程。

The solution to this is to have the data loading be in a component that stays mounted.对此的解决方案是让数据加载在保持挂载的组件中。 Either change App to not unmount Users, or move the fetching up to App and pass the data as a prop.要么将 App 更改为不卸载用户,要么将提取移动到 App 并将数据作为道具传递。

I think the issue is because of我认为这个问题是因为

context.setLoading(false);

just remove this line from your getUsers function and add a separate useEffect hook.只需从getUsers函数中删除这一行并添加一个单独的useEffect钩子。

useEffect(() => {
   context.setLoading(false);
}, [users]) //Run's only when users get changed

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM