setState 到 useState/useReducer
约 466 字大约 2 分钟
布欧-Lewyon
2026-05-15
this.setState → useState
// 类组件
class Counter extends React.Component {
state = { count: 0, step: 1 }
increment = () => {
this.setState(prev => ({ count: prev.count + prev.step }))
}
}// Hooks 版本 —— 拆分多个 useState
function Counter() {
const [count, setCount] = useState(0)
const [step, setStep] = useState(1)
const increment = () => setCount(c => c + step)
// 批量更新
const reset = () => {
setCount(0)
setStep(1)
// React 18 自动批处理,只渲染一次
}
}对象 state → 拆分 vs useReducer
// 类组件:一个大的 state 对象
class Form extends React.Component {
state = {
name: '',
email: '',
age: 0,
errors: {},
isSubmitting: false,
}
}// 选项 A:拆分多个 useState(推荐)
function Form() {
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [age, setAge] = useState(0)
const [errors, setErrors] = useState<Record<string, string>>({})
const [isSubmitting, setSubmitting] = useState(false)
}
// 选项 B:useReducer(多个字段强关联时)
type FormAction =
| { type: 'SET_FIELD'; field: string; value: string }
| { type: 'SET_ERRORS'; errors: Record<string, string> }
| { type: 'SUBMIT_START' }
| { type: 'SUBMIT_END' }
function formReducer(state: FormState, action: FormAction): FormState {
switch (action.type) {
case 'SET_FIELD':
return { ...state, [action.field]: action.value }
case 'SET_ERRORS':
return { ...state, errors: action.errors }
case 'SUBMIT_START':
return { ...state, isSubmitting: true }
case 'SUBMIT_END':
return { ...state, isSubmitting: false }
default:
return state
}
}this.forceUpdate → useReducer hack 或 useState 自增
// 类组件
this.forceUpdate()
// Hooks 版本
function useForceUpdate() {
const [, setCount] = useState(0)
return () => setCount(c => c + 1)
}
// 使用
const forceUpdate = useForceUpdate()setState callback → useEffect
// 类组件
this.setState({ count: 1 }, () => {
console.log('state 已更新', this.state.count)
})
// Hooks 版本 —— useEffect 监听
const [count, setCount] = useState(0)
useEffect(() => {
console.log('count 已更新', count)
}, [count])
setCount(1)迁移模式对照
| 类组件写法 | Hooks 写法 |
|---|---|
this.state.count | count(解构) |
this.setState({ count: 1 }) | setCount(1) |
this.setState(prev => ({ count: prev + 1 })) | setCount(c => c + 1) |
this.setState({a, b}, callback) | useEffect 监听 |
this.state = { x: 1 }(构造函数) | useState(1) |
| 单个大对象 state | 多个 useState 或 useReducer |
小结
- 一个类组件的
this.state对象拆成多个useState,更清晰。 - 多字段强关联时用
useReducer(类似 setState 但更可控)。 - 函数式更新
setCount(c => c + 1)对应setState(prev => ...)。 - setState 回调在 Hooks 中用
useEffect替代。 forceUpdate用useState自增 hack 模拟。
上一节:生命周期到 useEffect 映射 下一节:this 绑定与闭包
