React useEffect无限循环从api获取数据

时间:2020-07-25 15:52:16

标签: reactjs react-hooks

嗨,我正在尝试制作一个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",
      },
    });
  }

3 个答案:

答案 0 :(得分: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中使用一个空数组,则仅在安装组件时(开始时)执行它

答案 1 :(得分:0)

.className

因此,您的getTweets函数设置了tweets =>,当tweets更改时,钩子又可以正常工作=>调用getTweets => ... =无限循环

如果要下载tweet,请改用空数组-钩子将起作用一次

答案 2 :(得分:0)

将空数组作为第二个arg传递一次,否则将在每次tweet更改时对其进行更改,它将重新触发,因此只要状态发生更改,它就会像Tarukami所解释的那样重新呈现。您可以做的一件事是检查如下所示的长度,以便不比较整个对象,而只是比较长度

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

这可能会引发错误react-hooks/exhaustive-deps棉绒错误(您可以绕过它,可以使用它)。 但是,如果您想进行更严格的检查,可以像这样[tweet id here]) // Only re-subscribe if id changes

那样,比较每个重新渲染的ID(从数组中的所有元素创建一个哈希/键/ ID,然后在每个渲染中进行比较)。