3 ms·
>It's not that rare. Consider a route change where some state needs to be preserved or, like the article mentions, a scroll position change (or reset!). In my
by danabramov 9y ago
>It's not that rare. Consider a route change where some state needs to be preserved or, like the article mentions, a scroll position change (or reset!).
In my anecdotal experience this code is still pretty rare (compared to overall number of components). You don't need this hook to reset scroll position (`componentDidUpdate` alone is sufficient) or maintain it (browser does this automatically if the inserted DOM height is enough to cover it).
The use case for `getSnapshotBeforeUpdate` refers to cases where you have a list that needs to track its current position during offscreen insertions (for example, new items loaded above in the feed) or a list that “catches up” with new content (for example, a message thread that auto-scrolls to the last message unless you’re in the middle of a conversation).
>The constructor is meant to initialize internal and initial state of objects. Making a data/network request in the constructor is beyond bizarre.
I am not suggesting to do network requests in it. Please see the link I pointed to: it shows initializing initial state. Not data fetching.
To be clear: today in React there is no way to asynchronously fetch data on the server. It’s just not supported (and we’re aware it’s an unfortunate limitation). So if the data is already available synchronously (which in your case it seems to be because you said you were able to use `componentWillMount` for this which is also synchronous on the server), then you can synchronously read it in the constructor. If it’s not available synchronously, then there’s nothing `componentWillMount` gives you anyway.
In either case, this limitation is exactly what motivates our work on React Suspense (which will support waiting for data both on the server and on the client). But to support this API, we need to make component compatible with async rendering first. Which is what this blog post is all about.
>I'll have to check out suspense, but I feel that it's yet another API that reinvents the wheel. We'll see.
You’re welcome to start watching the RFC repository and comment when we post more technical details about it. We think it adds a capability that’s always been missing in React (pausing rendering while keeping the screen consistent) and I hope you’ll find it useful.
- smashed 9y ago> To be clear: today in React there is no way to asynchronously fetch data on the server. It’s just not supported What we've done for the past few years is trigger async fetches in componentWillMount on the server and perform multiple renderToString. This requires some instrumentation so you can monitor that all the data has loaded and your tree is fully rendered. Removing componentWillMount will force us to rewrite everything to the suspense API. I hope that transition won't cause too many headaches.
- danabramov 9y ago>perform multiple renderToString The downside of this is that the cost of rendering is multiplied. We know it’s an existing workaround but it’s not a good long term solution. We want to enable something better. >Removing componentWillMount will force us to rewrite everything to the suspense API. This is not accurate. The blog post states that `UNSAFE_componentWillMount` is here to stay so you can keep using that until we have a first-class data fetching solution that works both on the client and the server. You can also use the constructor for this (it’s technically equivalent to `componentWillMount`). While it contradicts what I said earlier (avoid side effects in constructor) you’re already using a hack (rendering twice) and I’d argue this is no worse as a temporary solution. Don’t forget that `componentWillMount` is equivalent to the constructor for all intents and purposes, and only exists because it predates ES6 classes (and the ability to define a constructor). So you were already doing side effects in what is effectively a constructor. Still, the upcoming Suspense API mentioned in the blog post is the intended long term solution to this. It will work both on the client and the server, and it will allow you to remove the double rendering hack. But to prepare for Suspense, we need to make components compatible with async rendering (which is what the blog post is all about). We added a section to the blog post which I hope clarified it: >When supporting server rendering, it’s currently necessary to provide the data synchronously – componentWillMount was often used for this purpose but the constructor can be used as a replacement. The upcoming suspense APIs will make async data fetching cleanly possible for both client and server rendering. So you can keep using `UNSAFE_componentWillMount` or constructor for now, and migrate to Suspense when it’s ready (and render your app in a single pass).
- smashed 9y agoThanks for the detailed explanation. Makes sense and I will keep an eye on the upcoming suspense API.