You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

API调用为何出现取消?父子组件状态传递引发的请求问题

问题解决:父子组件共享open状态导致子组件API请求被取消

核心问题是状态切换引发的请求竞态:当点击按钮把open设为true,子组件触发useEffect调用getUser,但如果在请求完成前关闭Modal(把open设为false),open状态变化会再次触发子组件的useEffect,同时React会自动取消未完成的异步请求(尤其是严格模式下),导致getUser调用失败。

解决步骤:

1. 用AbortController管理请求生命周期

给每个getUser请求绑定控制器,在组件useEffect清理时取消旧请求,避免竞态冲突。

2. 请求完成后检查当前open状态

确保只有当open仍为true时,才更新user状态,避免无效的状态更新。

修改后的代码:

parent.tsx(父组件逻辑无需大改)

const [open, setOpen] = useState(false);
const [post, setPost] = useState([]);

const fetchData = async() => {
  const res = await getPost();
  setPost(res);
}

useEffect(() => {
  fetchData();
}, [open]);

<Child open={open} setOpen={setOpen} />

Child.tsx

const Child = ({open, setOpen}) => {
  const [user, setUser] = useState();

  const fetchData = async(controller: AbortController) => {
    try {
      // 把AbortSignal传给API,用于后续取消请求
      const res = await getUser({ signal: controller.signal });
      // 请求完成后检查open状态,确保Modal仍处于打开状态
      if (open) {
        setUser(res);
      }
    } catch (err) {
      // 主动取消的请求无需报错
      if (!(err instanceof DOMException && err.name === 'AbortError')) {
        console.error('获取用户数据失败:', err);
      }
    }
  }

  useEffect(() => {
    const controller = new AbortController();
    // 仅当open为true时发起请求,避免无效调用
    if (open) {
      fetchData(controller);
    } else {
      setUser(null); // 关闭Modal时清空用户数据
    }
    
    // 组件卸载或open状态变化时,取消未完成的请求
    return () => controller.abort();
  }, [open]);

  return (
    <>
      <button onClick={() => setOpen(true)}>Click</button>
      {open && user && (
        <Modal onCancel={() => {
          setOpen(false);
          setUser(null);
        }} />
      )}
    </>
  )
}

关键说明:

  • AbortController能让我们在状态变化时主动取消旧请求,避免无用的网络请求和状态更新冲突。
  • 请求完成后检查open状态,确保只有Modal处于打开状态时才更新user数据,避免关闭后触发无效更新。
  • useEffect的清理函数调用controller.abort(),确保组件卸载或open状态变化时,旧请求被及时终止。

内容的提问来源于stack exchange,提问作者user22971224

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:15:04