State Hooks useReducer
在上一节的最后,简单说明了一下有多个 state 时,我们如何定义。
根据描述,如果 state 非常多时,就需要定义很多的 useState , 所以我们引入 useReducer 。
定义
const [state, dispatch] = useReducer(reducer, initialArg, init);
实例
import React, { useReducer } from 'react';
const initialState = {
count: 0,
value: null
}
export default () => {
const [state, dispatch] = useReducer(reducer, initialState)
return (
<div className="example-rooter">
<p>当前记数为:{state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
<input value={state.value} onChange={(e) => dispatch({ type: 'value_Changed', value: e.target.value })} />
<button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
</div>
);
}
const reducer = (state, action) => {
const _state = { ...state };
switch (action.type) {
case 'increment':
_state.count = state.count + 1;
break;
case 'decrement':
_state.count = state.count - 1;
break;
case 'value_Changed':
_state.value = action.value;
break;
case 'reset':
_state.count = state.value;
break;
default:
throw new TypeError();
}
return _state;
}
和 useState 一样,我们通过 react 引入 useReducer, 需要单独定义一个 reducer 函数,我们惊奇的发现,这个 reducer 函数与我们之前熟悉的 Redux 中的 reducer 长的几乎一模一样,所以不再详解示例。
下面解释一下这个 useReducer:
state: 从useReducer中解构出这个参数,这个参数就是useReducer第一个参数reducer函数返回的值。dispatch: 和state一样,由useReducer解构出。其作用和Redux中的dispatch相似。通过action来设置一个state的值。reducer:useReducer的第一个参数,是对state操作的函数,该函数有两个参数构成 ——state和action, 与Redux中的reducer一致。函数返回一个immutable state, 而且只返回每一个return的当前数据,不会将所有的state assign后都返回。 所以如果直接修改state参数,然后返回当前state是不生效的。initialArg: 顾名思义,初始化的state值。我们建议,每一个 state 都应该初始化。init:lazy initial state, 是一个函数,通过函数的方式初始化一个state值。再次强调,如果
dispatch中return一个相同的state(reducer参数中的state),React不再渲然children或者触发effects事件。因为 React 使用的是Object.is算法来比较dispatch返回的state的。