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

相关推荐
初遇你时动了情12 分钟前
html js 原生实现web组件、web公共组件、template模版插槽
前端·javascript·html
QQ27402875632 分钟前
Soundness Gitpod 部署教程
linux·运维·服务器·前端·chrome·web3
前端小崔41 分钟前
从零开始学习three.js(18):一文详解three.js中的着色器Shader
前端·javascript·学习·3d·webgl·数据可视化·着色器
哎呦你好1 小时前
HTML 表格与div深度解析区别及常见误区
前端·html
运维@小兵1 小时前
vue配置子路由,实现点击左侧菜单,内容区域显示不同的内容
前端·javascript·vue.js
龙湾开发2 小时前
计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 10.增强表面细节(二)法线贴图
c++·笔记·学习·图形渲染·贴图
koiy.cc2 小时前
记录:echarts实现tooltip的某个数据常显和恢复
前端·echarts
一只专注api接口开发的技术猿2 小时前
企业级电商数据对接:1688 商品详情 API 接口开发与优化实践
大数据·前端·爬虫
GISer_Jing2 小时前
[前端高频]数组转树、数组扁平化、深拷贝、JSON.stringify&JSON.parse等手撕
前端·javascript·json
liang_20262 小时前
【HT周赛】T3.二维平面 题解(分块:矩形chkmax,求矩形和)
数据结构·笔记·学习·算法·平面·总结