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

React中组件被父组件调用两次时useRef的工作机制疑问

问题原因分析

你遇到的现象核心原因是**useRef的声明位置错误**,导致多个MyInput组件实例共享了同一个ref对象,而非各自持有独立的ref。

错误写法的问题所在

如果你的代码是类似这样的:

// 错误:ref声明在组件外部,全局共享
const inputRef = useRef(null);

function MyInput() {
  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return <input ref={inputRef} />;
}
  • 这里的inputRef是定义在MyInput组件函数之外的,属于全局作用域变量。
  • 第一个MyInput渲染时,inputRef.current会被赋值为第一个输入框的DOM元素;第二个MyInput渲染时,inputRef.current会被覆盖为第二个输入框的DOM元素。
  • 最终所有effect执行时,只会对最后一次赋值的DOM元素(第二个输入框)调用focus(),所以只有它获得焦点。

正确的实现方式

要让每个组件实例拥有独立的ref,必须把useRef的声明放在组件函数内部:

// 正确:ref声明在组件内部,每个实例独立持有
function MyInput() {
  const inputRef = useRef(null); // 每个MyInput实例都会创建自己的inputRef

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return <input ref={inputRef} />;
}
  • 此时每个MyInput组件实例在渲染时,都会创建属于自己的inputRef对象,分别绑定各自的输入框DOM节点。
  • 每个实例的effect都会调用自己ref对应的focus()方法,因此两个输入框都会获得焦点。

补充说明

React的useRef是组件实例级别的钩子,只有当它在组件函数内部被调用时,React才会为每个组件实例分配独立的ref存储空间。如果放在组件外部,就失去了这种实例隔离的特性,变成了普通的共享变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 02:48:10