Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I define the return type for a React Router v6 loader?

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() 
like image 519
Ammar Ahmed Avatar asked Oct 12 '25 09:10

Ammar Ahmed


1 Answers

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;

Edit how-can-i-define-the-return-type-for-a-react-router-v6-loader

like image 148
Drew Reese Avatar answered Oct 16 '25 06:10

Drew Reese