zoukankan      html  css  js  c++  java
  • [React] Performance: Split state update and component render with Hoc

    For the follow code:

    function Cell({row, column}) {
      const state = useAppState()
      const cell = state.grid[row][column]
      const dispatch = useAppDispatch()
      const handleClick = () => dispatch({type: 'UPDATE_GRID_CELL', row, column})
      return (
        <button
          className="cell"
          onClick={handleClick}
          style={{
            color: cell > 50 ? 'white' : 'black',
            backgroundColor: `rgba(0, 0, 0, ${cell / 100})`,
          }}
        >
          {Math.floor(cell)}
        </button>
      )
    }
    Cell = React.memo(Cell)

    'useAppState()' is using context. 

    function useAppState() {
      const context = React.useContext(AppStateContext)
      if (!context) {
        throw new Error('useAppState must be used within the AppProvider')
      }
      return context
    }

    The way that context works is that whenever the provided value changes from one render to another, it triggers a re-render of all the consuming components (which will re-render whether or not they’re memoized).

    The way to improve the performance is that: 

    Split the code which cause re-render (context changes) with the code actually do the rendering

    Hoc can help with that:

    function withStateSlice(Comp, slice) {
      const MemoComp = React.memo(Comp)
      function Wrapper(props, ref) {
        const state = useAppState()
        const cell = slice(state, props)
        return <MemoComp ref={ref} state={cell} {...props} />
      }
      Wrapper.displayName = `withStateSlice(${Comp.displayName || Comp.name})`
      return React.memo(React.forwardRef(Wrapper))
    }
    
    function Cell({state: cell, row, column}) {
      const dispatch = useAppDispatch()
      const handleClick = () => dispatch({type: 'UPDATE_GRID_CELL', row, column})
      return (
        <button
          className="cell"
          onClick={handleClick}
          style={{
            color: cell > 50 ? 'white' : 'black',
            backgroundColor: `rgba(0, 0, 0, ${cell / 100})`,
          }}
        >
          {Math.floor(cell)}
        </button>
      )
    }
    Cell = withStateSlice(Cell, (state, {row, column}) => state.grid[row][column])
  • 相关阅读:
    音频波谱通用类|超酷的说
    跟随鼠标的星星实例
    AS3放大镜工具类
    caurina缓动类
    AS3中 is,as,typeof的区别
    Loader ,URLLoader ,URLStream的区别
    (转)AS3正则:元子符,元序列,标志,数量表达符
    动态绘制扇形实例
    AS3.0绘图API
    as3效率优化
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13861915.html
Copyright © 2011-2022 走看看