-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🗺️ Single Fetch #7641
Comments
I was talking to @jacob-ebey about this and he suggested we need some hooks for encoding/decoding loader data. I've asked him to write more about that here. |
Single fetch is going to require exposing a few internal router concepts as public API such Instead of calling this "Single fetch", let's call it the "data loader hook". The implementors responsibility will essentially be to return a DataResult per entry for routesToLoad. This is applicable for loaders and actions for both navigations and fetchers. Think of it as "call local loader / action function, or do something else completely to get the route data". The data loader hook will also NOT necessarily be responsible for decoding individual loader / action Response content. The data loader hook will return DataResults (SuccessResult, DeferredResult, RedirectResult, or ErrorResult) that are then fed through our existing "decode / parse loader / action responses" depending on the type of result. The existing "decode / parse" pipeline is locked down to just JSON / text responses and I believe unlocking this will be a bigger win than single fetch with less risk of exposing router implementation details. The hooks into the decode pipeline would unlock less restrictive transport formats in existing remix, as well as enable RSC. The data loader hook would allow us to implement remix's current fetch logic in a shared location outside of (RR) means handled by the router, (U) means overridable by the user of react-router: How I think about today's flow:
With decode hook:
With data loader hook:
With data loader hook and decode hook:
|
@jacob-ebey that sounds great to me. @brophdawg11 and I had discussed a long time ago that @remix-run/router will eventually need a pluggable "load the data" implementation, one use case we were thinking of was for SPAs that want to combine a bunch of graphql fragments into a single query and request. The I'd get Matt's take on it, I know he's thought a lot about it already. |
Step 1: remix-run/react-router#11086 |
We can talk about this on the call today but curious if we need 3/4 to be separate router APIs above? In the initial POC for I could probably be convinced pretty easily that createBrowserRouter(routes, {
fetchStrategy({ request, matches, defaultStrategy }) {
// 1. Default loader execution / Default response decoding
let results = await defaultStrategy();
// 2. Default loader execution / Custom response decoding
let results = await defaultStrategy((response) => customDecode(response));
// 3. Custom loader execution / Default response decoding
let results = Promise.all(matches.map(async (match) => {
let response = await callLoaderCustom(match);
// This is where it gets a bit tricky - no super clean way to expose a `defaultDecode()`
// function but I would argue we do not need to since it's just standard web fetch stuff
// and a one liner if you know your app only deals in JSON/whatever
let data = await response.json();
return { type: ResultType.Success, data };
}));
// 4. Custom loader execution / Custom response decoding
let results = Promise.all(matches.map(async (match) => {
let response = await callLoaderCustom(match);
let data = await customDecode(response);
return { type: ResultType.Success, data };
}));
}
}); The comment in code snippet (3) above is what I was getting at in this comment as well. |
@jacob-ebey @ryanflorence Should we should consider #4319 as a potential add-on or fast-follow to this work? |
The text was updated successfully, but these errors were encountered: