在写React的时候,useState
和useRef
是两个常见的hook。它们都能让函数组件"记住"一些数据,但作用场景和机制完全不同。这篇文章我们就来详细讲解什么时候用 useState
,什么时候用 useRef
。
useState是什么
useState
是 React 提供的一个 状态 Hook ,允许你在函数组件中定义响应式的状态。
当 state
发生变化时,React 会重新渲染组件 ,以保证UI 和状态保持一致。
用法示例
jsx
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>点击次数:{count}</p>
<button onClick={() => setCount(count + 1)}>点我+1</button>
</div>
);
}
每次点击按钮,count
更新,React 会触发组件重新渲染,页面上的数字随之变化。
使用场景
-
管理 UI 相关的状态:例如计数器、弹窗开关、表单输入值等。
-
需要驱动渲染的变量:只要这个值变了,UI 就必须更新。
useRef是什么
如果我们希望组件记住一些信息,但 不希望触发重新渲染 ,可以使用 useRef
。
useRef
返回一个对象,只有一个属性:current
。
你可以把任何值存在 current
里,并在渲染之间保留它。
和 useState
不同的是:修改 ref.current
并不会引起组件重新渲染。
用法
jsx
import { useRef } from 'react';
export default function Form() {
const inputRef = useRef(null);
function handleClick() {
inputRef.current.focus();
}
return (
<>
<input ref={inputRef} />
<button onClick={handleClick}>聚焦输入框</button>
</>
);
}
👉 ref={inputRef}
让 React 把这个 <input>
的 DOM 节点放进了 inputRef.current
,所以我们就能调用它的原生方法 .focus()
。
使用场景
- 操作 DOM 元素
- 聚焦输入框
- 滚动到某个区域
- 手动触发播放/暂停等
- 存储副作用中的变量
-
保存
setInterval
的定时器 ID,避免放到state
里导致无意义的渲染。iniconst timerRef = useRef(null); timerRef.current = setInterval(...); clearInterval(timerRef.current);
- 保存上一次的值
- 例如对比本次和上次的股票价格,判断涨跌。
- 这样不会影响渲染,但可以在逻辑里取到历史数据。
useState 和 useRef的区别
特性 | useState | useRef |
---|---|---|
是否触发重新渲染 | ✅ 会 | ❌ 不会 |
返回值 | [state, setState] | { current: value } |
使用场景 | 用于 UI 状态 | 保存 DOM、存储副作用变量 |
修改方式 | 必须通过 setState | 直接改 current |
生命周期 | 组件每次渲染都会更新 | 渲染间隔中值保持不变 |