2

Currently using getDerivedStateFromProps for the first time. My code works and it does what I want it to do, but I am getting a warning in my console that is confusing to me since my code is working. Warning : "getDerivedStateFromProps(): A valid state object (or null) must be returned. You have returned undefined." Is there a better way of writing the getDerivedStateFromProps in order to get rid of the warning in the console?

static getDerivedStateFromProps(props, state) {
 state.currentUser.id =
   props.location.state && props.location.state.user
     ? props.location.state.user.id
     : state.currentUser.id;
 state.currentUser.name =
   props.location.state && props.location.state.user
     ? props.location.state.user.name
     : state.currentUser.name;
 state.currentUser.roles =
   props.location.state && props.location.state.user
     ? props.location.state.user.roles
     : state.currentUser.roles;
 state.currentUser.hasAuthenticated = true;
}
eneooo
  • 368
  • 3
  • 11
  • `state.currentUser.id =` this mutates the state, which is a big no-no in React. You should construct a new modified state object and return it at the end of this function. – Emile Bergeron Sep 20 '19 at 17:49
  • 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. – Shaik Md N Rasool Jul 01 '20 at 02:00

2 Answers2

2

The getDerivedStateFromProps method should return the updated slice of state, instead of updating the state object passed as an argument.

return {
  currentUser: {
    ...state.currentUser,
    id: props.location.state && props.location.state.user ? props.location.state.user.id : state.currentUser.id,
    name: props.location.state && props.location.state.user ? props.location.state.user.name : state.currentUser.name,
    roles: props.location.state && props.location.state.user ? props.location.state.user.roles : state.currentUser.roles,
    hasAuthenticated: true;
  }
}

I've added ...state.currentUser in case there are some other fields of state.currentUser that you want to preserve into the new state.

cbr
  • 12,563
  • 3
  • 38
  • 63
1

You most likely don't need to use getDerivedStateFromProps: official docs explaining why.

It seems that what you want to do is update the state based on changing props, in which case componentDidUpdate() is more suitable, but also, you seem to be replicating the state based on your incoming props.

Simply accessing them inside your render should be enough; they don't require difficult computation. Just as a dummy example:

render() {
  const { userName, id } = this.props.currentUser;
  const hasAuthenticated = id && userName;

  return (hasAuthenticated)
  ?  <WelcomeMessage />
  :  <Login />
}
Yuan-Hao Chiang
  • 2,484
  • 9
  • 20