Remix 学习 - 路由模块(Route Module)

在 Remix 中,每个路由模块(Route Module)都可以包含多个导出,用于处理不同的功能。以下是每个路由模块主要的导出内容:

1. Component

  • 默认导出:每个路由模块通常会默认导出一个 React 组件。这是用于渲染该路由的页面。

    export default function MyPage() {
      return <h1>Hello, Remix!</h1>;
    }
    

2. Loader

  • 数据加载loader 函数用于在服务器端获取数据。它返回的数据可以在组件中使用。
      import { json } from "@remix-run/node";
      import { useLoaderData } from "@remix-run/react";
      
      export async function loader() {
        return json({ name: "Ryan", date: new Date() });
      }
      
      export default function SomeRoute() {
        const data = useLoaderData<typeof loader>();
      }
    
  • 此函数仅在服务器上运行。在初始服务器渲染时,它将向 HTML 文档提供数据。在浏览器中导航时,Remix 将通过fetch浏览器调用该函数。
  • 这意味着您可以直接与数据库对话,使用仅限服务器的 API 机密等。任何未用于呈现 UI 的代码都将从浏览器包中删除。

3. Action

  • 表单提交action 函数用于处理表单提交和其他 POST 请求。
    export async function action({ request }) {
      const formData = await request.formData();
      await saveData(formData);
      return redirect('/success');
    }
    
  • 路由 action 是服务器唯一功能,用于处理数据变化和其他操作。
  • 如果对路由发出非 GET 请求(DELETEPATCHPOSTPUT ),则在 loader 之前调用 action

4. Meta

  • 元数据meta 函数用于定义页面的元数据,如标题和描述。

      export const meta: MetaFunction = () => {
        return [
          { title: "Very cool app | Remix" },
          {
            property: "og:title",
            content: "Very cool app",
          },
          {
            name: "description",
            content: "This app is the best",
          },
        ];
      };
    

    生成如下 HTML:

      <title>Very cool app | Remix</title>
      <meta property="og:title" content="Very cool app" />;
      <meta name="description" content="This app is the best" />
    

5. Links

  • 样式和链接links 函数用于加载 CSS 或链接其他资源。

      import type { LinksFunction } from "@remix-run/node"; // or cloudflare/deno
      
      export const links: LinksFunction = () => {
        return [
          {
            rel: "icon",
            href: "/favicon.png",
            type: "image/png",
          },
          {
            rel: "stylesheet",
            href: "https://example.com/some/styles.css",
          },
          { page: "/users/123" },
          {
            rel: "preload",
            href: "/images/banner.jpg",
            as: "image",
          },
        ];
      };
    

6. ErrorBoundary

  • 错误处理:用于捕获未处理的 JavaScript 错误,并提供错误信息。

      import { isRouteErrorResponse, useRouteError } from "@remix-run/react";
      
      export function ErrorBoundary() {
      	const error = useRouteError();
      	if (isRouteErrorResponse(error)) {
      	    return (
      	      <div>
      	        <h1>
      	          {error.status} {error.statusText}
      	        </h1>
      	        <p>{error.data}</p>
      	      </div>
      	    );
      	 } else if (error instanceof Error) {
      	    return (
      	      <div>
      	        <h1>Error</h1>
      	        <p>{error.message}</p>
      	        <p>The stack trace is:</p>
      	        <pre>{error.stack}</pre>
      	      </div>
      	    );
      	 } else {
      	    return <h1>Unknown Error</h1>;
      	 }
      }
    

7. CatchBoundary

  • 特定错误处理:用于处理特定 HTTP 错误,如 404。

      export function CatchBoundary() {
         let caught = useCatch();
         return (
           <div>
             <h1>Error {caught.status}</h1>
             <p>{caught.statusText}</p>
           </div>
         );
       }
    

8. Client Loader (clientLoader)

  • 客户端数据加载:用于在客户端进行数据加载,适合在页面交互后需要动态更新的数据。
  • 返回的数据用于客户端更新,不影响初始服务器端渲染。
  • 可以提供更好的用户体验,因为它避免了不必要的页面刷新和服务器负载。
    	export const clientLoader = async ({
    	  request,
    	  params,
    	  serverLoader,
    	}: ClientLoaderFunctionArgs) => {
    	  // call the server loader
    	  const serverData = await serverLoader();
    	  // And/or fetch data on the client
    	  const data = getDataFromClient();
    	  // Return the data to expose through useLoaderData()
    	  return data;
    	};
    
    

9. Client Action (clientAction)

  • 客户端表单处理:在客户端处理表单提交,用于无刷新提交,无需与服务器交互。
    	export const clientAction = async ({
    	  request,
    	  params,
    	  serverAction,
    	}: ClientActionFunctionArgs) => {
    	  invalidateClientSideCache();
    	  const data = await serverAction();
    	  return data;
    	};
    

10. Handle

  • 路由元数据:用于传递自定义数据或配置到路由模块,比如页面标题、描述等,供其他部分(如布局组件、文档组件)使用。

      // 在路由模块中
      export let handle = {
        breadcrumb: 'Home',
        customData: { someKey: 'someValue' }
      };
      
      // 在其他地方使用 handle 数据
      export default function SomeRoute() {
        let data = useLoaderData();
        let handle = useRouteHandle();
      
        return (
          <div>
            <h1>{handle.breadcrumb}</h1>
            <p>{data.someData}</p>
          </div>
        );
      }
    

11. Headers

  • 自定义头部:定义页面的 HTTP 头部信息。

      import type { HeadersFunction } from "@remix-run/node"; // or cloudflare/deno
      
      export const headers: HeadersFunction = ({
        actionHeaders,
        errorHeaders,
        loaderHeaders,
        parentHeaders,
      }) => ({
        "X-Stretchy-Pants": "its for fun",
        "Cache-Control": "max-age=300, s-maxage=3600",
      });
    
    

12. HydrateFallback

  • 加载占位符:用于在客户端渲染之前显示的占位内容。
     export async function clientLoader() {
       const data = await loadSavedGameOrPrepareNewGame();
       return data;
     }
     // Note clientLoader.hydrate is implied without a server loader
     
     export function HydrateFallback() {
       return <p>Loading Game...</p>;
     }
    
     export default function Component() {
       const data = useLoaderData<typeof clientLoader>();
       return <Game data={data} />;
     }
    

13. Should Revalidate (shouldRevalidate)

  • 重新验证:控制数据是否需要重新验证或刷新。

  • 此功能可让应用程序优化在 actions 以及客户端导航后,判断应重新加载哪些路由数据。

      import type { ShouldRevalidateFunction } from "@remix-run/react";
      
      export const shouldRevalidate: ShouldRevalidateFunction = ({
        actionResult,
        currentParams,
        currentUrl,
        defaultShouldRevalidate,
        formAction,
        formData,
        formEncType,
        formMethod,
        nextParams,
        nextUrl,
      }) => {
        return true;
      };
    

每个路由模块可以根据需要导出这些功能,以支持页面的不同需求。通过这些导出,Remix 提供了灵活的方式来处理数据、错误和页面渲染。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值