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 提供了灵活的方式来处理数据、错误和页面渲染。

相关推荐
阿伟来咯~37 分钟前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端42 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱1 小时前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai1 小时前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨1 小时前
在JS中, 0 == [0] 吗
开发语言·javascript
Suckerbin1 小时前
Hms?: 1渗透测试
学习·安全·网络安全
水豚AI课代表1 小时前
分析报告、调研报告、工作方案等的提示词
大数据·人工智能·学习·chatgpt·aigc
聪明的墨菲特i1 小时前
Python爬虫学习
爬虫·python·学习
Diamond技术流1 小时前
从0开始学习Linux——网络配置
linux·运维·网络·学习·安全·centos
斑布斑布1 小时前
【linux学习2】linux基本命令行操作总结
linux·运维·服务器·学习