• [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])
  • 相关阅读:
    ElasticSearch 分词器
    ElasticSearch 搜索引擎概念简介
    Kibana,Logstash 和 Cerebro 的安装运行
    ElasticSearch 安装与运行
    ElasticSearch 入门简介
    SVM 支持向量机算法-实战篇
    SVM 支持向量机算法-原理篇
    nginx 访问限速
    nginx 开启 autoindex
    nginx 开启 gzip 压缩
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13861915.html
Copyright © 2020-2023  润新知