Hacker News new | ask | show | jobs
by danabramov 3007 days ago
This lifecycle exists for a fairly rare use case. Why do you use it often? Instead of keeping state “in sync” with the props, can you just read it from the props?

For the rare cases where you do want to retain previous props, yes, we’re asking you to be explicit about it. This will allow better memory usage in future versions of React, and also avoids the need for an extra `prevProps !== null` check that would need to happen in every `getDerivedStateFromProps` method.

2 comments

Responding to "exists for a fairly rare use case" statement, I just searched the the web app I am currently writing and it uses componentWillReceiveProps() ~20 times. Most cases are for detecting changes requiring freeing/fetching network based resources where the data involved can get excessive if care is not taken. This would seem to be a common scenario for many domains. On a sidenote, I have thoroughly enjoyed working with react and RN over the last 4 years and have learned much from dan's work. Thanks guys.
>I just searched the the web app I am currently writing and it uses componentWillReceiveProps() ~20 times.

How many components do you have? Absolute number doesn’t tell me a lot. :-)

>Most cases are for detecting changes requiring freeing/fetching network based resources where the data involved can get excessive if care is not taken.

Not sure I fully understand. Could you provide a small example?

Component count is around 140. Fwiw, some are stateless, functional components while others are more complex.

A form of master/detail is driving the need to detect prop changes to fetch additional data while freeing previous data. Consider the master/detail of multiple levels deep driven by route parameters through the ui hierarchy. In RN, this is less of an issue since screens tend to be more focused and ui stack driven. But users working full-time in a complex ui specialized for power users can require much more data/dynamism.

Fair enough. As mentioned in Update on Async Rendering blog post, there’s a less verbose data fetching API coming down the line (“suspense”). Not quite ready for the release yet. But it will require components to be async-compatible which is why we're getting these lifecycle changes out now.
Intriguing. Been too busy cranking on a new product to stay up on the latest changes so thanks for the pointer. I have lots of reading to do.

And thanks for listening about my use case. One concern about using a static function for getDerivedStateFromProps() is that it will not allow for taking instance variables into account. Have not thought through how that might come into play but components certainly allow for this, though many may feel it a strange idea. Perhaps a reference to the component could be passed as well as an additional argument.

I look forward to coming up for air and catching up with the improved approach. Things continue to move quickly and I continue to be impressed at how the changes bring improvement to the ecosystem.

Lack of instance is intentional—otherwise we would’ve made it an instance method. Happy to hear about specific patterns you’re aiming for but since getDerivedStateFromProps executes during the “render phase” (interruptible in async mode) we want people to treat it as pure and discourage them from any side effects and mutations. If you really need some instance variable there then perhaps you could move it into state.
I have 27 componentWillReceiveProps across 286 components, so not a whole lot. But in almost none of those do I update the component state, the most common thing is to compare the previous and new props and dispatch some Redux action that will start a load of some data, which will eventually update the props (of multiple components) via Redux. I guess I should start using componentDidUpdate instead?

The other case of componentWillReceiveProps usage I see is where there is computationally expensive derived state, but for some reason the asynchronous nature of setState prevented it from being used, and an instance variable "had" to be used instead. There are a few cases of these where after much hair pulling the instance variable "fixed" the issue.

> I guess I should start using componentDidUpdate instead?

Sounds like it, based on your description!

> The other case of componentWillReceiveProps usage I see is where there is computationally expensive derived state, but for some reason the asynchronous nature of setState prevented it from being used, and an instance variable "had" to be used instead.

`setState` calls made from within `componentWillReceiveProps` are processed (synchronously) before `componentWillUpdate` or `render` are called.