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