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

useRef()未触发re-render为何能引发视图更新?

问题描述

我编写了如下React基础代码示例:
代码运行时,用户点击按钮后,输入框会自动获取焦点并填入文本test。
整个过程中组件state从未修改,也没有触发组件re-render,为什么视图仍然会出现对应变化?

import { useRef } from "react";

const App = () => {
  const inputRef = useRef(null);
  const handleClick = () => {
    inputRef.current.focus();
    inputRef.current.value = "test";
  };

  return (
    <>
      <input ref={inputRef}></input>
      <button onClick={handleClick}>Click me!!</button>
    </>
  );
};
核心原因

这个现象的本质是混淆了React渲染流程和浏览器原生DOM更新的边界:

  • React的re-render只会在组件state、传入props、订阅的context发生变化时触发,整个流程是:重新执行组件函数生成新的虚拟DOM → 对比新旧虚拟DOM差异 → 把需要更新的差异同步到真实DOM上,这是React自己管控的UI更新路径。
  • useRef返回的ref对象上的current属性,存的就是真实DOM节点的直接引用,对这个属性做操作,本质是直接操作浏览器原生DOM,完全绕开了React的虚拟DOM和渲染调度逻辑。

点击事件里的两行代码,全是直接调用浏览器原生能力:

  1. inputRef.current.focus()是直接调用原生input元素的内置focus方法,输入框聚焦、出现光标、高亮边框这些效果,本来就是浏览器原生提供的UI反馈,和React的渲染没有任何关系。
  2. inputRef.current.value = "test"是直接修改原生input元素的value属性,浏览器监听到原生DOM属性变更后,会直接更新输入框的显示内容,整个过程根本不需要React参与,自然不需要触发组件re-render就能看到视图变化。

注意:这种直接操作ref修改DOM的方式是React提供的"逃逸舱"能力,只适合处理和React状态无关的DOM操作。如果输入框是受控组件(值和React state绑定),不要用这种方式直接修改DOM值,否则会出现DOM显示内容和React中存储的状态不一致的问题,常规场景还是推荐通过state更新来驱动UI变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:57:31