是否有更好的方法来组织这个React页面与异步调用的API?



我有这个useEffect应该只运行一次。因此,我将router.query.something设置为依赖项。请求必须等待router.query.something被水化,然后只有当值为真时才发出请求。

这似乎是一个过于复杂的函数,向API发出一个简单的一次性请求,但我还没有找到一个更清晰的方法来实现它。

const MyPage = () => {
const [user, setUser] = useState(null)
const router = useRouter()
useEffect(async () => {
try {
if (router.query.something) {
const res = await api.get(`/resetTokens/${router.query.something}`)
setUser(res.data)
}
} catch (err) {
setUser(null)
}
}, [router.query.something])
return (<div>...</div>)
}

通常情况下,我会使用getServerSideProps,但在这种情况下,我不能,因为请求正在设置cookie。如果我使用getServerSideProps, cookie不会传递到客户端。

您应该注意两件事:

首先,useEffect不应该使用async函数。在控制台中应该有一个关于在useEffect中使用async的警告。

其次,您应该清理useEffect,因为您正在处理承诺。如果不进行清理,可能会遇到内存泄漏,从而导致意想不到的结果。

你的代码应该是这样的

useEffect(() => {
let isMounted = true;
if (router.query.something) {
api.get(`/resetTokens/${router.query.resetToken}`)
.then(res=> {
if(!isMounted) return;
setUser(res.data)
})
.catch(e => {
if(!isMounted) return;
setUser(null)
});

}

return () => {
isMounted = false;
};
}, [router.query.something])

您也可以尝试使用AbortController执行此操作。学术界有一个很好的博客,解释了正在发生的事情以及如何解决。https://academind.com/tutorials/useeffect-abort-http-requests/

const MyPage = () => {
const [user, setUser] = useState(null)
const router = useRouter()
useEffect(() => {
const abortController = new AbortController();
const fetchData = async () => {
try {
const res = fetch(`/resetTokens/${router.query.resetToken}`, { signal: abortController.signal });
setUser(res.data)
} catch (e) {
setUser(null)
}
};

if (router.query.something) {
fetchData();
}
return () => {
abortController.abort();
};
}, [router.query.something]);
return (<div>...</div>)
}

相关内容

  • 没有找到相关文章

最新更新