代码之家  ›  专栏  ›  技术社区  ›  digory doo

防止不必要的重新渲染反应组件

  •  0
  • digory doo  · 技术社区  · 7 年前

    onClick

    class ColorPicker extends React.PureComponent {
      render() {
        console.log('ColorPicker being rendered');
        const fields = this.props.colors.map((color, idx) => {
          const fieldProps = {
            key: `${idx}`,
            color,
            /*onClick: () => { // PROBLEM HERE
              this.props.colorPicked(color);
            }*/
          };
          return <ColorField { ...fieldProps}/>;
        });
        return (
          <div className="bla-picker">
            <div>{`Refresh seed: ${this.props.seed}`}</div>
            {fields}
          < /div>
        );
      }
    }
    

    此组件存在一个小问题:每当 ColorPicker ColorField 一次点击

    render 方法,如下所示: onClick: this.handleClick 处理程序需要捕获 color

    解决这类问题的最佳实践是什么?

    jsfiddle 尝试一下;作为一个片段:

    class ColorField extends React.PureComponent {
      render() {
        console.log('ColorField being rendered');
        const divProps = {
          className: 'bla-field',
          style: {
            backgroundColor: this.props.color
          },
          onClick: this.props.onClick
        };
        return <div { ...divProps}/>;
      }
    }
    class ColorPicker extends React.PureComponent {
      render() {
        console.log('ColorPicker being rendered');
        const fields = this.props.colors.map((color, idx) => {
          const fieldProps = {
            key: `${idx}`,
            color,
            /*onClick: () => { // PROBLEM HERE
              this.props.colorPicked(color);
            }*/
          };
          return <ColorField { ...fieldProps}/>;
        });
        return (
          <div className="bla-picker">
            <div>{`Refresh seed: ${this.props.seed}`}</div>
            {fields}
          < /div>
        );
      }
    }
    
    class Layout extends React.PureComponent {
      constructor(props, ctx) {
        super(props, ctx);
        this.state = {
          seed: 1
        };
      }
      render() {
        const pickerProps = {
          colors: ['#f00', '#0f0', '#00f'],
          colorPicked: (color) => {
            console.log(`Color picked: ${color}`);
          },
          seed: this.state.seed
        };
        return (
          <div>
            <div
              className="bla-button"
              onClick = {this.btnClicked}
            >
              {'Click Me'}
            </div>
            <ColorPicker { ...pickerProps} />
          </div>
        );
      }
      btnClicked = () => {
        this.setState({ seed: this.state.seed + 1 });
      };
    };
    
    ReactDOM.render( <
      Layout / > ,
      document.getElementById("react")
    );
    .bla-button {
      background-color: #aaa;
      padding: 8px;
      margin-bottom: 8px;
    }
    
    .bla-picker {}
    
    .bla-field {
      width: 32px;
      height: 32px;
    }
    <div id="react">
    </div>
    
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

    颜色选取器 console.log 一次点击 色域

    1 回复  |  直到 7 年前
        1
  •  2
  •   teimurjan    7 年前

    你可以实现 shouldComponentUpdate

    class ColorField extends React.Component {
      shouldComponentUpdate(nextProps) {
        return this.props.color !== nextProps.color;
      }
    
      render(){
        const { color, onClick } = this.props;
        console.log('Color re-rendered');
        return (
          <div 
            className="color"
            onClick={onClick}
            style={{ 
              backgroundColor: color,
              height: '50px',
              width: '50px',
            }} 
          />
        )
      }
    }
    

    Example here