Remix路由模塊輸出對象loader函數(shù)詳解
主要內(nèi)容
Remix loader 函數(shù)是一個獲取當前頁面頁面數(shù)據(jù)的函數(shù),經(jīng)常與 useLoaderData 一起配合使用
當前 Remix 版本:1.15.0
- 定義方式
- loader 與 useLoaderData 使用
- 返回值類型以及使用方法
- 參數(shù)/上下文
- 重定向
- 錯誤處理
- laoder 操作純 api 輸出數(shù)據(jù)使用
loader 函數(shù)定義
- Remix Route 中定義 loader 函數(shù)
- export 對外暴露
- 返回 json/defer/ new Response 實例等
經(jīng)常與 ORM/ODM 進行交互,從數(shù)據(jù)庫獲取數(shù)據(jù)。
loader 函數(shù)配合 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 函數(shù)返回值
- json 一般是同步數(shù)據(jù),json 函數(shù)可以指定兩個參數(shù),第一個是 目標數(shù)據(jù),第二個是 http 狀態(tài)
export const loader = () => {
json({jsonKey: "jsonValue"})
}
export const loader = () => {
json({jsonKey: "jsonValue"}, {
status: 200,
headers: {
"Cache-Control": "no-store"
}
})
}
- defer 允許返回一個 promise, 一般配合
Await 組件使用
json 數(shù)據(jù)一般是返回一個同步 json 對象,但是 defer 允許我們返回值可以是一個 promise
import { defer } from "@remix-run/node"; // or cloudflare/deno
export const loader = async () => {
const thePromise = loadSlowDataAsync(); // 產(chǎn)生一個 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 函數(shù)的類型
loader 函數(shù)打通了其類型,在使用的是 typeof 執(zhí)行 loader 函數(shù)配合 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 函數(shù)中獲取 params
export async function loader({ params }: LoaderArgs) {
let id = params.id; // "123"
}
一般 id 用于提供給后端查詢數(shù)據(jù)庫
loader 函數(shù)中處理 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 數(shù)據(jù)。
loader 函數(shù)上下文
如果你有一些上下文,需要串可以修改 server.js 中的內(nèi)容,這里以 exprss 為例:
const {
createRequestHandler,
} = require("@remix-run/express");
// 對所有的請求,創(chuàng)建一個對象,提供上下文
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函數(shù)中能使用 redirect 函數(shù)進行重定向
錯誤處理
- throw 一個指定 http 狀態(tài)碼,如 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>
);
}
在頁面中的表現(xiàn)

使用 loader 獲取的數(shù)據(jù),獲取保存在 html 文檔的 window.__remixContext 對象里面。
loader 作為純 api 輸出數(shù)據(jù)使用
Remix 是一個全棧框架,loader 函數(shù)用于對外輸出數(shù)據(jù),這里將 loader 定義為一個純的 api 接口使用 loader 對外提供數(shù)據(jù):
- 定于路由:
api.loader.tsx
export const loader = () => {
return {
a: 1
}
}
啟動服務,直接訪問 /api/loader 接口得默認使用 get 方法 json 數(shù)據(jù)。如果要處理不同的請求方式,可以在 loader 函數(shù)的參數(shù)中獲取。
小結(jié)
從文中可以看到, Remix Loader 提供強大的數(shù)據(jù)處理能力,通過 window.__remixContext 提供上下文, loder 中支持獲取 json 數(shù)據(jù), defer 異步數(shù)據(jù),使用 Fetch API 的 Response 標準響應一個數(shù)據(jù)。能使用自定義上下文,能重定向等等。
以上就是Remix路由模塊輸出對象loader函數(shù)詳解的詳細內(nèi)容,更多關(guān)于Remix路由模塊輸出對象loader的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React router cache route實現(xiàn)緩存頁面流程介紹
react-router自身沒有路由緩存的特性,在5.x版本之前,我們可以基于react-router-cache-route來實現(xiàn)路由緩存功能。但是react-router 6.x在實現(xiàn)上做了比較大的變化,react-router-cache-route沒有提供相應的支持2023-01-01
React?useEffect異步操作常見問題小結(jié)
本文主要介紹了React?useEffect異步操作常見問題小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-06-06
React前端渲染優(yōu)化--父組件導致子組件重復渲染的問題
本篇文章是針對父組件導致子組件重復渲染的優(yōu)化方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08
React 如何使用時間戳計算得到開始和結(jié)束時間戳
這篇文章主要介紹了React 如何拿時間戳計算得到開始和結(jié)束時間戳,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09

