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

  • 相关阅读:
    vue 使用print.js实现前端打印功能
    lin UI微信小程序组件库
    将博客搬至CSDN
    第20节:Java集合框架 【多测师_王sir】
    第19节:Java三大特性-多态之接口 【多测师_王sir】
    第18节:Java练习题 【多测师_王sir】
    第17节:Java三大特性-继承之重写 【多测师_王sir】
    第16节:Java练习题【多测师_王sir】
    第15节:Java三大特性【多测师_王sir】
    第14节:Java练习题【多测师_王sir】
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12456556.html
Copyright © 2011-2022 走看看