Use a background
I don’t like writing componentWillReceiveProps in code, because that would lead to child components too flexible, you don’t know when to just get rid of the state of child components. However, when the child component needs to update its own state based on an attribute in the parent component’s props to render the child, I have to write a code that I don’t like:
class Demo extends Component {
state = {
value: this.props.value
};
componentWillReceiveProps(props){
if(props.value ! = =this.state.value){
this.setState({value:props.value})
}
if(this.props.value){
// Do something that needs this.props}}// ...
}Copy the code
This code should be applied in actual React very common, in the new version of the React, componentWillReceiveProps is marked as unsafe, at the same time, the official getDerivedStateFromProps out of a new life cycle, Cooperate componentDidUpdate officer says, can cover all usage of componentWillReceiveProps
The instructions
ComponentWillReceiveProps can use this. Props, not only can do setState operation, can also with this. Compare the props to do some daily method of operation.
componentWillReceiveProps(props){
if(props.value ! == this.state.value){ this.setState({value:props.value}) }if(this.props. Value){// Do something that needs this.props}}Copy the code
GetDerivedStateFromProps disallows access to this.props, forcing the specified props to be compared only with state, so to speak, for setState.
static getDerivedStateFromProps(props,state){
if(props.value ! == state.value){return {
value:props.value
}
}
return null
}Copy the code
And those things that need this. Props to do are done with componentDidUpdate, Also explains the above getDerivedStateFromProps + componentDidUpdate = componentWillReceiveProps
componentDidUpdate() {if(this.props. Value){// Do something that needs this.props}}Copy the code
You could say that the new life cycle makes it much clearer when to do what, Through forced not to reveal this. Props to componentWillReceiveProps subdivided into getDerivedStateFromProps and componentDidUpdate with their respective responsibilities
Is that the only difference between the two?
Consumption of the test
We respectively in the parent component render and subcomponents componentWillReceiveProps and getDerivedStateFromProps print log
The parent component
class Index extends React.Component {
// ...
render(){
console.log('Parent component Update')
<Demo value={this.state.value}>
}
}Copy the code
Use componentWillReceiveProps child components
class Demo extends Component {
state = {
value: this.props.value
};
componentWillReceiveProps(props){
console.log('componentWillReceiveProps')
if(props.value ! == this.state.value){ this.setState({value:props.value}) } }render(){
console.log('Sub-component Update') / /... }}Copy the code
Printable result of initialization of sub-component:
Parent component updates child component updatesCopy the code
The child component updates the printable result of state.value:
Child components updated parent component componentWillReceiveProps child components updatedCopy the code
2. Use getDerivedStateFromProps for subcomponents
class Demo extends Component {
state = {
value: this.props.value
};
static getDerivedStateFromProps(props,state){
console.log('getDerivedStateFromProps')
if(props.value ! == state.value){return {
value:props.value
}
}
return null
}
render(){
console.log('Sub-component Update') / /... }}Copy the code
Printable result of initialization of sub-component:
Parent component updated getDerivedStateFromProps child component updatedCopy the code
The child component updates the printable result of state.value:
The getDerivedStateFromProps subcomponent is updated. The parent component is updated. The getDerivedStateFromProps subcomponent is updatedCopy the code
This makes it clear that the getDerivedStateFromProps function fires not only when the props change, but every time the render (state and props update) is performed
GetDerivedStateFromProps is also triggered when the state of a parent component changes, not just the child component’s render
Most cases of alternative componentWillReceiveProps method
When I plans to replace my componentWillReceiveProps getDerivedStateFromProps, see an article from the React you may not need to use the derived the state official blog, although last year’s article, But I still feel like I want to double click on 666.
Anyone familiar with React knows that whether the key values are the same or not is how React decides whether to recreate or update components.
And again, we can use this principle for our example.
Set the key value in our parent component:
<Demo key={item.value} callback={changeValue}>Copy the code
Remove getDerivedStateFromProps/componentWillReceiveProps child components
Every time the state.value of the Demo component changes, it triggers a props change. What we did in getDerivedStateFromProps was to change the state of the child component when the props changed.
Now let’s recreate the Demo component every time the key changes by assigning a key. This sounds slow, but the performance is negligible. If there is heavy logic in the Demo component tree, the creation is faster than the update because the diff of the child component is omitted
In most cases, this is the best way to handle resetting state.