-
-
Notifications
You must be signed in to change notification settings - Fork 10.7k
Description
What is the new or updated feature that you are suggesting?
Proposal: Update the element
prop of the Route
component so it also accepts a function. If provided, the function is given the loader data.
function SomeComponent() {
return (
<Route
path="/user/:id"
loader={({ params }) => loadUser(params.id)}
element={({ data }) => (
// ...
)}
/>
);
}
Why should this feature be included?
This proposal aims at achieving similar results than #9189, but with a more "type safe" approach.
Currently, to access loader data you need to use the useLoaderData
hook. The usage of a hook makes Typescript lose track of the type of the data. If Route
provides the data to its element
prop, then react-router can make use of generics to ensure that type information is not lost.
Before
type RouteProps = {
// ...
loader?: (args: LoaderFunctionArgs): Promise<Response> | Response | Promise<any> | any;
element?: React.ReactNode | null;
}
After
type RouteProps<T> = {
// ...
loader?: (args: LoaderFunctionArgs): Promise<Response> | Response | Promise<T> | T;
element?: React.ReactNode | null | ((args: { data: T }) => React.ReactNode | null);
}
If
loader
returns aPromise<Response>
orResponse
, and ifelement
is a function, then we'll have to trust that the deserialized data will be of typeT
.
I do not have the full picture about the ins and outs of useLoaderData
, so I'm aware that my proposal may not be in line with react-router's architecture.
EDIT 2023-01-04
I just stumbled upon the FAQ that explains why Route
no longer accepts render props. I understand the motivation behind this choice and I don't expect the Remix team to make this issue a priority.
However I'm sure the team is aware that using react-router's hooks is not the panacea. Not just for the type-safety issue mentioned above. As Fiona described below, they tend to add more coupling between your components and react-router. I can only hope you'd reconsider the tradeoffs of render-props :)