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])
  • 相关阅读:
    如何重新加载 Spring Boot 上的更改,而无需重新启动服务器?
    FileUpload拦截器
    aspnet网页刷新
    查看SQL表的详细信息
    学习GDI+ (1)
    设计模式简单工厂模式
    对数据库表操作,统一的方法。
    随机产生300道四则运算
    略谈从计算机专业,再到软件构建的初识
    #在android studio中维护日程管理系统
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13861915.html
Copyright © 2011-2022 走看看