Hacker News new | ask | show | jobs
by myth_drannon 3007 days ago
Does anyone finds the new getDerivedStateFromProps adds too much boilerplate code for the developer to write and be aware? So for every previous prop that I need to compare with I need to remember to update it in the state? If before it was as simple as this.props.X!==nextProps.X now I need to set the state with the current prop!
3 comments

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.

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.

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.

For different reasons I don't use Redux that much in my app. The state is persisted in the url, or to be more precise React-Router's location. So let's say I have five different components on the page. All of them receive location and history as props. Each component updates the url separately, let's say a table updates the url with sort1=blah now the component needs to read this param compare next and current and fetch the new data in componentWillReceiveProps. All components verify if the url was updated with the url param they need and only the one that had it changed will fetch data. I use componentWillReceiveProps everywhere. I'm not sure if there is another life cycle to do just that.
I believe it's in the blog post:

https://reactjs.org/blog/2018/03/27/update-on-async-renderin...

(TLDR: Use `componentDidUpdate` for this.)

Have you had a chance to skim through it?

Yes, I also saw your post on twitter. I will try to use it from now on. Thanks!
Personally, I find the word "derived" to be a somewhat unfortunate choice
Why is that?
Doesn't feel like it's needed. "getStateFromProps" would have been fine. I think any state "derivation" from props is implied.
We intentionally made the naming a little bit obtuse. A name like `getStateFromProps` implies this is a common operation because it sounds so “normal”. And this is, in fact, a common misconception with React beginners who try to copy props into state instead of using props directly or lifting state up. So we wanted the naming to reflect that this pattern is not supposed to be the most common.
This naming choice makes sense now!