I'm using loaders with the new react-router-dom
and when I use the useLoaderData
hook in the component, the response type is unknown, so I can't use it. I don't want to use the as
type definition as I feel like that's kind of cheating but if that's the only way, then, please let me know:
My loader function:
{
path: "/reset-password/:resetToken",
element: <ResetPassword />,
loader: async ({ params }) => {
if (!params.resetToken){
return null
}
const fakeTokens = ["abcdef123456", "bingbong", "foobar"]
// make API call to check if the given token is valid
const fakeAPICall = (resetToken: string) : Promise<object> => {
if (fakeTokens.includes(resetToken)){
return new Promise(resolve => resolve({ success: true }))
}
return new Promise(resolve => resolve({ success: false }))
}
const resp = await fakeAPICall(params.resetToken);
return resp;
}
},
Inside the <ResetPassword />
:
// this type is "unknown", so I can't access the properties on it
const resetTokenResponse = useLoaderData()
The useLoaderData
hook's return type is unknown
, so you'll need to re-type it in the component.
See source
/** * Returns the loader data for the nearest ancestor Route loader */ export function useLoaderData(): unknown { let state = useDataRouterState(DataRouterStateHook.UseLoaderData); let route = React.useContext(RouteContext); invariant(route, `useLoaderData must be used inside a RouteContext`); let thisRoute = route.matches[route.matches.length - 1]; invariant( thisRoute.route.id, `useLoaderData can only be used on routes that contain a unique "id"` ); return state.loaderData[thisRoute.route.id]; }
AFAIK using the as
typing is how you'd do it, i.e.
interface ResetTokenResponse {
success: boolean;
}
...
const resetTokenResponse = useLoaderData() as ResetTokenResponse;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With