共计 2056 个字符,预计需要花费 6 分钟才能阅读完成。
一、解决什么问题?
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 有了状态!
正文完