一、解决什么问题?

useReducer 是 useState 的降级版本,对 setState 这个操作进行了拆分,能够依据不同类型,进行不同的逻辑计算,最初去扭转 state 对象。

1、实例:useReducer 实现计数器组件
const initialState = { count: 0 };function reducer(state, action) {    switch (action.type) {        case 'increment':            return { count: state.count + 1 };        case 'decrement':            return { count: state.count - 1 };        default:            throw new Error();    }}function Counter() {    const [state, dispatch] = React.useReducer(reducer, initialState);    return (        <>            Count: {state.count}            <button onClick={() => dispatch({ type: 'decrement' })}>-</button>            <button onClick={() => dispatch({ type: 'increment' })}>+</button>        </>    );}

二、useReducer 初始化办法
1、法一:应用第二个参数初始化
const [state, dispatch] = useReducer(    reducer,    { count: initialCount });
2、法二:惰性初始化

useReducer 须要一个初始值和初始函数,通过计算失去的值作为 useReduccer 的初始化数据。这样就把计算逻辑独立在 useReducer 内部,为未来对重置 state 的 action 做解决提供了便当。

function init(initialCount) {    return { count: initialCount };}function reducer(state, action) {    switch (action.type) {        case 'increment':            return { count: state.count + 1 };        case 'decrement':            return { count: state.count - 1 };        case 'reset':            return init(action.payload);        default:            throw new Error();    }}function Counter({ initialCount }) {    const [state, dispatch] = useReducer(reducer, initialCount, init);    return (        <>            Count: {state.count}            <button                onClick={() => dispatch({ type: 'reset', payload: initialCount })}>                Reset            </button>            <button onClick={() => dispatch({ type: 'decrement' })}>-</button>            <button onClick={() => dispatch({ type: 'increment' })}>+</button>        </>    );}

三、晋升性能的阐明

如果 useReducer 返回的 state 相比于之前没有变动,React会主动跳过对组件的渲染操作。这里的比拟操作是调用了js的 Object.is() 办法。


四、解决层层回调的懊恼
1、useContext + useReducer

顶层组件有个回调函数要传递上来,须要每一层都应用 props 进行设置,很繁琐,这里能够用 useContext + useReducer 来解决。

useContext 负责传递执行函数,useReducer 负责对执行函数划分出不同状态,可供选择执行。

const TodosDispatch = React.createContext(null);function TodosApp() {    // 提醒:`dispatch` 不会在从新渲染之间变动    const [todos, dispatch] = useReducer(todosReducer);    return (        <TodosDispatch.Provider value={dispatch}>            <DeepTree todos={todos} />        </TodosDispatch.Provider>    );}
function DeepChild(props) {    // 如果咱们想要执行一个 action,咱们能够从 context 中获取 dispatch。    const dispatch = useContext(TodosDispatch);    function handleClick() {        dispatch({ type: 'add', text: 'hello' });    }    return (        <button onClick={handleClick}>Add todo</button>    );}

五、参考链接:
  • React的Reducer Hook让state有了状态!