Skip to content

Using getDerivedStateFromProps/componentDidUpdate when shouldComponentUpdate returns false #808

Description

@nilshartmann

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions