首先,useReducer 是 react 内置 hooks,是 redux 的简易版,可以实现外部状态管理,但是只能在函数组件内部实现,不能脱离函数组件存在,且不可以处理异步。
语法
// 外部
const initState = xxx // 初始状态
// reducer 处理函数
const reducer = (prevState, action) => {
// prevState 默认状态
// action 动作
let newState = { ...prevState };
switch (action.type) {
case "xxx":
// 处理新的状态
return newState;
// ...
default:
return prevState;
}
}
// 父组件或者根组件
const [state, dispatch] = useReducer(reducer, initState); // 传入外部的 reducer 和 initState
// 要更改状态的组件
dispatch({ type: "xxx", ... });
完整案例-可以结合 useContext 来共同实现 点击 Child1 中的两个按钮,分别实现 Child2 和 Child3 组件中的 state 改变
import React, { useContext, useReducer } from "react";
const initState = {
count1: 0,
count2: 0,
};
const reducer = (prevState, action) => {
let newState = { ...prevState };
switch (action.type) {
case "add-child1":
newState.count1 = action.value;
return newState;
case "add-child2":
newState.count2 = action.value;
return newState;
default:
return prevState;
}
};
const myContext = React.createContext("");
const ComUseReducer = () => {
const [state, dispatch] = useReducer(reducer, initState);
const { Provider } = myContext;
return (
<>
<Provider value={{ state, dispatch }}>
<Child1 />
<Child2 />
<Child3 />
</Provider>
</>
);
};
const Child1 = () => {
const { dispatch } = useContext(myContext);
return (
<>
<button
onClick={() => {
dispatch({ type: "add-child1", value: 100 });
}}
>
child1
</button>
<button
onClick={() => {
dispatch({ type: "add-child2", value: 200 });
}}
>
child2
</button>
</>
);
};
const Child2 = () => {
const { state } = useContext(myContext);
return <div>child2 - {state.count1}</div>;
};
const Child3 = () => {
const { state } = useContext(myContext);
return <div>child3 - {state.count2}</div>;
};
export default ComUseReducer;
执行 reducer 会导致整个组件渲染,使 state 拿到最新的值。