Why getDerivedStateFromProps is called after setState?

后端 未结 5 1592
别那么骄傲
别那么骄傲 2021-02-06 23:02

React introduced new static method getDerivedStateFromProps(props, state) which is called before every render method, but why? Calling it after prop change makes se

相关标签:
5条回答
  • 2021-02-06 23:41

    For this case (updating the state based on props change), use:

    componentDidUpdate(prevProps) {
      // don't forget to compare props
      if (this.props.userID !== prevProps.userID) {
        this.fetchData(this.props.userID);
      }
    }
    

    componentDidUpdate will get called after each update (due to props changes / state changes). so you should check if the prop is changed (by this.props.userID !== prevProps.userID).

    0 讨论(0)
  • 2021-02-06 23:46

    The way getDerivedStateFromProps hook works whenever the new props, setState, and forceUpdate is being received.

    In the version of 16.3, React is not affecting getDerivedStateFromProps whenever the setState is being used. But they improved it in the version starting with 16.4, so whenever the setState is being called the getDerivedStateFromProps is being hooked.

    Here's extracted image from React lifecycle diagram:

    16.3

    ^16.4


    So, it's up to you when to hook the getDerivedStateFromProps by checking props and states properly. Here's an example:

    static getDerivedStateFromProps (props, state) {
      // check your condition when it should run?
      if(props.currentMonth != state.currentMonth) {
        return {
          currentMonth: state.currentMonth
        }
      }
      // otherwise, don't do anything
      else {
       return null
      }
    }
    
    0 讨论(0)
  • 2021-02-06 23:48

    I did something like this

    constructor(props) {
        super(props);
        this.state = {
            expanded: props.expanded,
            ownUpdate: false
        }
    }
    
    static getDerivedStateFromProps(props, state) {
        if (state.ownUpdate) {
            return {
                expanded: state.expanded,
                ownUpdate: false
            };
        } else if (props.expanded !== state.expanded) {
            return {
                expanded: props.expanded
            };
        }
        return null;
    }
    
    toggle() {
        this.props.onAftePress(this.state.expanded, this.props.index);
        this.setState({
            expanded: !this.state.expanded,
            ownUpdate: true
        })
    }
    
    0 讨论(0)
  • 2021-02-06 23:51

    I also got that issue. So I set another variable to check is that prop received for the first time.

    this.state={flag:true}
    

    In getderivedstatefromprops

    static getderivedstatefromprops(props, state){
       if(props.<*propName*> && flag){
          return({ props.<*propName*>, flag:false})
       }
    }
    

    if you want to use multiple props values you need to set your if statements (or any other logic) accordingly.

    0 讨论(0)
  • 2021-02-07 00:06

    you have the answer in your question itself. "which is called before every render method". Whenever you do a setState the render method will be called.

    I would suggest that you lift the state variables currentMonth and currentYear to the parent component and pass them as prop along with other three. You can also pass the change handler as prop and call it from the child.

    on initial render - currentMonth and currentYear can be set to null, so that you can have the logic for showing default stuff. When someone chicks on month name, you can call the changeHandler from parent which will pass the new prop. Now in getderivedstatefromprops you no longer have currentMonth and currentYear as `null so you know that the month has changed.

    0 讨论(0)
提交回复
热议问题