facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
229.3k stars 46.96k forks source link

React 18 data fetching network call cancellation #21701

Open rybon opened 3 years ago

rybon commented 3 years ago

I understood from various discussions online that for Suspense for data fetching to work properly React needs to be more directly involved in the mechanics of fetching data from the network. How will that work in practice? Would it take care of XHR cancellation for example in case a Suspense subtree is no longer needed or changes props? What will it mean for using libraries like Axios? Can strategies like retry with exponential backoff still be implemented? HTTP caching behavior?

gaearon commented 3 years ago

for Suspense for data fetching to work properly React needs to be more directly involved in the mechanics of fetching data from the network

I'm not quite sure what this means. (More involved compared to which approach?) Suspense is a mechanism for a part of the tree to say it's not ready, and to notify React when it's time to retry. When React retries, it expects any fetched result to be resolved form the cache. There is a contract for how it should happen. But React itself is not involved with fetching or network.

Would it take care of XHR cancellation for example in case a Suspense subtree is no longer needed or changes props?

No. Fetches fill the cache. At least currently, we're still filling the cache if the response comes back, whether it's needed by an active tree or not. For example if you keep quickly switching between tabs, we'll still fill the cache when either response comes back rather than keep cancelling them. I don't think it's impossible we'd add some kind of abort mechanism but it's pretty tricky because it's hard to say when something is truly no longer needed. However, note that in our model there is no rendering CPU work directly attached to handling the response. In other words, when the request comes back, it's not going to trigger a bunch of stale or useless rendering logic. All it does is tell React it can retry that part of the tree. And if that part of the tree is no longer waiting for that Promise, it should be ignored. At least that's my understanding. (But I might be wrong about implementation details, so please correct me if you see it behaving differently.)

What will it mean for using libraries like Axios?

Nothing in particular. We'll provide a solution for the common case (see react-fetch here) but there's nothing special about react-fetch: you could write your own on top of the same contract (https://github.com/reactwg/react-18/discussions/25). But this is the part that isn't fully designed yet.

Can strategies like retry with exponential backoff still be implemented? HTTP caching behavior?

You can implement anything at the network layer. React is only concerned with how you cache the result on the client (because it will provide a cache for you) and how you notify it about the results.

bbohlender commented 3 years ago

I think an abort mechanism would be very helpful for applications that do more than a simple web request. But even in this case, there might be a big file download; the user does not want to wait and clicks on the next file, which then also starts to download. When the user selects a third file, which might be much smaller, it will also be loaded very slow, since the system still fetches the other files. Of course, not aborting the requests has the advantage, that eventually all files will be cached, and the user can see all the files, but that should be down to the developer to decide whether to continue fetching or aborting.

rybon commented 2 years ago

@gaearon with the use RFC https://github.com/reactjs/rfcs/pull/229 it seems this topic is relevant once more.

How would I for example cancel an Axios promise (cancellation is something Axios already supports today) if a component suspended on a use hook receives new props or is unmounted? Or would it end up in an LRU cache where it gets cleaned up automatically eventually? Is that what the future cache RFC is about?