useReducer
useReducer 是一个可以让你向组件中添加 reducer 的 Hook
const [state, dispatch] = useReducer(reducer, initialArg, init?)
基本用法
const reducer = (state, action) => {
...
}
const MyComponent = () => {
const [state, dispatch] = useReducer(reducer, {age: 42})
const handleClick = () => {
dispatch({type:'increase'})
}
...
}
比 useState 多了一个处理函数,该函数可以根据不同的分发状态来对应的改变状态
注意:state 不可修改 不能这样写, reducer 函数应当返回一个新对象
function reducer(state, action) {
switch (action.type) {
case 'incremented_age': {
// 🚩 Don't mutate an object in state like this:
state.age = state.age + 1;
return state;
}
function reducer(state, action) {
switch (action.type) {
case 'incremented_age': {
// ✅ Instead, return a new object
return {
...state,
age: state.age + 1
};
}
不要重新执行初始函数 第一种写法会导致每次渲染时候都调用 createInitialState 函数 造成性能浪费
function createInitialState(username) {
// ...
}
// ❌
function TodoList({ username }) {
const [state, dispatch] = useReducer(reducer, createInitialState(username));
// ✅
function TodoList({ username }) {
const [state, dispatch] = useReducer(reducer, username, createInitialState);
// ...
dispatch 后如何使用最新的状态值
调用 dispatch 函数不会更改运行代码中的状态 ,使用最新的状态值应该是这样写
function handleClick() {
console.log(state.age); // 42
dispatch({ type: 'incremented_age' }); // Request a re-render with 43
console.log(state.age); // Still 42!
setTimeout(() => {
console.log(state.age); // Also 42!
}, 5000);
}
const action = { type: 'incremented_age' };
dispatch(action);
const nextState = reducer(state, action);
console.log(state); // { age: 42 }
console.log(nextState); // { age: 43 }
参考
- https://react.dev/reference/react/useReducer