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 }