What is correct lifecycle method in React 16.3 to update canvas from props?

后端 未结 2 1017
余生分开走
余生分开走 2021-02-01 07:35

I have a Canvas component, which looks approximately like this:

<
相关标签:
2条回答
  • 2021-02-01 07:51

    I found this because I had a sort of similar problem but not completely the same. The solution that works for me is just to put all the relevant code in shouldComponentUpdate:

    (the if statement used to be in componentWillReceiveProps)

      shouldComponentUpdate (nextProps, nextState) { // no more random renders
        if (
          (nextProps.nightMode !== this.props.nightMode) ||
          (nextProps.language  !== this.props.language)
        ) {
          this.props.setRefresh(true)                       // setTimeout means after current operation
          setTimeout(() => this.props.setRefresh(false), 1) // so loading will show for longer than 1ms
        }
    
        return this.props.refresh !== nextProps.refresh
      }
    
    0 讨论(0)
  • 2021-02-01 08:03

    Use componentDidUpdate for DOM manipulations like this. A shouldComponentUpdate won’t really make a difference for a component with a single child that always has the same props. So you should be able to remove it without a significant difference in performance.

    If you've profiled the application and determined that in this particular case it does make a difference, you can hoist the element into constructor.

    This way React will skip over it completely (which effectively works the same way as shouldComponentUpdate):

    class Canvas extends React.Component {
      constructor(props) {
        super(props);
        this._ctx = null;
        this._child = <canvas ref={node => {
          this._ctx = node ? node.getContext('2d') : null
        } />;
      }
    
      componentDidUpdate(prevProps){
        // Manipulate this._ctx here
      }
    
      render() {
        // A constant element tells React to never re-render
        return this._child;
      }
    }
    

    You could also split it into two components:

    class Canvas extends React.Component {
      saveContext = ctx => {
        this._ctx = ctx;
      }
    
      componentDidUpdate(prevProps){
        // Manipulate this._ctx here
      }
    
      render() {
        return <PureCanvas contextRef={this.saveContext} />;
      }
    }
    
    
    class PureCanvas extends React.Component {
      shouldComponentUpdate() {
        return false;
      }
    
      render() {
        return (
          <canvas
            ref={node => node ? this.props.contextRef(node.getContext('2d') : null)}
          />;
      }
    }
    
    0 讨论(0)
提交回复
热议问题