DEV Community

Yuichi Nabeshima
Yuichi Nabeshima

Posted on • Updated on

How Define the Type of Loader in Remix

According to the tutorial of Remix.

Basic usage of loader is like below(It is my original code from this).

1 import { type LoaderFunction, json } from "@remix-run/node";
2 import { useLoaderData } from "@remix-run/react";
3 import { PrismaClient } from "@prisma/client";
4
5 export const loader: LoaderFunction = async () => {
6  const prisma = new PrismaClient();
7  const postData = await prisma.post.findFirst();
8
9    return json({ postData });
10 };
11
12 export default function Index() {
13  const { postData } = useLoaderData<typeof loader>();
14
15  return (
16    <>
17      <h1>My app for sample</h1>
18      <h2>{postData?.name ? postData.name : 'loading...'}</h2>
19      <h2>{postData?.body ? postData.body : 'loading...'}</h2>
20    </>
21  );
22 }
Enter fullscreen mode Exit fullscreen mode

Then, the variable postData of line 7 has the Type like below(VS code let us show the type while I hover on the variable.).

Image description

But the postData of line 13 which is defined at client has type of any.

Image description

We want to know that type.

The simple answer is below.

July 29th Add

I research again this thing and found much simple way.
We use function declaration instead of allow function.

import { type LoaderFunction, json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { PrismaClient } from "@prisma/client";

- export const loader: LoaderFunction = async () => {
+ export async function loader() {

 const prisma = new PrismaClient();
 const postData = await prisma.post.findFirst();

   return json({ postData });
};

export default function Index() {
 const { postData } = useLoaderData<typeof loader>();

 return (
   <>
    <h1>My app for sample</h1>
    <h2>{postData?.name ? postData.name : 'loading...'}</h2>
    <h2>{postData?.body ? postData.body : 'loading...'}</h2>
   </>
 );
}
Enter fullscreen mode Exit fullscreen mode

We can see the type of the data!

Image description

Below is old.

import { type LoaderFunction, json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { PrismaClient } from "@prisma/client";

+ type LoaderReturn = {
+   postData: {
+     name: string;
+     body?: string;
+   },
+ }

export const loader: LoaderFunction = async () => {
  const prisma = new PrismaClient();
  const postData = await prisma.post.findFirst();

  return json({ postData });
};

export default function Index() {
-   const { postData } = useLoaderData<typeof loader>();
+   const { postData } = useLoaderData<typeof loader>() as LoaderReturn;

  return (
    <>
      <h1>My app for sample</h1>
      <h2>{postData?.name ? postData.name : 'loading...'}</h2>
      <h2>{postData?.body ? postData.body : 'loading...'}</h2>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

You can define the type manually!

Image description

Or, you can replace the loader in the generics of useLoaderData to the type you made.

import { type LoaderFunction, json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { PrismaClient } from "@prisma/client";

+ type LoaderReturn = {
+   postData: {
+     name: string;
+     body?: string;
+   },
+ };

export const loader: LoaderFunction = async () => {
  const prisma = new PrismaClient();
  const postData = await prisma.post.findFirst();

  return json({ postData });
};

export default function Index() {
-   const { postData } = useLoaderData<typeof loader>();
+   const { postData } = useLoaderData<LoaderReturn>();

  return (
    <>
      <h1>My app for sample</h1>
      <h2>{postData?.name ? postData.name : 'loading...'}</h2>
      <h2>{postData?.body ? postData.body : 'loading...'}</h2>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

This is cleaner than before!

The return of the action is same.

I am looking for a job

As of July 2024, I am looking for a job.
My areas of expertise are React, TypeScript, Remix, Next, PHP, and WordPress.
I'm currently a student, so I'm looking for a part-time position where I can work up to 20 hours a week.
I'm looking for a full-time job starting next August.

Top comments (0)