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

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

1. Component

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

    jsx 复制代码
    export default function MyPage() {
      return <h1>Hello, Remix!</h1>;
    }

2. Loader

  • 数据加载loader 函数用于在服务器端获取数据。它返回的数据可以在组件中使用。

    javascript 复制代码
      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 请求。

    javascript 复制代码
    export async function action({ request }) {
      const formData = await request.formData();
      await saveData(formData);
      return redirect('/success');
    }
  • 路由 action 是服务器唯一功能,用于处理数据变化和其他操作。

  • 如果对路由发出非 GET 请求(DELETEPATCHPOSTPUT ),则在 loader 之前调用 action

4. Meta

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

    javascript 复制代码
      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:

    html 复制代码
      <title>Very cool app | Remix</title>
      <meta property="og:title" content="Very cool app" />;
      <meta name="description" content="This app is the best" />
  • 样式和链接links 函数用于加载 CSS 或链接其他资源。

    typescript 复制代码
      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 错误,并提供错误信息。

    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。

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

8. Client Loader (clientLoader)

  • 客户端数据加载:用于在客户端进行数据加载,适合在页面交互后需要动态更新的数据。

  • 返回的数据用于客户端更新,不影响初始服务器端渲染。

  • 可以提供更好的用户体验,因为它避免了不必要的页面刷新和服务器负载。

    javascript 复制代码
    	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)

  • 客户端表单处理 :在客户端处理表单提交,用于无刷新提交,无需与服务器交互。

    javascript 复制代码
    	export const clientAction = async ({
    	  request,
    	  params,
    	  serverAction,
    	}: ClientActionFunctionArgs) => {
    	  invalidateClientSideCache();
    	  const data = await serverAction();
    	  return data;
    	};

10. Handle

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

    javascript 复制代码
      // 在路由模块中
      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 头部信息。

    javascript 复制代码
      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

  • 加载占位符 :用于在客户端渲染之前显示的占位内容。

    javascript 复制代码
     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 以及客户端导航后,判断应重新加载哪些路由数据。

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

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

相关推荐
架构文摘JGWZ4 小时前
FastJson很快,有什么用?
后端·学习
量子-Alex6 小时前
【多视图学习】显式视图-标签问题:多视图聚类的多方面互补性研究
学习
乔木剑衣6 小时前
Java集合学习:HashMap的原理
java·学习·哈希算法·集合
古蓬莱掌管玉米的神6 小时前
vue3语法watch与watchEffect
前端·javascript
林涧泣6 小时前
【Uniapp-Vue3】uni-icons的安装和使用
前端·vue.js·uni-app
练小杰7 小时前
Linux系统 C/C++编程基础——基于Qt的图形用户界面编程
linux·c语言·c++·经验分享·qt·学习·编辑器
雾恋7 小时前
AI导航工具我开源了利用node爬取了几百条数据
前端·开源·github
拉一次撑死狗7 小时前
Vue基础(2)
前端·javascript·vue.js
皮肤科大白7 小时前
如何在data.table中处理缺失值
学习·算法·机器学习
祯民7 小时前
两年工作之余,我在清华大学出版社出版了一本 AI 应用书籍
前端·aigc