0

This question has already been answered here but things are always changing.

componentWillReceiveProps is deprecated now and it will be removed soon.
So, what is the cleanest way to update a child component when the parent needs to fetch some data?

See the old question for more details.
Thanks

UPDATE:

Basically, the parent component fetches some data and the child component needs that data.

This is the child component.

class Dropdown extends React.Component {
constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
}


// This is deprecated so need to be replaced by your answer
componentWillReceiveProps(nextProps) {
    this.setState({
        value: nextProps._layouts[0]
    });
}


handleChange(event) {
    this.setState({
        value: event.target.value
    });
}

render() {
    // The options for the dropdown coming from the parent
    const options = this.props._layouts.map((number) =>
        React.createElement("option", null, number)
    )

    // This logs the value coming from the parent
    // A timeout is needed since fetch is asynchronous
    setTimeout(() => {
        console.log(this.state.value)
    }, 400);

    // This is just a dropdown menu
    return React.createElement("div",
        null, React.createElement("span", {
            class: "custom-dropdown"
        }, React.createElement("select", {
            onChange: this.handleChange,
        }, options)));
    }
}
isar
  • 1,661
  • 1
  • 20
  • 39
  • 2
    The parent fetches the data and updates its own state... The state (or a portion of it gets passed to the child via props... The state updates, the props update... No need for a lifecycle method here at all... If you need more granular control of rerendering then look at the methods available for each use case here: https://reactjs.org/docs/react-component.html#updating – SakoBu Feb 18 '19 at 18:24
  • Re _"See the old question for more details."_, your question should be freestanding, and not depend on any another question. What if that other question gets closed? If more details are needed for your question then embed them rather than linking to somewhere else. – skomisa Feb 18 '19 at 18:45
  • @skomisa I updated the answer. Please, tell me if I need to change anything. – isar Feb 18 '19 at 20:47

2 Answers2

1

You can use the shouldComponentUpdate(nextProps,nextState) and return true if the props or state changed in the parent.

More info in the react documentation

davbuc
  • 537
  • 6
  • 14
0

The lifecycle method that replaced componentWillReceiveProps is static getDerivedStateFromProps. (Actually that's not entirely true, but you can achieve the same result with it)
The function is static, and receives the state and props of the component, and returning a new object to merge into the component's state.

But the real question is - do you really need it? The answer from the question above (slightly adjusted):

getDerivedStateFromProps(nextProps) {
  return nextProps.data;
}

simply does nothing. You can just as well use the props instead of the state.
As the React doc says:

This method exists for rare use cases where the state depends on changes in props over time.

Dor Shinar
  • 1,474
  • 2
  • 11
  • 17
  • `componentWillReceiveProps` let me set the state while `static getDerivedStateFromProps` does not. How do I set the state without using `componentWillReceiveProps`? – isar Feb 18 '19 at 20:58
  • `this.state = {value: props.value}` inside the constructor works just fine but was considered antipattern so I used `componentWillReceiveProps` which is now deprecated. – isar Feb 18 '19 at 21:02
  • With `getDerivedStateFromProps`, the value you return will be merged with the state. No need to call `this.setState()` yourself. – Dor Shinar Feb 18 '19 at 21:03
  • It doesn't seem: when logging `componentWillReceiveProps` gives me the updated props I expect, `getDerivedStateFromProps` gives me `undefined`. – isar Feb 18 '19 at 21:09
  • Can you provide the way you implemented `getDerivedStateFromProps`? – Dor Shinar Feb 19 '19 at 05:05
  • I implemented it how you suggested above `return nextProps._layouts[0];`. In the end, I decided not to set the state in the child component anymore. Thanks anyway. – isar Feb 19 '19 at 16:00