美文网首页
useReducer—— React Hook

useReducer—— React Hook

作者: Lia代码猪崽 | 来源:发表于2020-12-29 11:12 被阅读0次

参考

https://zh-hans.reactjs.org/docs/hooks-reference.html#usereducer

一、useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init);
// reducer 函数
// initialArg state的初始值
// init 惰性地创建初始 state ,特别适合用于有重置需求的场景

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

二、使用 useReducer 的场景

在某些场景下,useReducer 会比 useState 更适用,例如:

  • state 逻辑较复杂且包含多个子值
  • 或者下一个 state 依赖于之前的 state 等。

并且,使用 useReducer 还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递 dispatch 而不是回调函数

三、示例:以下是用 reducer 重写 useState 一节的计数器示例:

const initialState = {count: 0};

// reducer 函数接受两个参数,一个是当前的 state ,另一个是 action: { type, payload }
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] = useReducer(reducer, initialState);
  return (
    <>
      Count: { state.count }
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  )
}

注意
React 会确保 dispatch 函数的标识是稳定的,并且不会在组件重新渲染时改变。这就是为什么可以安全地从 useEffect 或 useCallback 的依赖列表中省略 dispatch。

四、示例2:使用第三个参数,惰性初始化

// const initialState = {count: 0};

function init(initialState) {
  return { count: initialState }
}

// reducer 函数接受两个参数,一个是当前的 state ,另一个是 action: { type, payload }
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    // 当操作是 reset 时,根据传入的参数来设定重置的值
    case 'reset':
      return init(action.payload);
    default:
      throw new Error();
  }
}

// 作为 props 传入
function Counter({ initialState }) {
  const [state, dispatch] = useReducer(reducer, initialState, init);
  return (
    <>
      Count: { state.count }
      // 所以这里也要传入 payload 
      <button
        onClick={() => dispatch({type: 'reset', payload: initialCount})}>
        Reset
      </button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  )
}

相关文章

网友评论

      本文标题:useReducer—— React Hook

      本文链接:https://www.haomeiwen.com/subject/hdrfoktx.html