Calling setState() in React from render method
componentWillReceiveProps is deprecated now (since June'18)
You should use one of the alternatives presented in the react docs instead.
In your case I guess it could be justified to use the 'not so recommended' alternative 1 version that uses getDerivedStateFromProps, as you are just recomputing the state vars:
getDerivedStateFromProps(props, state) {
if(props.resetMessages) {
const company = Object.assign({}, state.company);
company.id = 0;
company.messages = [];
return {
company: company
}
}
You might want to look into componentWillReceiveProps(nextProps)
function. As per the official docs:
componentWillReceiveProps()
is invoked before a mounted component receives new props. If you need to update the state in response to prop changes (for example, to reset it), you may compare this.props and nextProps and perform state transitions using this.setState() in this method.
This is where you want to do the resets. So something like:
componentWillReceiveProps(nextProps) {
if(nextProps.resetMessages) {
const company = Object.assign({}, this.state.company);
company.id = 0;
company.messages = [];
this.setState({company: company});
}
}
The snippet above will run every time props are sent down to the component. It first checks if the resetMessages
prop is truthy. If it is, it will create a temporary copy of the company
state, change the id
and messages
property values, and then update company
with the new one.
I want to highlight the issues you had with your code:
Calling
setState()
insiderender()
is a no-no.Whenever you call
setState()
in general therender()
will be run afterwards. Doing so insiderender()
itself will cause that function to be called again, and again, and again...Mutating the state and/or props directly.
This line
const company = this.state.company;
does not create a copy of the state variable. It only store the reference to it. So once you do this, and then docompany.id = ...
you are essentially doingthis.state.company.id = ...
, which is anti-pattern in React. We only ever change state throughsetState()
.To create a copy, use
Object.assign({}, this.state.yourObject)
for objects andthis.state.yourArray.slice()
for arrays.