软件开发定制useReducer 介绍和基本使用

一、前言

useReduceruseState 软件开发定制的替代方案。软件开发定制它接收一个形如 (state, action) => newState 的 reducer,软件开发定制并返回当前的 state 软件开发定制以及与其配套的 dispatch 方法。(软件开发定制如果你熟悉 的话,软件开发定制就已经知道它如何工作了。)

const [state, dispatch] = useReducer(reducer, initialArg, init);
  • 1

useReducer接收两个参数:

  • 第一个参数:reducer函数。
  • 第二个参数:初始化的state。返回值为最新的state和dispatch函数(用来触发reducer函数,计算对应的state)。

在某些场景下,useReducer 会比 useState 更适用,例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。并且,使用 useReducer 还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递 dispatch 而不是回调函数 。

二、 reducer 重写

用 reducer 重写 useState 计数器示例

//	useState 计数器function Counter({initialCount}) {  const [count, setCount] = useState(initialCount);  return (    <>      Count: {count}      <button onClick={() => setCount(initialCount)}>Reset</button>      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>    </>  );}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
//	reducer 计数器const initialState = {count: 0};const 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] = useReducer(reducer, initialState);  return (    <>      Count: {state.count}      <button onClick={() => dispatch({type: 'decrement'})}>-</button>      <button onClick={() => dispatch({type: 'increment'})}>+</button>    </>  );}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

三、reducer

reducer 本质是一个纯函数,没有任何UI和副作用。这意味着相同的输入(state、action),reducer函数无论执行多少遍始终会返回相同的输出(newState)。因此通过reducer函数很容易推测state的变化,并且也更加容易单元测试。

如上例中count有可能只是 state中的一个属性。针对这种场景我们可以使用ES6的结构赋值:

// 返回一个 newState (newObject)    function countReducer(state, action) {        switch(action.type) {            case 'add':                return { ...state, count: state.count + 1; }            case 'sub':                return { ...state, count: state.count - 1; }            default:                 return count;        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

简单来说 reducer是一个函数(state, action) => newState:接收当前应用的state和触发的动作action,计算并返回最新的state。

React中的state比较方案
React在比较oldState和newState的时候是使用Object.is函数,如果是同一个对象则不会出发组件的rerender。 可以参考官方文档bailing-out-of-a-dispatch。

关于上面这段代码有两个重要的点需要我们记住:

  • reducer处理的state对象必须是 immutable,这意味着永远不要直接修改参数中的state对象,reducer函数应该每次都返回一个新的state object
  • 既然reducer要求每次都返回一个新的对象,我们可以使用ES6中的解构赋值方式去创建一个新对象,并复写我们需要改变的state属性,如上例。

state 为什么需要 immutable?
**reducer的幂等性:**我们上文提到过reducer需要保持幂等性,更加可预测、可测试。如果每次返回同一个state,就无法保证无论执行多少次都是相同的结果。

四、useState + useContext 结合实现 redux 数据管理效果

在某些场景下, 会比 useState 更适用,例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。并且,使用 useReducer 还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递 dispatch 而不是回调函数 。

useReducer 替代 useState + useContext可以实现类似 redux 的数据管理效果。
可参考:

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发