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'))
  • 相关阅读:
    <JavaScript> 组合继承
    <JavaScript> 稳妥构造函数模式与工厂模式的区别
    <JavaScript> call()、apply()、bind() 的用法
    <JavaScript>可枚举属性与不可枚举属性
    <JavaScript>闭包(closure)
    在MongoDB中实现聚合函数
    (转)如何入门 Python 爬虫
    Python爬虫实战四之抓取淘宝MM照片
    转载:十年驾车经验总结:活着,才是硬道理
    设计模式之单例模式的七种写法
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12464013.html
Copyright © 2011-2022 走看看