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

React自定义hook传入空对象触发无限重渲染,有没有更优解决办法?

问题复现

自定义Hook代码

export function myHook<TVariables = Record<string,string>> (variables?: TVariables) {
    const [result, setResult] = useState<number>();

    const fooFunction = (variables?: TVariables) => {
       // 实际业务中会对variables做对应处理
       setResult(666);
    }

    useEffect(() => {
        fooFunction(variables);
    }, [variables])
    
    return result;
}

组件调用代码

export interface IMyVariables {
    // 此处为空接口,仅为示例使用
}

const MyComponent: React.FunctionComponent = () => {
  const variables = {};
  const result = myHook<IMyVariables>(variables);
  return <></>;
}

问题说明

组件每次渲染都会生成新的空对象引用,React对useEffect依赖做浅比较时会判定variables发生变更,触发「执行effect→更新state→组件重渲染」的无限循环。
目前可行的临时方案是用useMemo缓存空对象保证引用稳定:const params = useMemo(() => { return {}; }, []);

更优雅的解决方案

以下三个方案均可解决问题,可根据实际业务场景选择:

  • 方案1:Hook内部设置默认值兜底
    将空对象常量提到Hook外部作为默认入参,外部无参数时直接不传值即可,无需额外处理引用:
    // 常量定义在Hook外部,全局唯一稳定引用
    const EMPTY_OBJECT = {} as const;
    export function myHook<TVariables = Record<string,string>> (variables: TVariables = EMPTY_OBJECT as TVariables) {
      // 原有逻辑不变
      const [result, setResult] = useState<number>();
      const fooFunction = (variables?: TVariables) => {
        setResult(666);
      }
      useEffect(() => {
        fooFunction(variables);
      }, [variables])
      
      return result;
    }
    
    组件调用简化为:const result = myHook<IMyVariables>()
  • 方案2:使用深度比较的useEffect
    若业务中经常需要传入对象类型依赖,可将Hook内的原生useEffect替换为深度比较版本,直接对比对象内容而非引用:
    // 仅替换useEffect即可,外部调用无需修改
    useDeepCompareEffect(() => {
      fooFunction(variables);
    }, [variables])
    
  • 方案3:抽离全局稳定常量
    若不想修改Hook内部逻辑,可将常用的空对象、空数组抽成全局公共常量,组件直接引用即可保证引用稳定:
    // 全局常量文件定义
    export const EMPTY_OBJ = {} as const;
    export const EMPTY_ARR = [] as const;
    
    组件内调用:const variables = EMPTY_OBJ as IMyVariables

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 09:06:10