
本文讲解如何利用 React 的 useRef 在非受控输入(uncontrolled input)中实现实时值同步显示,避免状态管理,同时说明其原理、适用场景及关键限制。
本文讲解如何利用 react 的 `useref` 在非受控输入(uncontrolled input)中实现实时值同步显示,避免状态管理,同时说明其原理、适用场景及关键限制。
在 React 中,非受控组件(uncontrolled component) 是指其值由 DOM 自身管理(如原生 ),而非通过 value prop 和 onChange 驱动的受控组件。通常,非受控输入仅在表单提交(如 onSubmit)时读取值(例如通过 ref.current.value),默认不会触发重渲染,也无法直接响应实时输入变化。
但若希望在不引入 useState 的前提下,实现实时显示输入内容(如同步到 标签)
以下是一个典型实现:
import { useRef, ChangeEvent } from 'react';
function UncontrolledInputWithRef() {
const inputRef = useRef<HTMLInputElement>(null);
const paragraphRef = useRef<HTMLParagraphElement>(null);
const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
// 直接更新 p 标签文本,不触发重渲染
if (paragraphRef.current) {
paragraphRef.current.textContent = e.target.value;
}
};
return (
<div>
{/* 非受控输入:无 value prop,依赖 DOM 自持值 */}
<input
type="text"
ref={inputRef}
onChange={handleInputChange}
placeholder="请输入内容(非受控)"
/>
<p ref={paragraphRef}>—</p>
</div>
);
}
export default UncontrolledInputWithRef;✅ 核心要点解析:
- 输入元素未设置 value 属性,因此属于真正意义上的非受控组件;
- onChange 事件仍被监听,但不用于更新 state,而是直接操作 paragraphRef.current.textContent;
- useRef 提供对 DOM 节点的稳定引用,确保每次都能安全访问并修改其内容;
- 整个过程不触发组件重渲染,性能轻量,适用于只读同步、日志展示、调试辅助等场景。
⚠️ 重要注意事项:
- 此方式违背 React “声明式 UI” 原则,属于命令式 DOM 操作,在多数业务逻辑中不推荐替代受控组件;
- 若需结合校验、条件禁用、动态默认值或与其他状态联动,应优先选择受控模式(useState + value + onChange);
- ref.current 在首次渲染时为 null,务必在使用前做存在性检查(如 if (paragraphRef.current));
- SSR(服务端渲染)环境下,ref 在服务端不可用,需确保相关逻辑在客户端执行(如 useEffect 内初始化或事件回调中安全调用)。
? 总结:
虽然非受控输入本身不驱动视图更新,但借助 useRef 和事件回调,我们完全可以在不引入状态的前提下,实现 DOM 层面的实时值同步。它是一种“务实的例外”,适合轻量级、副作用明确的展示需求,但不应成为表单交互的默认方案。理解其边界,才能在受控与非受控之间做出更精准的技术选型。

















