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

父组件传入数组作为useMemo依赖触发无限重渲染问题

问题原因

每次父组件渲染时,keys={['title', 'description']}会创建一个新的数组引用——JavaScript里数组字面量每次执行都会生成全新的对象,哪怕内容完全一致。这就导致子组件useMemo的依赖项keys每次都不相等,useMemo会重新执行创建Fuse实例。如果Fuse实例的变化又触发了父组件的状态更新(比如子组件的筛选回调修改了父组件状态),就会形成「父组件渲染→传新keys→子组件useMemo重新计算→触发父组件状态更新→父组件再渲染」的无限循环。

解决办法

针对这种静态数组的场景,有三种直接有效的处理方式:

1. 父组件用useMemo缓存keys数组

在父组件里把静态数组用useMemo包裹,保证每次渲染时引用稳定:

const Parent = () => {
  const keys = React.useMemo(() => ['title', 'description'], []);
  return <FilterInput data={data} keys={keys} />;
};

2. 把keys定义为组件外部的常量

如果keys是固定不变的静态值,直接放到组件外部,彻底避免每次渲染重新创建数组:

// 组件外部定义,全局唯一引用
const SEARCH_KEYS = ['title', 'description'];

const Parent = () => {
  return <FilterInput data={data} keys={SEARCH_KEYS} />;
};

3. 子组件内部做浅比较优化(备选方案)

如果无法修改父组件的传参逻辑,可以在子组件里手动对keys做浅比较,结合useMemo和useRef判断是否需要更新Fuse实例:

const FilterInput = ({ data, keys }) => {
  const prevKeysRef = React.useRef();
  const stableKeys = React.useMemo(() => {
    // 浅比较数组内容是否一致
    if (prevKeysRef.current?.length !== keys.length) {
      prevKeysRef.current = keys;
      return keys;
    }
    for (let i = 0; i < keys.length; i++) {
      if (prevKeysRef.current[i] !== keys[i]) {
        prevKeysRef.current = keys;
        return keys;
      }
    }
    return prevKeysRef.current;
  }, [keys]);

  const fuse = React.useMemo(() => {
    return new Fuse(data, { keys: stableKeys });
  }, [data, stableKeys]);

  // 其他组件逻辑...
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:57:39