getDerivedStateFromProps returned undefined

3.8k views Asked by At

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;
}
2

There are 2 answers

0
cbr On BEST ANSWER

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.

0
Yuan-Hao Chiang On

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 />
}