zoukankan      html  css  js  c++  java
  • [React] Prevent Unnecessary Rerenders of Compound Components using React Context

    Due to the way that React Context Providers work, our current implementation re-renders all our compound component consumers with every render of the <Toggle /> which could lead to unnecessary re-renders. Let's fix that by ensuring that the value prop we pass to the <ToggleContext.Provider /> is only changed when the state changes.

    // Flexible Compound Components with context
    // This allows you to avoid unecessary rerenders
    
    import React from 'react'
    import {Switch} from '../switch'
    
    const ToggleContext = React.createContext()
    
    function ToggleConsumer(props) {
      return (
        <ToggleContext.Consumer {...props}>
          {context => {
            if (!context) {
              throw new Error(
                `Toggle compound components cannot be rendered outside the Toggle component`,
              )
            }
            return props.children(context)
          }}
        </ToggleContext.Consumer>
      )
    }
    
    class Toggle extends React.Component {
      static On = ({children}) => (
        <ToggleConsumer>
          {({on}) => (on ? children : null)}
        </ToggleConsumer>
      )
      static Off = ({children}) => (
        <ToggleConsumer>
          {({on}) => (on ? null : children)}
        </ToggleConsumer>
      )
      static Button = props => (
        <ToggleConsumer>
          {({on, toggle}) => (
            <Switch on={on} onClick={toggle} {...props} />
          )}
        </ToggleConsumer>
      )
      // The reason we had to move `toggle` above `state` is because
      // in our `state` initialization we're _using_ `this.toggle`. So
      // if `this.toggle` is not defined before state is initialized, then
      // `state.toggle` will be undefined.
      toggle = () =>
        this.setState(
          ({on}) => ({on: !on}),
          () => this.props.onToggle(this.state.on),
        )
      state = {on: false, toggle: this.toggle}
      render() {
        return (
          <ToggleContext.Provider value={this.state}>
            {this.props.children}
          </ToggleContext.Provider>
        )
      }
    }
    
    function Usage({
      onToggle = (...args) => console.log('onToggle', ...args),
    }) {
      return (
        <Toggle onToggle={onToggle}>
          <Toggle.On>The button is on</Toggle.On>
          <Toggle.Off>The button is off</Toggle.Off>
          <div>
            <Toggle.Button />
          </div>
        </Toggle>
      )
    }
    Usage.title = 'Flexible Compound Components'
    
    export {Toggle, Usage as default}
  • 相关阅读:
    1115:直方图
    1114:白细胞计数
    1114:白细胞计数
    忘记mysql密码后重置密码
    pycharm中无法导入pip安装的包
    win7升级win10
    WIN7 Windows update提示不支持硬件
    getcwd() 和 os.path.realpath () 的区别
    selenium启动chrome时,弹出设置页面:Windows Defender 防病毒要重置您的设置
    ui测试如何检测页面差异
  • 原文地址:https://www.cnblogs.com/Answer1215/p/9552036.html
Copyright © 2011-2022 走看看