码迷,mamicode.com
首页 > 其他好文 > 详细

[React] When to useReducer instead of useState

时间:2020-03-11 18:14:07      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:tps   targe   next   import   user   reac   col   def   cert   

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

标签:tps   targe   next   import   user   reac   col   def   cert   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!