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.