首页 > 其他 > 详细

[React] When to useReducer instead of useState

时间:2020-03-11 19:09:05      阅读:63      评论:0      收藏:0      [点我收藏+]

useState is typically simpler at first than useReducer (you can even implement useState using useReducer), but there‘s one scenario where useReducer is almost certainly better than useState:

When one element of your state relies on the value of another element of your state in order to update: useReducer

More information: KcD‘s blog

 

import React from ‘react‘
import ReactDOM from ‘react-dom‘

function undoReducer(state, action) {
  const {past, present, future} = state
  const {type, newPresent} = action

  switch (type) {
    case ‘UNDO‘: {
      if (past.length === 0) return state

      const previous = past[past.length - 1]
      const newPast = past.slice(0, past.length - 1)
      return {
        past: newPast,
        present: previous,
        future: [present, ...future],
      }
    }
    case ‘REDO‘: {
      if (future.length === 0) return state
      const next = future[0]
      const newFuture = future.slice(1)
      return {
        past: [...past, present],
        present: next,
        future: newFuture,
      }
    }
    case ‘SET‘: {
      if (newPresent === present) {
        return state
      }
      return {
        past: [...past, present],
        present: newPresent,
        future: [],
      }
    }
    case ‘RESET‘: {
      return {
        past: [],
        present: newPresent,
        future: [],
      }
    }
    default: {
      throw new Error(`Unhandled action type: ${type}`)
    }
  }
}

function useUndo(initialPresent) {
  const [state, dispatch] = React.useReducer(undoReducer, {
    past: [],
    present: initialPresent,
    future: [],
  })

  const canUndo = state.past.length !== 0
  const canRedo = state.future.length !== 0

  const undo = React.useCallback(() => {
    dispatch({type: ‘UNDO‘})
  }, [])

  const redo = React.useCallback(() => {
    dispatch({type: ‘REDO‘})
  }, [])

  const set = React.useCallback(newPresent => {
    dispatch({type: ‘SET‘, newPresent})
  }, [])

  const reset = React.useCallback(newPresent => {
    dispatch({type: ‘RESET‘, newPresent})
  }, [])

  return [state, {set, reset, undo, redo, canUndo, canRedo}]
}

function App() {
  const [state, {set}] = useUndo(‘first‘)

  React.useEffect(() => {
    set(‘second‘)
  }, [set])

  React.useEffect(() => {
    set(‘third‘)
  }, [set])

  return <pre>{JSON.stringify(state, null, 2)}</pre>
}

ReactDOM.render(<App />, document.getElementById(‘root‘))

 

[React] When to useReducer instead of useState

原文:https://www.cnblogs.com/Answer1215/p/12464013.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!