React中如何基于首个API请求的state发起单次二次API请求
解决React中依赖前序API响应的二次请求问题
你需要给第二个useEffect添加listID作为依赖项,并且在内部判断listID不为空时再发起请求,这样就能保证只在listID更新为有效值时执行一次请求:
useEffect(() => { // 只有当listID存在时才发起请求 if (!listID) return; console.log("listID = " + listID); axios.get(`/listcontent/user/${listID}`) .then((response) => { console.log(response.data); setListContent(response.data); }) .catch((err) => { console.error(err); }); }, [listID]); // 依赖listID,当它变化时触发
为什么之前的方法无效:
- 空依赖的第二个useEffect:
useEffect的空数组依赖意味着它只会在组件挂载时执行一次,这时候第一个API请求还没完成,listID还是初始的null,所以请求会失败。 - 组件内直接写if判断:组件每次渲染(比如
listnames、listcontent更新时)都会执行这段代码,所以会重复发起请求。 - 用sss变量控制次数:每次组件渲染都会重新声明
let sss = 0,这个变量无法跨渲染保存状态,条件永远成立,还是会重复请求。
额外优化:取消请求防止内存泄漏
如果组件在请求完成前卸载,可能会导致内存泄漏,可以用AbortController来取消请求:
useEffect(() => { if (!listID) return; const controller = new AbortController(); const signal = controller.signal; axios.get(`/listcontent/user/${listID}`, { signal }) .then((response) => { setListContent(response.data); }) .catch((err) => { if (err.name !== 'CanceledError') { console.error(err); } }); // 组件卸载或依赖变化时取消请求 return () => controller.abort(); }, [listID]);
另一种思路:链式调用API请求
如果第二个请求完全依赖第一个请求的结果,也可以直接在第一个请求的then里发起第二个请求,这样不需要额外的useEffect:
useEffect(() => { axios.get(`/lists/user/${thisUserID}`) .then((response) => { const firstList = response.data[0]; setListNames(firstList.listName); setListID(firstList._id); // 直接发起第二个请求 return axios.get(`/listcontent/user/${firstList._id}`); }) .then((response) => { setListContent(response.data); }) .catch((err) => { console.error(err); }); }, []);
内容的提问来源于stack exchange,提问作者Marcus
相关产品推荐
相关产品推荐

