useRef 和 useState 有什么区别?
先理解原理和示例,再练习完整口述与追问。
回答要点
ref 在重渲染间保留可变容器,改 current 不触发渲染,适合 DOM、计时器或命令式对象;界面依赖的状态通常用 state。不要在渲染期间任意读写 ref 以规避状态机制。
原理拆解
useState 保存影响 UI 的状态并通过 setter 请求更新;useRef 保存跨渲染稳定的容器,修改 current 不会自动让组件重渲染。ref 适合 DOM、计时器 ID、请求序号和不需要直接显示的可变信息。稳定容器身份不等于其中数据有自动响应式能力,也不意味着可以在 render 中随意修改外部资源。
示例与推演
输入框的显示值用 state;用于取消请求的 controller 和 requestVersion 可放 ref;需要聚焦的 DOM 用模板 ref。把计数显示只写为 ref.current++,页面不会因此自动更新。如果一份数据同时要显示又要被回调读取,应先明确状态为主的来源,避免 state/ref 两份内容逐渐不同步。
易错点
不要把 ref 当成省略 Effect 依赖的默认手段。对 DOM ref 的可用性要等提交,条件节点移除后 ref 也可能变回 null。
参考回答可直接练习口述
useState 变化会请求渲染,用于界面依赖的数据;useRef 提供跨渲染稳定的容器,修改 current 不触发渲染,适合 DOM、定时器标识或外部实例。不能把应展示的值只存在 ref 中再期待 UI 自动更新。渲染期间也应避免任意读写 ref,以保持可重复计算。
面试官可能继续问追问与完整解答展开收起
追问
如何向父级暴露有限方法?React 19 的函数组件可接收 ref prop,与旧项目 forwardRef 写法如何区分?
追问回答
可以用 useImperativeHandle 向父级暴露 focus、validate 等有限命令式方法。React18 常通过 forwardRef 接收 ref;React19 函数组件可以把 ref 作为 prop 接收。应按项目版本实现,而不是直接删除旧项目所有 forwardRef。