I am not sure if current behavior is correct or not.
In 16.3 I was successfully using getDerivedStateFromProps when I had a component that had received its state via props, checking between props and state (or is it more succinct to say prevState and nextProps) using said function was just fine. It updated the state when new props came in, and changes to state functioned as normal.
Now in 16.4 because calls to setState also trigger getDerivedStateFromProps, I'm seeing an unexpected result. The state to which it compares is already updated to the new state (logically?) but since props or nextProps remain unchanged my comparison updates to the current set props. These are logically unchanged as I only changed the state. So, my calls to set state now fail. Maybe I'm doing it wrong? Maybe it should compare to the state as is was before setState was called? This is what I would expect, and would solve the problem because the real previous state will match the props and no change will occur.
here is an example: https://jsfiddle.net/rjacks24/1yupwngv/
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
stopped: this.props.stopped || false
};
this.wasToggled = false;
this.toggleStop = this.toggleStop.bind(this);
}
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.stopped !== nextProps.stopped) {
return { stopped: nextProps.stopped };
}
return null;
}
/**
* function to handle the stop of the antenna
* @returns {void}
*/
toggleStop() {
this.wasToggled = !this.wasToggled;
this.setState({
stopped: !this.state.stopped
});
}
render() {
return (
<div>
<button
type="button"
onClick={this.toggleStop}
className={this.state.stopped ? "done" : ""}
>
Toggle
</button>
State Toggled? {this.state.stopped ? "yes" : "no"}
<div>
But Actually... wasToggled: {this.wasToggled ? "yes" : "no"}{" "}
</div>
</div>
);
}
}
The expected behavior is that which you get by removing the codeblock for getDerivedStateFromProps(), however, updates from heigher up to props aren't then handled,the way they should be.
I apologize if I am just doing it wrong, but since I was good in 16.3, if figured it's at least worth bringing up for discussion. This person seems to be experiencing the same thing, but my example is a bit easier: Proper use of React getDerivedStateFromProps
My guess is that the correct way in these cases is to always handle the state on the HOC, then calling gdsfp is not a problem.
tldr; 16.3 let me change state while using getderivedStateFromProps, 16.4 does not.