Reactjs.org: Using getDerivedStateFromProps/componentDidUpdate when shouldComponentUpdate returns false

Created on 15 Apr 2018  路  1Comment  路  Source: reactjs/reactjs.org

Hi!

I've just read your example on how to migrate to getDerivedStateFromProps from componentWillReceiveProps (https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples) and I think I have a use case that is not covered there:

In my application I have a component that wraps a d3/nvd3 chart. To do that I initially render an svg tag in the component's render function that is later on "managed" by d3. In componentDidMount I create the initial chart with the properties initially passed to the component. To avoid re-rendering of the DOM nodes that are generated by d3, I then always return false in shouldComponentUpdate.

When the properties (with the data for the chart) are updated, I can update the chart in componentWillReceiveProps as that callback is called even if shouldComponentUpdate returned false before.

Simplified example with React 16.2 using componentWillReceiveProps:

export default class Chart extends React.Component {
  shouldComponentUpdate() { 
    // I NEVER want this component to be re-rendered,
    // as the svg children are managed by D3

    return false; 
  }

  componentDidMount() {
    this.nvd3chart = ...;
    // ...  creating the actual nvd3/d3 chart left off here ...

    this.d3selection = d3.select(this.chart);
  }

  componentWillReceiveProps(nextProps) {
    const { data } = nextProps;

    // forward data from new next props to the d3 Chart 
    this.d3selection.datum(data).call(this.nvd3chart);
  }

  render() {
    return (
      <div>
        <svg ref={c => this.chart = c} />
      </div>
    );
  }
}

With React 16.3 and getDerivedStateFromProps I don't know how to handle this use-case, as componentDidUpdate, that could be a replacement for getDerivedStateFromProps is not called when shouldComponentUpdate returned false. And as getDerivedStateFromProps is static, I cannot access the instance variables of my component (this.d3selection for example) in that hook.

(btw: I'm not sure if it is really necessary to suppress re-rendering but I want to make sure that React doesn't "destroy" anything that has been created/modified by d3)

Do you have a hint for me how to implement this use-case using the new lifecycle hooks? Thanks you very much!

Most helpful comment

I answered a very similar question here.

https://stackoverflow.com/a/49803151/458193

I want to make sure that React doesn't "destroy" anything that has been created/modified by d3

If that鈥檚 the only reason you had shouldComponentUpdate there you can remove it. React won鈥檛 touch attributes that weren鈥檛 added by React. Similarly it won鈥檛 touch children if from React鈥檚 point of view they never change (which is the case in your example).

>All comments

I answered a very similar question here.

https://stackoverflow.com/a/49803151/458193

I want to make sure that React doesn't "destroy" anything that has been created/modified by d3

If that鈥檚 the only reason you had shouldComponentUpdate there you can remove it. React won鈥檛 touch attributes that weren鈥檛 added by React. Similarly it won鈥檛 touch children if from React鈥檚 point of view they never change (which is the case in your example).

Was this page helpful?
0 / 5 - 0 ratings