Remix路由模块输出对象loader函数详解

 更新时间:2023年04月10日 14:40:18   作者:乔治_x  
这篇文章主要为大家介绍了Remix路由模块输出对象loader函数详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>

主要内容

Remix loader 函数是一个获取当前页面页面数据的函数,经常与 useLoaderData 一起配合使用

当前 Remix 版本:1.15.0

  • 定义方式
  • loader 与 useLoaderData 使用
  • 返回值类型以及使用方法
  • 参数/上下文
  • 重定向
  • 错误处理
  • laoder 操作纯 api 输出数据使用

loader 函数定义

  • Remix Route 中定义 loader 函数
  • export 对外暴露
  • 返回 json/defer/ new Response 实例等

经常与 ORM/ODM 进行交互,从数据库获取数据。

loader 函数配合 useLoaderData 一起使用

import { json } from "@remix-run/node"; // or cloudflare/deno
export const loader = async () => {
  return json({ ok: true });
};
export default function Users() {
  const data = useLoaderData();
  return (
    <>{JSON.stringly(data)}</>
  );
}

loader 函数返回值

  • json 一般是同步数据,json 函数可以指定两个参数,第一个是 目标数据,第二个是 http 状态
export const loader = () => {
  json({jsonKey: "jsonValue"})
}
export const loader = () => {
  json({jsonKey: "jsonValue"}, {
    status: 200,
    headers: {
      "Cache-Control": "no-store"
    }
  })
}
  • defer 允许返回一个 promise, 一般配合 Await 组件使用

json 数据一般是返回一个同步 json 对象,但是 defer 允许我们返回值可以是一个 promise

import { defer } from "@remix-run/node"; // or cloudflare/deno
export const loader = async () => {
  const thePromise = loadSlowDataAsync(); // 产生一个 Promise 值
  // So you can write this without awaiting the promise:
  return defer({
    critical: "data",
    slowPromise: thePromise, // 直接将 Promise 的值交给 defer
  });
};

值得注意的是 defer 返回的值不直接使用,需要配合 Suspense + Await 组件使用, 下面是一个 loader 返回 defer 的示例:

import { defer } from "@remix-run/node";
import { Await, useLoaderData } from "@remix-run/react";
import { Suspense } from "react";
export const loader = () => {
  let p = new Promise((resolve) => {
    setTimeout(() => {
      resolve("defer a promise value");
    }, 2000);
  });
  return defer({
    pv: p,
  });
};
export default function Defer() {
  const data = useLoaderData();
  console.log(data);
  return (
    <div>
      <div>This is defer value: </div>
      <Suspense fallback={<div>Loading...</div>}>
        <Await resolve={data.pv}>{(data) => <div>{data}</div>}</Await>
      </Suspense>
    </div>
  );
  • new Response 一个标准的响应示例
export async function loader() {
  const body = JSON.stringify({ loader: "loader data"});
  return new Response(body, {
    headers: {
      "Content-Type": "application/json",
    },
  });
}
export default function() {
  return <div>loader.response</div>
}

Response 是 Fetch API 的响应对象。

loader 函数的类型

loader 函数打通了其类型,在使用的是 typeof 执行 loader 函数配合 LoaderArgs 类型:

import type { LoaderArgs } from "@remix-run/node";
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
export async function loader(args: LoaderArgs) {
  return json({ name: "Ryan", date: new Date() });
}
export default function SomeRoute() {
  const data = useLoaderData<typeof loader>();
}

loader 函数中获取 params

export async function loader({ params }: LoaderArgs) {
  let id = params.id; // "123"
}

一般 id 用于提供给后端查询数据库

loader 函数中处理 headers

export async function loader({ request }: LoaderArgs) {
  // read a cookie
  const cookie = request.headers.get("Cookie");
  // parse the search params for `?q=`
  const url = new URL(request.url);
  const query = url.searchParams.get("q");
}

从 request 对象使用 get 获取 “Cookie” headers 然后使用 request.url 获取 searchParams 这些常用的 url 数据。

loader 函数上下文

如果你有一些上下文,需要串可以修改 server.js 中的内容,这里以 exprss 为例:

const {
  createRequestHandler,
} = require("@remix-run/express");
// 对所有的请求,创建一个对象,提供上下文
app.all(
  "*",
  createRequestHandler({
    getLoadContext(req, res) {
      // this becomes the loader context
      return { expressUser: req.user };
    },
  })
);
// 在 loader 中使用上下文
export async function loader({ context }: LoaderArgs) {
  const { expressUser } = context;
  // ...
}

loader 中重定向到

import { redirect } from "@remix-run/node";
export async function loader() {
  return redirect('/abc')
}
export default function() {
  return <div>loader.response</div>
}

在 loader函数中能使用 redirect 函数进行重定向

错误处理

  • throw 一个指定 http 状态码,如 401:
throw json(
      { invoiceOwnerEmail: invoice.owner.email },
      { status: 401 }
    );
  • 使用 CatchBoundary + useCatch 捕获错误
export function CatchBoundary() {
  // this returns { data, status, statusText }
  const caught = useCatch<ThrownResponses>();
  switch (caught.status) {
    case 401:
      return (
        <div>
          <p>You don't have access to this invoice.</p>
          <p>
            Contact {caught.data.invoiceOwnerEmail} to get
            access
          </p>
        </div>
      );
    case 404:
      return <div>Invoice not found!</div>;
  }
  // You could also `throw new Error("Unknown status in catch boundary")`.
  // This will be caught by the closest `ErrorBoundary`.
  return (
    <div>
      Something went wrong: {caught.status}{" "}
      {caught.statusText}
    </div>
  );
}

在页面中的表现

使用 loader 获取的数据,获取保存在 html 文档的 window.__remixContext 对象里面。

loader 作为纯 api 输出数据使用

Remix 是一个全栈框架,loader 函数用于对外输出数据,这里将 loader 定义为一个纯的 api 接口使用 loader 对外提供数据:

  • 定于路由: api.loader.tsx
export const loader = () => {
  return {
    a: 1
  }
}

启动服务,直接访问 /api/loader 接口得默认使用 get 方法 json 数据。如果要处理不同的请求方式,可以在 loader 函数的参数中获取。

小结

从文中可以看到, Remix Loader 提供强大的数据处理能力,通过 window.__remixContext 提供上下文, loder 中支持获取 json 数据, defer 异步数据,使用 Fetch API 的 Response 标准响应一个数据。能使用自定义上下文,能重定向等等。

以上就是Remix路由模块输出对象loader函数详解的详细内容,更多关于Remix路由模块输出对象loader的资料请关注脚本之家其它相关文章!

相关文章

  • 深入理解React中Suspense与lazy的原理

    深入理解React中Suspense与lazy的原理

    在react中为我们提供了一个非常有用的组件,那就是Suspense,本文主要介绍了如何使用Suspense 和 react提供的lazy结合起来达到异步加载状态的目的,感兴趣的可以了解下
    2024-04-04
  • React中使用antd组件的方法

    React中使用antd组件的方法

    antd 是基于 Ant Design 设计体系的 React UI 组件库,主要用于研发企业级中后台产品,这篇文章主要介绍了React中使用antd组件,需要的朋友可以参考下
    2022-09-09
  • react中使用usestate踩坑及解决

    react中使用usestate踩坑及解决

    这篇文章主要介绍了react中使用usestate踩坑及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • 使用ReactJS实现tab页切换、菜单栏切换、手风琴切换和进度条效果

    使用ReactJS实现tab页切换、菜单栏切换、手风琴切换和进度条效果

    这篇文章主要介绍了使用ReactJS实现tab页切换、菜单栏切换、手风琴切换和进度条效果的相关资料,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2016-10-10
  • react使用echart绘制地图的案例

    react使用echart绘制地图的案例

    这篇文章主要介绍了react使用echart绘制地图,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-01-01
  • 基于react hooks,zarm组件库配置开发h5表单页面的实例代码

    基于react hooks,zarm组件库配置开发h5表单页面的实例代码

    这篇文章主要介绍了基于react hooks,zarm组件库配置开发h5表单页面,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • React-vscode使用jsx语法的问题及解决方法

    React-vscode使用jsx语法的问题及解决方法

    很多朋友在安装插件ES7 React/Redux/GraphQL/React-Native snippets还是不能完全支持jsx语法,纠结是什么原因呢,该如何处理呢,下面小编给大家分享本文帮助大家解决React-vscode使用jsx语法问题,感兴趣的朋友一起看看吧
    2021-06-06
  • 解决React报错The tag is unrecognized in this browser

    解决React报错The tag is unrecognized in this browser

    这篇文章主要为大家介绍了解决React报错The tag is unrecognized in this browser示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • React props全面详细解析

    React props全面详细解析

    props 是 React 组件通信最重要的手段,它在 React 的世界中充当的角色是十分重要的。学好 props 可以使组件间通信更加灵活,同时文中会介绍一些 props 的操作技巧,和学会如何编写嵌套组件
    2022-10-10
  • React-Native左右联动List的示例代码

    React-Native左右联动List的示例代码

    本篇文章主要介绍了React-Native左右联动List的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09

最新评论