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'))
  • 相关阅读:
    NYOJ 32(组合数)
    NYOJ 289(01背包)
    批量修改文件(图片)名称
    解决IIS7虚拟目录出现HTTP 错误 500.19(由于权限不足而无法读取配置文件)的问题
    MPP(最下正周期)
    wcf学习网站
    winform中用户输入查询与拼音首字母的结合,提高用户的操作体验 (转)
    通过SvcUtil.exe生成客户端代码和配置(转)
    WinMail 搭建邮件服务器。
    quick easy ftp server软件在机子上架设了个服务器
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12464013.html
Copyright © 2011-2022 走看看