Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

class Canvas extends React.Component{

    saveRef = node => {
        this._canvas = node;
    }
    
    shouldComponentUpdate(){
        /*I will never re-render this component*/
        return false;
    }
    
    componentWillReceiveProps( nextProps ){
        /*Here I do manipulations with this._ctx, when new props come*/
    }
    
    render(){
        return (
            <canvas ref={this.saveRef} />
        );
    }
    
    componentDidMount(){
        this._ctx = this._canvas.getContext( "2d" );
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

React community began to deprecate componentWillReceiveProps in order to replace it with getDerivedStateFromProps. I can use componentDidUpdate to perform my drawings, but then I need to remove shouldComponentUpdate and I will have a lot of useless render calls. What is the correct performant way to update my component in react 16.3, when new props come?

like image 989
Alex Fomin Avatar asked Apr 12 '18 01:04

Alex Fomin


People also ask

What is the correct order of life cycle methods for updating?

The three phases are: Mounting, Updating, and Unmounting.

Which lifecycle method will you use to update a local state via props update after the component has been mounted?

componentDidUpdate() This method gets invoked immediately after the component is updated and re-rendered. It receives the prevState and prevProps as parameters and can also access the newly changed state or props.

Which lifecycle method we can get an updated state in parent flowed as updated props in child?

componentDidUpdate() A most common use case would be, updating the DOM in response to prop or state changes.

Where does props get updated in lifecycle?

In this article, we are going to see how to execute a function if the props passed to the component is updated in the DOM tree. This method is used during the updating phase of the React lifecycle. This function is generally called if the props passed to the component change.


1 Answers

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)}
      />;
  }
}
like image 159
Dan Abramov Avatar answered Oct 13 '22 18:10

Dan Abramov