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

自定义useAsyncEffect依赖溢出:如何实现单次运行+依赖更新触发

问题分析

你开发的useAsyncEffect Hook在依赖项为空数组时出现浏览器溢出,核心原因是Hook内部未正确处理异步操作的清理逻辑,或是状态更新触发了无限重渲染循环。当依赖为空数组时,预期仅执行一次,但错误的状态更新逻辑会导致组件反复渲染,最终引发溢出。

修复方案

要实现「仅运行一次,依赖更新时重新运行」的目标,需确保Hook满足:异步操作的清理、依赖变化时重新执行、避免无限重渲染。以下是修正后的useAsyncEffect实现:

import { useEffect, useRef, useState } from 'react';

const useAsyncEffect = <T>(
  effect: () => Promise<T | undefined>,
  deps: React.DependencyList
) => {
  const [data, setData] = useState<T | undefined>();
  const [error, setError] = useState<Error | undefined>();
  const [loading, setLoading] = useState(true);
  const isMounted = useRef(true);

  useEffect(() => {
    isMounted.current = true;

    const execute = async () => {
      try {
        setLoading(true);
        const result = await effect();
        if (isMounted.current) {
          setData(result);
          setError(undefined);
        }
      } catch (err) {
        if (isMounted.current) {
          setError(err as Error);
          setData(undefined);
        }
      } finally {
        if (isMounted.current) {
          setLoading(false);
        }
      }
    };

    execute();

    return () => {
      isMounted.current = false;
    };
  }, deps);

  return { data, error, loading };
};

export default useAsyncEffect;
关键改进点
  • 挂载状态追踪:用useRef的isMounted标记组件是否仍处于挂载状态,避免异步操作完成后更新已卸载组件的状态,从根源上减少无效重渲染。
  • 受控状态更新:仅在组件挂载时更新data、error、loading状态,防止无效状态更新触发循环渲染。
  • 依赖正确绑定:将传入的deps直接绑定到内部useEffect,确保依赖变化时重新执行异步逻辑;当deps为空数组时,仅在组件挂载时执行一次。
使用验证

用你提供的示例代码测试:

import useAsyncEffect from "./useAsyncEffect";

const useSomethingExample = ({ processes, datasets }) => {
  console.log(processes);
  console.log(datasets);

  return useAsyncEffect(async () => {
    await new Promise((resolve) => {
      setTimeout(() => {
        resolve({ processes, datasets });
      }, 300);
    });
  }, [processes, datasets]);
};

export default useSomethingExample;

当processes和datasets为空数组时,Hook仅执行一次,不会引发浏览器溢出;当这两个依赖项更新时,Hook会自动重新执行异步逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:34:58