前端 - React - - useEffect处理网络请求
2026/6/26 8:00:36 网站建设 项目流程
  • 问题还原:

在例如搜索场景下,用户输入a,发起网络请求“a”,紧接着输入b,又发起网络请求“ab”,此时因网络问题先返回了“ab”的结果,再返回“a”的结果,就导致输入ab,展示的是a的结果。

  • 方案一 async/await(错误)

const [list,setList] = useState([...]); useEffect(async ()=>{ const res = await getList(id) setList(res) },[id])

useEffect设计规则:要么不返回任何东西,要么返回清理函数。async隐式返回Promise,所以违反useEffect规则。

  • 方案二 开关控制/防抖(可行):

const [list,setList] = useState([...]); useEffect(()=>{ let isFlag = true; getList(id).then((res)=>{ if(ifFlag){ setList(res) } }); return ()=>{isFlag = false} },[id])

当getList网络请求还未响应时,依赖项id改变了,则react会先执行完第一次的useEffect,将第一个isFlag改为false,终止setList,然后第二次执行useEffect。

缺点1:如果不执行setList,则此次网络请求就是多余的,会浪费网络资源。

缺点2:如果组件因为非依赖项问题而切换,比如在网络请求中被销毁,则会导致setList依然执行。

  • 方案三 AbortController(推荐):

const [list,useList] = useState([...]); useEffect(() => { const controller = new AbortController(); getList(id, { signal: controller.signal }) .then((res) => { setList(res); }) .catch((error) => { if (error.name !== 'AbortError') { // 处理主动终止的错误 } }); return () => { controller.abort(); // 取消正在进行的请求 }; }, [id]);

AbortController对象(浏览器内置api)生成一个唯一值(controller.signal),当网络请求中,执行了清除函数,那么signal则会发生改变,请求就会进入catch。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询