zoukankan      html  css  js  c++  java
  • [React] When to useReducer instead of useState

    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'))
  • 相关阅读:
    VS2013 调试窗口一闪而过的解决方法
    什么是文件?
    局部变量和全局变量的区别
    一个简单java程序的要素
    运行一个简单的Java程序
    Javascript 构造函数原型继承机制
    函数式编程之一等公民的函数
    弹性布局flex-兼容问题
    TypeScript中的枚举类型
    依赖注入
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12464013.html
Copyright © 2011-2022 走看看