remix-demo

react router (remix) demo

git clone https://9o.is/git/remix-demo.git

hooks.ts

(1206B)


      1 import { useMatches } from "@remix-run/react";
      2 import { useMemo } from "react";
      3 import type { User } from "~/models/user.server";
      4 
      5 /**
      6  * This base hook is used in other hooks to quickly search for specific data
      7  * across all loader data using useMatches.
      8  * @param {string} id The route id
      9  * @returns {JSON|undefined} The router data or undefined if not found
     10  */
     11 export function useMatchesData(
     12   id: string
     13 ): Record<string, unknown> | undefined {
     14   const matchingRoutes = useMatches();
     15   const route = useMemo(
     16     () => matchingRoutes.find((route) => route.id === id),
     17     [matchingRoutes, id]
     18   );
     19   return route?.data;
     20 }
     21 
     22 export function useOptionalUser(): User | undefined {
     23   function isUser(user: any): user is User {
     24     return user && typeof user === "object" && typeof user.email === "string";
     25   }
     26 
     27   const data = useMatchesData("root");
     28   if (!data || !isUser(data.user)) {
     29     return undefined;
     30   }
     31   return data.user;
     32 }
     33 
     34 export function useUser(): User {
     35   const maybeUser = useOptionalUser();
     36   if (!maybeUser) {
     37     throw new Error(
     38       "No user found in root loader, but user is required by useUser. If user is optional, try useOptionalUser instead."
     39     );
     40   }
     41   return maybeUser;
     42 }