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])
  • 相关阅读:
    各种数据类型的取值范围(总结全)
    Help Johnny-(类似杭电acm3568题)
    ExtJs 设置GridPanel表格文本垂直居中
    批处理通过字符串截取得到文件名
    sql优化-提防错误关联
    Unix Domain Socket 域套接字实现
    solr源码分析之数据导入DataImporter追溯。
    spark初识
    Spark:一个高效的分布式计算系统--转
    Importing/Indexing database (MySQL or SQL Server) in Solr using Data Import Handler--转载
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13861915.html
Copyright © 2011-2022 走看看