简体   繁体   中英

Set state in React component from props and update when props change?

My React component sets a state property called userInGroup based on props.

    this.state = {
        userInGroup: this.props.user
            ? this.props.user.groups.includes(props.group._id)
            : false,
    };

This works but does not update when the props change and the value of userInGroup should also change, until I refresh the page. How can I make this update reactively?

Maybe I could use componentWillUpdate or componentDidUpdate but then Id be repeating the logic used by userInGroup. Is this repetition inevitable?

You need to use getDerivedStateFromProps . The other methods are now deprecated and deemed unsafe.

getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing.

This method exists for rare use cases where the state depends on changes in props over time. For example, it might be handy for implementing a component that compares its previous and next children to decide which of them to animate in and out.

static getDerivedStateFromProps(props) {
  return {
    userInGroup: props.user
      ? props.user.groups.includes(props.group._id)
      : false,
  }
}

Yes you need to make use of componentWillReceiveProps along with constructor/componentDidMount , when you want to update state when props change since constructor/componentDidMount are called only once when the component mounts, and componentWillReceiveProps() is invoked before a mounted component receives new props or the Parent component updates

You could write a function that contains the logic

this.state = {
        userInGroup: this.getUserStatus();
    };

componentWillReceiveProps(nextProps) {
    if(nextProps.user !== this.props.user) {
        this.setState({userInGroup: this.getUserStatus(nextProps)})
    }
}
getUserStatus = (newProps) => {
    const data = newProps || this.props
    return data.user
            ? data.user.groups.includes(data.group._id)
            : false
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM