-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Calling Loaders/Actions outside of navigation (or other apps) #169
Comments
About the alternative API, you could still use useFetch with React Query or SWR, so the first option could work, something like: let fetch = useFetchRoute
useQuery("autocomplete", () => fetch(“some url”)) |
Also, shouldn’t there be a way in the parameters of the action a way to identify if your action is being used in a navigation or not so you can return a redirect or json? |
@sergiodxa that's a good point. I think I assumed you'd have actions that are always used as navigations, and actions that aren't, didn't really expect to have an action that is used either way. We'll need to think about that. Anyway, knee-jerk reaction is we send a header: |
A header will work pretty well, and I assume it will be easier to add and if it’s a standard header of Remix you can build a helper function that receives the request and return a Boolean let isNavigation = checkNavigationHeader(request) (Probably isNavigation should be the function name, since it’s a sync thing you could just call it anytime you need it) |
In my current project we use next.js API routes to proxy all our backend calls. Our API is accessed at https://our-website.com/api/... which is split using CloudFront behaviours. In order to be able develop locally we have a catch all route in the Would this be possible with this proposed solution? |
@amuttsch I think you don’t need that with Remix, you will call your API inside the loaders and actions so you don’t need to expose your API |
This is kinda big but opens up a lot of use cases, ## useTransition: - can build better pending navigation UI with useTransition telling app more detailed information (state, type) - replaces usePendingFormSubmit and usePendingLocation - actually aborts stale submissions/loads - fixes bugs around interrupted submissions/navigations ## useActionData - actions can return data now - super useful for form validation, no more screwing around with sessions ## useFetcher - allows apps to call loaders and actions outside of navigation - manages cancellation of stale submissions and loads - reloads route data after actions - commits the freshest reloaded data along the way when there are multiple inflight ## experimental_shouldReload allows route modules to decide if they should reload or not - after submissions - when the search params change - when the same href is navigated to ## other stuff - reloads route data when the same href is navigated to - does not create ghost history entries on interrupted navigation ## Deprecations These old hooks still work, but have been deprecated for the new hooks. - useRouteData -> useLoaderData - usePendingFormSubmit -> useTransition().submission - usePendingLocation -> useTransition().location Closes #169, #151, #175, #128, #54, #208
This is kinda big but opens up a lot of use cases, - can build better pending navigation UI with useTransition telling app more detailed information (state, type) - replaces usePendingFormSubmit and usePendingLocation - actually aborts stale submissions/loads - fixes bugs around interrupted submissions/navigations - actions can return data now - super useful for form validation, no more screwing around with sessions - allows apps to call loaders and actions outside of navigation - manages cancellation of stale submissions and loads - reloads route data after actions - commits the freshest reloaded data along the way when there are multiple inflight allows route modules to decide if they should reload or not - after submissions - when the search params change - when the same href is navigated to - reloads route data when the same href is navigated to - does not create ghost history entries on interrupted navigation These old hooks still work, but have been deprecated for the new hooks. - useRouteData -> useLoaderData - usePendingFormSubmit -> useTransition().submission - usePendingLocation -> useTransition().location Closes #169, #151, #175, #128, #54, #208
This is kinda big but opens up a lot of use cases, - can build better pending navigation UI with useTransition telling app more detailed information (state, type) - replaces usePendingFormSubmit and usePendingLocation - actually aborts stale submissions/loads - fixes bugs around interrupted submissions/navigations - actions can return data now - super useful for form validation, no more screwing around with sessions - allows apps to call loaders and actions outside of navigation - manages cancellation of stale submissions and loads - reloads route data after actions - commits the freshest reloaded data along the way when there are multiple inflight allows route modules to decide if they should reload or not - after submissions - when the search params change - when the same href is navigated to - reloads route data when the same href is navigated to - does not create ghost history entries on interrupted navigation These old hooks still work, but have been deprecated for the new hooks. - useRouteData -> useLoaderData - usePendingFormSubmit -> useTransition().submission - usePendingLocation -> useTransition().location Closes #169, #151, #175, #128, #54, #208
This is kinda big but opens up a lot of use cases, - can build better pending navigation UI with useTransition telling app more detailed information (state, type) - replaces usePendingFormSubmit and usePendingLocation - actually aborts stale submissions/loads - fixes bugs around interrupted submissions/navigations - actions can return data now - super useful for form validation, no more screwing around with sessions - allows apps to call loaders and actions outside of navigation - manages cancellation of stale submissions and loads - reloads route data after actions - commits the freshest reloaded data along the way when there are multiple inflight allows route modules to decide if they should reload or not - after submissions - when the search params change - when the same href is navigated to - reloads route data when the same href is navigated to - does not create ghost history entries on interrupted navigation These old hooks still work, but have been deprecated for the new hooks. - useRouteData -> useLoaderData - usePendingFormSubmit -> useTransition().submission - usePendingLocation -> useTransition().location Closes #169, #151, #175, #128, #54, #208
This is kinda big but opens up a lot of use cases, - can build better pending navigation UI with useTransition telling app more detailed information (state, type) - replaces usePendingFormSubmit and usePendingLocation - actually aborts stale submissions/loads - fixes bugs around interrupted submissions/navigations - actions can return data now - super useful for form validation, no more screwing around with sessions - allows apps to call loaders and actions outside of navigation - manages cancellation of stale submissions and loads - reloads route data after actions - commits the freshest reloaded data along the way when there are multiple inflight allows route modules to decide if they should reload or not - after submissions - when the search params change - when the same href is navigated to other stuff - reloads route data when the same href is navigated to - does not create ghost history entries on interrupted navigation These old hooks still work, but have been deprecated for the new hooks. - useRouteData -> useLoaderData - usePendingFormSubmit -> useTransition().submission - usePendingLocation -> useTransition().location Also includes a helping of docs updates Closes #169, #151, #175, #128, #54, #208
This is kinda big but opens up a lot of use cases, - can build better pending navigation UI with useTransition telling app more detailed information (state, type) - replaces usePendingFormSubmit and usePendingLocation - actually aborts stale submissions/loads - fixes bugs around interrupted submissions/navigations - actions can return data now - super useful for form validation, no more screwing around with sessions - allows apps to call loaders and actions outside of navigation - manages cancellation of stale submissions and loads - reloads route data after actions - commits the freshest reloaded data along the way when there are multiple inflight allows route modules to decide if they should reload or not - after submissions - when the search params change - when the same href is navigated to other stuff - reloads route data when the same href is navigated to - does not create ghost history entries on interrupted navigation These old hooks still work, but have been deprecated for the new hooks. - useRouteData -> useLoaderData - usePendingFormSubmit -> useTransition().submission - usePendingLocation -> useTransition().location Also includes a helping of docs updates Closes #169, #151, #175, #128, #54, #208
This is kinda big but opens up a lot of use cases, - can build better pending navigation UI with useTransition telling app more detailed information (state, type) - replaces usePendingFormSubmit and usePendingLocation - actually aborts stale submissions/loads - fixes bugs around interrupted submissions/navigations - actions can return data now - super useful for form validation, no more screwing around with sessions - allows apps to call loaders and actions outside of navigation - manages cancellation of stale submissions and loads - reloads route data after actions - commits the freshest reloaded data along the way when there are multiple inflight allows route modules to decide if they should reload or not - after submissions - when the search params change - when the same href is navigated to other stuff - reloads route data when the same href is navigated to - does not create ghost history entries on interrupted navigation These old hooks still work, but have been deprecated for the new hooks. - useRouteData -> useLoaderData - usePendingFormSubmit -> useTransition().submission - usePendingLocation -> useTransition().location Also includes a helping of docs updates Closes #169, #151, #175, #128, #54, #208
This is kinda big but opens up a lot of use cases, - can build better pending navigation UI with useTransition telling app more detailed information (state, type) - replaces usePendingFormSubmit and usePendingLocation - actually aborts stale submissions/loads - fixes bugs around interrupted submissions/navigations - actions can return data now - super useful for form validation, no more screwing around with sessions - allows apps to call loaders and actions outside of navigation - manages cancellation of stale submissions and loads - reloads route data after actions - commits the freshest reloaded data along the way when there are multiple inflight allows route modules to decide if they should reload or not - after submissions - when the search params change - when the same href is navigated to other stuff - reloads route data when the same href is navigated to - does not create ghost history entries on interrupted navigation These old hooks still work, but have been deprecated for the new hooks. - useRouteData -> useLoaderData - usePendingFormSubmit -> useTransition().submission - usePendingLocation -> useTransition().location Also includes a helping of docs updates Closes #169, #151, #175, #128, #54, #208
This is kinda big but opens up a lot of use cases, - can build better pending navigation UI with useTransition telling app more detailed information (state, type) - replaces usePendingFormSubmit and usePendingLocation - actually aborts stale submissions/loads - fixes bugs around interrupted submissions/navigations - actions can return data now - super useful for form validation, no more screwing around with sessions - allows apps to call loaders and actions outside of navigation - manages cancellation of stale submissions and loads - reloads route data after actions - commits the freshest reloaded data along the way when there are multiple inflight allows route modules to decide if they should reload or not - after submissions - when the search params change - when the same href is navigated to other stuff - reloads route data when the same href is navigated to - does not create ghost history entries on interrupted navigation These old hooks still work, but have been deprecated for the new hooks. - useRouteData -> useLoaderData - usePendingFormSubmit -> useTransition().submission - usePendingLocation -> useTransition().location Also includes a helping of docs updates Closes #169, #151, #175, #128, #54, #208
coming in 0.19 as |
Calling Loaders/Actions Outside of Navigation
Some might call them "API routes".
Use cases:
Why not just use an express/vercel/architect endpoint?
Indeed, this was our original thinking back when we had the
data
folder. We realized quickly that sharing code between compiled-by-remix and not-compiled-by-remix was overly complex, so we moved everything into the Remix app itself.This is the same problem with "just using a server route instead of remix". Code re-use between the server-only routes (express/vercel/firebase, etc.) and the remix-compiled code is overly complex.
Additionally, you'll have to think in two paradigms: the web
Request
andResponse
model in Remix and thereq/res
of whatever platform you're using. Any abstractions you build on top of the web fetch API for your remix server-side code will be unusable outside of Remix.API Proposal
useFetchRoute()
You can call Remix route's with
fetch
directly if you know how to construct the URL and know the route id convention that Remix uses internally. You would also need to know the conventions Remix actions use to redirect (204 + header) since actions require a redirect.However, even by doing all of that, you still can't point a webhook at a remix endpoint because most webhooks require a 2xx response.
All we really need is to support these use cases are two things:
useFetch
This hook will call a route's data functions outside of navigation.
Combobox use case
Mixed third-party browser + remix server side flow
For user flows that involved browser-only third-party tools and remix mutations, you can call actions directly:
If you model this as a navigation, it's way more involved and a little indirect
Webhook Example
Deleting a bunch of records in a list
If you've got a list of items and click delete on multiple quickly, the pending or optimistic UI in remix is impossible to build since only one form can be pending at a time. The last clicked item is the one that will show is deleting, while others you may have already clicked will stop rendering their pending UI.
We have discussed allowing multiple pending forms at once, but it's still unclear how that API should look (
usePendingFormSubmits()
with an "s" would probably be okay). So we may be able to figure something out here to model as navigation (which would be good so that it works if JS fails, or you want to be able to turn it off and on ...)So, until we tackle that, this UI isn't straightforward to build Remix right now. But with
useFetchRoute
it's pretty straightforward React.Of course, this is fraught with data synchrony issues, which is why this really is a navigation, because remix will automatically recall loaders up the tree to make sure the mutation is reflected.
But until we figure out "multiple pending forms" this would allow people to continue building UI the way they're used to in React but now with Remix handling the backend "api route".
In Summary
Implementation notes
Special case calls from navigation to actions with a header so that we continue to enforce a redirect. If the header isn't present, then we don't care what they return, it's not a navigation.
Alternative API
Instead of a full
fetch
-like object, just return the data url, and then use that anywhere you want (includingfetch
).This is probably better because then people can use React Data,
useSWR
, and any other client-side data library out there.The text was updated successfully, but these errors were encountered: