• [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}
  • 相关阅读:
    团队-团队编程项目作业名称-最终程序
    《团队-中国象棋-项目总结》
    课后作业-阅读任务-阅读提问-4
    《20171130-构建之法:现代软件工程-阅读笔记4》
    《软件工程课程总结》
    《20171117-构建之法:现代软件工程-阅读笔记-3》
    -课后作业-阅读任务-阅读提问-3
    《团队-中国象棋-团队一阶段互评》
    《团队-中国象棋-开发文档》
    《结对-贪吃蛇-结对项目总结》
  • 原文地址:https://www.cnblogs.com/Answer1215/p/9552036.html
Copyright © 2020-2023  润新知