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

React组件中useMemo回调多次触发问题及单次调用方案问询

问题解析与解决方案

为什么updateLogAndGetId被调用4次?

这是因为**React开发环境的严格模式(Strict Mode)**会刻意重复调用useMemo这类钩子的回调函数,目的是检测代码中潜在的非纯函数副作用。

你的代码里渲染了两个MyComponent实例,在严格模式下,每个实例的useMemo回调会被执行两次:第一次是正常渲染,第二次是React用来验证重复执行是否会引发问题的校验逻辑。两个实例各执行两次,最终就出现了4次调用。

至于HTML显示1和3,是因为useMemo会复用第一次执行的缓存结果,第二次执行的返回值会被忽略。但你的全局id变量每次调用都会自增,所以第一个组件第一次调用返回0、第二次返回1,最终组件使用的是缓存的1;第二个组件第一次返回2、第二次返回3,最终使用的是缓存的3,因此DOM呈现这两个值。

如何确保每个组件仅调用一次updateLogAndGetId?

方案1:利用useRef存储唯一ID

useRef的.current属性不会随组件重渲染重置,初始化逻辑只会执行一次,不受严格模式重复渲染的影响:

import { useRef } from "react";

let id = 0;

export const MyComponent = () => {
  const componentIdRef = useRef(null);
  if (!componentIdRef.current) {
    componentIdRef.current = ++id;
    console.log(componentIdRef.current);
  }
  const componentId = componentIdRef.current;
  console.log("outside", componentId);
  return <li>{componentId}</li>;
};

方案2:生产环境自动消除重复调用

严格模式的重复调用逻辑仅存在于开发环境,生产环境打包后,React会自动关闭该校验,每个组件的useMemo回调只会执行一次。

方案3:改用纯函数式ID生成(可选)

如果场景允许,可使用纯函数生成唯一ID(比如结合组件的props或上下文),避免依赖全局变量。但如果必须生成实例唯一ID,useRef的方案更直接可靠。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 11:27:06