【问题标题】:React useEffect infinite loop fetching data from an apiReact useEffect 无限循环从 api 获取数据
【发布时间】:2020-07-25 15:52:16
【问题描述】:

您好,我正在尝试制作一个 twitter 克隆应用程序。我在客户端使用 React,在服务器端使用 Express,并使用 PostgreSQL 作为我的数据库。所以这就是问题所在,我正在尝试像这样使用useEffect

const [tweets, setTweets] = useState([]);
  const getTweets = async () => {
    const res = await api.get("/posts", {
      headers: { token: localStorage.token },
    });
    setTweets(res.data);
  };
  useEffect(() => {
    getTweets();
  }, [tweets]);

我不知道为什么它会无限循环,但我是否正确使用它?我希望每次发布推文时都更新推文。它工作正常,但它运行无限次。我只是希望它在发布推文时重新渲染。

这是我获取所有帖子的服务器代码:

async all(request: Request, response: Response, next: NextFunction) {
    return this.postRepository.find({
      relations: ["user"],
      order: {
        createdAt: "DESC",
      },
    });
  }

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    问题是每次你更改推文时它都会执行useEffect 并更改推文等等,所以它很自然地无限循环,解决方案是添加一个触发器,当你设置为 true 时推文被发布,所以解决方案是这样的

    const [tweets, setTweets] = useState([]);
    const [isFetching, setIsFetching] = useState(false);
      const getTweets = async () => {
        const res = await api.get("/posts", {
          headers: { token: localStorage.token },
        });
        setTweets(res.data);
      };
    
      useEffect(() => {
        getTweets();
        setIsFetching(false);
      }, [isFetching]);
    
    

    并设置一些逻辑以使用setIsFetching(true) 以执行useEffect

    PS:如果你在 useEffect 中使用空数组,它只会在组件被挂载时执行(在开始时)

    【讨论】:

    • 哦,我现在明白了。感谢您的解释!但是,如果我尝试使用 useEffect 实现新闻源(推文),这是最佳做法吗?
    • 是的,这是你应该使用的任何实时数据从 API 获取包括推文在内的各种列表!
    【解决方案2】:
    useEffect(() => {
        getTweets();
      }, [tweets]); // [tweets means that hook works every time 'tweets' state changes]
    

    所以你的 getTweets 函数设置 tweets => 随着 tweets 的改变,钩子再次工作 => 调用 getTweets => ... = 无限循环

    如果您想下载推文,请改用空数组 - 钩子将工作一次

    【讨论】:

    • 对不起,我无法理解你的解释:(但我现在明白了
    • 我写了和上面一个人一样的东西——你的钩子里有错误的依赖列表。
    【解决方案3】:

    传递空数组作为第二个参数调用一次,否则在每次推文更改时更改它都会重新触发,所以只要状态会改变,它就会像 Tarukami 解释的那样重新渲染。您可以做的一件事是检查下面提到的长度,因此不要比较整个对象,而只是比较长度

    useEffect(() => {
        getTweets();
      }, [tweets.length]);
    

    这可能会引发错误react-hooks/exhaustive-deps lint 错误(这是您可以使用的绕过方法)。 但是,如果您想要更严格的检查,您可以比较每次重新渲染时的 id(从数组中的所有元素创建一个哈希/键/id 并在每次渲染时比较它们),就像 [tweet id here]) // Only re-subscribe if id changes

    【讨论】:

      猜你喜欢
      • 2020-04-21
      • 2022-01-12
      • 2021-01-21
      • 2021-01-31
      • 2020-04-14
      • 2020-09-06
      • 2019-08-15
      • 2021-10-21
      相关资源
      最近更新 更多