zoukankan      html  css  js  c++  java
  • [React] useReducer with lazy initializtion

    const [state, dispatch] = useReducer(reducer, initialArg, init);

    The third arguement 'init' is a lazy initialization which is a function.

    It is useful when you want to reset the state or dynamiclly generate the state.

    function init(initialCount) {
      return {count: initialCount};
    }
    
    function reducer(state, action) {
      switch (action.type) {
        case 'increment':
          return {count: state.count + 1};
        case 'decrement':
          return {count: state.count - 1};
        case 'reset':
          return init(action.payload);
        default:
          throw new Error();
      }
    }
    
    function Counter({initialCount}) {
      const [state, dispatch] = useReducer(reducer, initialCount, init);
      return (
        <>
          Count: {state.count}
          <button
            onClick={() => dispatch({type: 'reset', payload: initialCount})}>
    
            Reset
          </button>
          <button onClick={() => dispatch({type: 'decrement'})}>-</button>
          <button onClick={() => dispatch({type: 'increment'})}>+</button>
        </>
      );
    }

    Or dyanmically generate the init val:

    const preferDarkQuery = '(prefers-color-scheme: dark)'
    function darkModeReducer(state, action) {
      switch (action.type) {
        case 'MEDIA_CHANGE': {
          return {...state, mode: action.mode}
        }
        case 'SET_MODE': {
          // make sure to spread that state just in case!
          return {...state, mode: action.mode}
        }
        default: {
          // helps us avoid typos!
          throw new Error(`Unhandled action type: ${action.type}`)
        }
      }
    }
    // use the init function to lazily initialize state so we don't read into
    // localstorage or call matchMedia every render
    function init() {
      return {
        mode:
          window.localStorage.getItem('colorMode') ||
          (window.matchMedia(preferDarkQuery).matches ? 'dark' : 'light'),
      }
    }
    function useDarkMode() {
      const [state, dispatch] = React.useReducer(
        darkModeReducer,
        {mode: 'light'},
        init,
      )
      const {mode} = state
      React.useEffect(() => {
        const mediaQuery = window.matchMedia(preferDarkQuery)
        const handleChange = () =>
          dispatch({
            type: 'MEDIA_CHANGE',
            mode: mediaQuery.matches ? 'dark' : 'light',
          })
        mediaQuery.addListener(handleChange)
        return () => mediaQuery.removeListener(handleChange)
      }, [])
      React.useEffect(() => {
        window.localStorage.setItem('colorMode', mode)
      }, [mode])
      // We like the API the way it is, so instead of returning the state object
      // and the dispatch function, we'll return the `mode` property and we'll
      // create a setMode helper (which we have to memoize in case someone wants
      // to use it in a dependency list):
      const setMode = React.useCallback(
        newMode => dispatch({type: 'SET_MODE', mode: newMode}),
        [],
      )
      return [mode, setMode]
    }

     'init' function will override the second arguement.

    More

  • 相关阅读:
    Java Socket通信实现私聊、群聊
    一套简单的web即时通讯——第二版
    一套简单的web即时通讯——第一版
    前后端API交互数据加密——AES与RSA混合加密完整实例
    跨境电商ERP中的自动化 3.平台订单自动发货
    跨境电商ERP中的自动化 2.平台商品和本地单品自动绑定
    跨境电商ERP中的自动化 1.平台订单自动同步至本地
    小特工具箱3.0版发布 春节优惠价99元/套
    河南农信移动支付解析
    win10 chrome 百分浏览器 centbrowser 收藏夹栏字体突然变小
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12456556.html
Copyright © 2011-2022 走看看