96SEO 2026-08-13 18:23 1
在日常开发中。你可能会遇到以下痛点:
useRef 与 useState 的区别时只会背公式,却没有实战案例可说服面试官。早期前端开发经常这样写:

document.getElementById.textContent = "Hello";按理说,document.querySelector.style.color = "red";其实,
这是典型的命令式 DOM 编程:我们直接找到节点。接下来修改它的内容或样式。
它并不是“不能用”,但当页面变复杂后问题会逐渐出现:
React 采用的是声明式思路:
// 命令式:自己找到节点并修改
input.value = "hello";样子
setValue,
更准确地说React 并没有“消灭 DOM”,而是接管了大多数由状态驱动的 DOM 更新。你负责描述 UI,React 负责把状态变化落实到 DOM。
现实中的前端总会遇到 React 不应该直接接管的对象:
这时就需要 useRef.
调用 useRef 会得到一个稳定的对象:
const ref = useRef;// ref 的形状可以理解为:{ current: initialValue }
两个关键特征:
对象本身仍然是同一个对象。 不会自动触发重新渲染。
Pain point: 很多人误以为只要把值放进 就能让 UI 自动更新,其实这正是 设计之初想要避免的副作用。
| # 对比项 | `useState` | `useRef` |
|---|---|---|
| `更新方式` | `调用 setter` | `直接修改 current` |
| `是否触发重新渲染` | `会` | `不会` |
| `读取方式` | `当前渲染中的 state 快照` | `ref.current 的当前值` |
"如果数据变化需要页面立刻反映,就用 state;怎么说呢,如果只是给副作用或外部对象使用,就可以考虑 ref。"
import { useEffect,useRef } from "react";export default function LoginForm {
const inputRef = useRef;useEffect => {
// 页面挂载完毕后聚焦
inputRef.current?.focus,},);return (
);话说回来,}
创建一个 容器;;.
组件卸载时React 会把 DOM ref 清回
.current 可以是数字、字符串、对象甚至函数,只要你想跨渲染保持即可。下面展示几个常见场景:
为什么不直接用 autoFocus?老实说,
// 仅 autoFocus 无法满足需求
// 如在弹窗打开后再聚焦、在某个动画结束后聚焦等
通过 Ref。你还能:
至于面孔二。可变值——保存不参与渲染的数据
.ref 用作计数器
import { useR ef,u seS tate } from 'react';export default function RefCounter{
const numR ef = us eRe f;// 初始 undefined
const = us eS t ate;// 强制刷新
function handleC lick{ numR ef .c u rrent +=1;// 改变值,不触发重绘 forceRender;// 手动刷新 UI,仅为演示 }
return (
注意如果计数本身就是 UI 必须展示的数据,请直接使用 useState<>;把它当成 “不会自动更新页面的 state” 往往会让代码难以阅读。
import { us eE ffect,us eR ef } from 'react';export default function Polling{
const timerR ef = us eR ef;
us eE ffect=>{ timerR ef .c u rrent = setInterval=> console .log,1000);return=>{ if{clearI nterval;} },},);return
轮询中
}Pain point忘记在 cleanup 中清理导致内存泄漏。使用 Ref 保存 ID 能确保即使组件多次重渲染,也能拿到同一个 ID 并正确清理。
import { us eE ffect,us eR ef} from 'react';function SearchResult{
const prevK eywordR ef = us eR ef;us eE ffect=>{
if{
console.log;}
prevK eywordR ef .c u rrent=keyword;},),return
再看当前关键词,{keyword}
}
Why not put it in state?话说回来, 因为我们只关心“变化是否发生”。 而不是把旧值展示来,State 会导致额外一次渲染,而 Ref 则保持轻量。
js const configRef = useRef;useEffect=>{ configRef.current = latestConfig;},),说起来,
// 在事件处理函数内部随时读取最新配置 function handleClick{ doSomething;}
提醒这种写法绕开了 React 响应式模型。只适合 “读取最新值” 的场景,不要把业务状态全部塞进 Ref。
. 主线程负责 UI 渲染与交互。如果在主线程执行大量同步计算,会导致页面卡顿甚至失去响应。说起来,Promise/async 并不能把同步任务搬到别的线程。它们仍然占用主线程时间片。Worker 提供独立线程,用于耗时计算,同时保持 UI 流畅。
主线程 Worker
──────postMessage───►
…耗时计算,◀──────onmessage─────
setResult
jsx
function App{
const workerR ef = us eR ef;// ❌ 每次组件函数执行都可能创建新 Worker → 重复线程 + 内存泄漏
workerR ef .c u rrent = new Worker);return
Pain pointStrictMode 会双倍执行函数。使得意外产生多个 Worker;副作用应放在 useEffect 中。
jsx import { useEffect。useRef,useState } from 'react';
export default function WorkerDemo { const workerR ef = us eR ef;const = us eS t ate;const = us eS t ate;
us eE ffect=>{ const w = new Worker,{type:'module'});workerR ef .c u rrent = w;
w.onmessage = ev=>{ setResult;setStatus,};w.onerror = =>{ setStatus;},
setStatus;w.postMessage;
return=>{ w.terminate;不过,workerR ef .c u rrent=null;},},);
return (
{status}
{result!==null &&结果这方面,{result}
}
对应 worker.js
js
self.onmessage = ev=>{
ifreturn;let sum=0,for{ sum+=i;}
self.postMessage;},
为什么不用 State 保存 Worker? 虽然 useState 一样可以保存引用,但它暗示该值是 UI 状态。Worker 本身不参与 UI 渲染。用 Ref 更能表达 “这是外部可变实例,不驱动界面”。只要初始化方式正确,State 一样不会每次渲染都重新创建,但语义上更易混淆。
| Name | Description | If changed → Re‑render? | |
|---|---|---|---|
`useState<>` | 保存会影响 UI 的状态,如表单值、请求结果等。 | 是 → 每次 setter 调用都会触发重新渲染。 | count。loading,error 等。 |
`useRef<>` | 跨渲染保存可变引用,如 DOM 节点、timer ID、Worker 实例、上一次的 props 等。 | 否 → 修改 `.current` 不触发重绘。 | inputRefs。timerId,workerInstance… |
`useEffect<>` | 安排副作用,本身不保存任何业务数据。 | 否,但内部可以更新 State 或 Ref。 | 创建订阅、启动计时器、发送网络请求等。 |
>setValue,而不是 valueRef.current=nextValue;不过,.
若仅用于内部逻辑。则保持使用 valueRef.current=nextValue;.
text
"useRef 返回一个跨渲染保持稳定的对象,通过 current 保存任意值。修改 current 不会触发组件重新渲染,所以适合:
• 持有真实 DOM 节点;• 保存 timerId / 上一次 props;• 持有 WebWorker / WebSocket 等外部实例。若数据变化需立即反映 UI,应使用 useState;若涉及创建/订阅/销毁资源,则配合 useEffect 完成生命周期管理。”
此答案覆盖四个关键点:
1️⃣ 稳定引用 ✅ 2️⃣ 可变 current 不触发渲染 ✅ 3️⃣ 常见用途✅ 4️⃣ 与 state/effect 协同使用 ✅
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback