useReducer进阶
第一句话很重要。
An alternative to useState.
表明底层还是useState实现,且作为additional的hook我们其实不用他也可以实现,那什么场景会需要useReducer呢?
如果你熟悉redux的话你会发现useReducer跟redux很像,上手很容易。
const [state, dispatch] = useReducer(reducer, initialArg, init);</pre>
三个参数
-
reducer function reducer是一个利用action提供的信息,将state从A转换到B的一个纯函数
-
initialArg 初始化的state。返回值为最新的state和dispatch函数(用来触发reducer函数,计算对应的state)
-
init function 非必须 我们在Lazy initialization的时候需要用到。至于什么场景什么情况会用到我们先看官方demo, 我们将官网demo放进codesandbox我们可以直接看出来
It lets you extract the logic for calculating the initial state outside the reducer. This is also handy for resetting the state later in response to an action
当我们需要在reducer外部计算init state的时候我们可以把这部分逻辑提取出来,这也非常方便当你需要在action中重置state
useReducer Concept
可以把UseReducer想象成一个后端,后端通常需要一个数据库和一些APl来修改你数据库的数据。
-
state 就是数据库存储你的数据
-
dispatch相当于调用 API 端点来修改数据库。
-
你可以指定type表明哪一个API被调用.
-
你可以提供额外的数据在payload的属性里, 这就像POST请求的body.
-
type 和 payload 都是提供给reducer的对象的属性. 该对象被称作action.
-
reducer 是 API 的逻辑。 它在后端收到 API 调用(dispatch)时调用,并根据端点和请求内容(action)处理如何更新数据库.
Why useReducer
先上图
image再看看官网解释
useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. useReducer also lets you optimize performance for components that trigger deep updates because you can passdispatchdown instead of callbacks.
-
复杂的state逻辑
-
下个一个state依赖上一个state
-
需要提升performance
-
多个state相互依赖 (form表单)
userReducer VS useState
- init
const [state, setState] = useState(initialValue); // setState for useState
const [state, dispatch] = useReducer(reducer, initialValue); // dispatch for useReducer</pre>
- change state
// with `useState`
<button onClick={() => setCount(prevCount => prevCount + 1)}>
+
</button>
// with `useReducer`
<button onClick={() => dispatch({type: 'increment', payload: 1})}>
+
</button></pre>
Full Demo
我们创建了一个在表单情况下使用useReducer的情况
详情参照代码里的注释
- JS
- TS
https://codesandbox.io/s/react-userreducer-form-ts-4ko55u
Preference
https://devtrium.com/posts/how-to-use-react-usereducer-hook#usereducer-a-backend-mental-model