主题
useState
基本使用
介绍
useState 是一个 hooks 函数,它允许我们向组件添加一个状态变量,从而控制影响组件的渲染结果。
提示
可以类比于 vue2 中的 data,或者 vue3 中的 ref、reactive。
示例
tsx
import { useState } from 'react'
function State() {
const [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1)
}
const [obj, setObj] = useState({
name: '张三',
age: 18,
})
const handleClick2 = () => {
setObj({
...obj,
name: '李四',
})
}
const [arr, setArr] = useState([1, 2, 3])
const handleClick3 = () => {
setArr([4, 5, 6])
}
return (
<>
{/* 基本状态 */}
<h2>{count}</h2>
<button type="button" onClick={handleClick}>
count++
</button>
<hr />
{/* 对象状态 */}
<h2>{JSON.stringify(obj)}</h2>
<button type="button" onClick={handleClick2}>
更改 obj
</button>
<hr />
{/* 数组状态 */}
<h2>{JSON.stringify(arr)}</h2>
<button type="button" onClick={handleClick3}>
添加 arr
</button>
</>
)
}
export default State计算属性
jsx
import { useState } from 'react'
function App() {
const [count] = useState(10)
const doubleCount = count * 2
return <div>{doubleCount}</div>
}
export default AppsetState 的更新是异步的吗?
是“延迟处理”,所以看起像“异步”处理的错觉。
- 同步提交,延迟执行:
setState函数本身是同步的,但它触发的状态更新和组件重新渲染,会被 React 延迟处理 并进行 批量合并。 - 性能优化:通过将多次状态更新合并成单次渲染,避免不必要的计算和 DOM 操作,最大化应用性能。
- 状态一致性:保证在一次事件处理流程中,所有状态变更能够同时生效,防止用户看见不完整的中间 UI 状态,提升应用健壮性。
useState 的两种更新方式
js
const [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1)
}js
const [count, setCount] = useState(0)
const handleClick = () => {
setCount((prevCount) => prevCount + 1)
}示例:State 更新不符合预期
在一次点击中,连续调用了三次 setCount,期望 count 增加 3:
jsx
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1)
setCount(count + 1)
setCount(count + 1)
}
return (
<div>
<p>{count}</p>
<button onClick={handleClick}>Increment by 3</button>
</div>
)
}
export default Counter结果是:count 只增加了 1。
提示
- 闭包陷阱:
handleClick函数作用域内的count值,永远是当前渲染时的“快照”(0)。 - 异步与批处理:React 会将短时间的多次
setCount调用合并处理,以此来优化性能。
解决方案就是,使用“函数式更新”,通过函数获取最新的 state:
jsx
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
const handleClick = () => {
setCount((prevCount) => prevCount + 1)
setCount((prevCount) => prevCount + 1)
setCount((prevCount) => prevCount + 1)
}
return (
<div>
<p>{count}</p>
<button onClick={handleClick}>Increment by 3</button>
</div>
)
}
export default Counter结果是:count 增加了 3。
如果新状态依赖于旧状态,直接使用函数是更新!
