React: Warning: getDerivedStateFromProps(): A valid state object (or null) must be returned. You have returned undefined.

Created on 6 Apr 2018  路  14Comments  路  Source: facebook/react

Do you want to request a feature or report a bug?

Depends on how you look at it. Sure looks like a bug to me.

What is the current behavior?

When getDerivedStateFromProps() doesn't explicitly return anything a warning is being output to the console:

Warning: getDerivedStateFromProps(): A valid state object (or null) must be returned. You have returned undefined.

What is the expected behavior?

Treat undefined as null.

It's really inconvenient to add an extra unneeded return null statement in the end of getDerivedStateFromProps().
It is an unnecessary complication of code, adding a no-op line, making everybody's code less clean.
There's no reason not to treat undefined same as null.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

16.3.1

Most helpful comment

Right, I see your point. I still disagree with it. We want both the cases where you do and where you don't want to update state in response to props to be very explicit. This is explicit.

All 14 comments

Hey there, the intent (as far as i understand) is to be explicit about ones intent. undefined can mean "forgot to do anything" (e.g. no return), whereas returning null is an explicit action on the dev to opt out of making any changes. This is also consistent with how the function version of setState works: this.setState(state => null).

Yes, in general we prefer explicit APIs in React, and this was an intentional decision. I don't agree writing four characters more makes the code "less clean".

@gaearon

I don't agree writing four characters more makes the code "less clean".

Not four, more like fifteen.

static getDerivedStateFromProps(props, state) {
  if (props.value !== state.value) {
    return {
      value: props.value,
      ...
    };
  }
  // THIS LINE. TOTALLY UNNECESSARY.
  return null;
}

Right, I see your point. I still disagree with it. We want both the cases where you do and where you don't want to update state in response to props to be very explicit. This is explicit.

Ok.

This also follows the precedent set by render where React warns about an undefined return value. This is to warn about potential mistakes where someone perhaps writes an if/else statement incorrectly or forgets to handle a case.

Hi all, I can't get prev state in getDerivedStateFromProps as the second param, it gives me an empty object always, why?

@Sulsummer
that means the component is rather getting created again...

Hi @Sulsummer 馃槃 This issue is closed, and from the sounds of it- about something other than what you're reporting.

Please file a new issue with repro steps if you think you've found a bug with React.

As @thecodejack mentions, please rule out the fact that your component is just being recreated (iwth a fresh state).

Thanks guys! @thecodejack @bvaughn I'm really new to React and it seems the child component is created twice at least but I can't tell why, all I do were passing data to the child component via props.
And I had to get it done at that time so I finally prevented to use getDerivedStateFromProps.

How does returning an empty object {} work in terms of updating state? Does it follow the same code path that returning null follows? Does it cost anything extra?

I ask because it seems natural to do this:

static getDerivedStateFromProps(nextProps, prevState)
  let nextState = {};
  if (something()) {
    nextState.foo = 'bar';
  }
  if (somethingElse()) {
    nextState.baz = 'qux';
  }
  return nextState;
}

And not so natural to do this every time:

static getDerivedStateFromProps(nextProps, prevState)
  ...
  return Object.keys(nextState).length ? nextState : null;
}

It's not a big deal since it's a small detail; I'm only curious. An empty object would be considered an explicit way of saying "no updates are necessary."

Currently, returning an empty object is pretty much the same as returning null. We would do a shallow merge of the empty object properties (it has none) and then proceed as normal.

https://github.com/facebook/react/blob/a9abd27e4f5aa1e68bd6035be901299327279ee2/packages/react-reconciler/src/ReactUpdateQueue.js#L418-L423

When returning an Empty Object to getDerivedStateFromProps, will it trigger a re-render?

When returning an Empty Object to getDerivedStateFromProps, will it trigger a re-render?

If getDerivedStateFromProps is called, a render is already in progress (it has already been "triggered"). Whether or not it will be continue depends on what your component's shouldComponentUpdate method returns.

React 16.4+ lifecycles shows the flow for 16.4+:
image

Was this page helpful?
0 / 5 - 0 ratings