Skip to content

Loader 和 action

警告

  1. loader 设计的理念是用户没进入路由之前,先获取到异步请求的数据,然后渲染到页面上

  2. action 设计的理念是拦截用户通过 Form 组件包裹的数据转发到 action 上面

  3. 表单提交动作处理,不能是 get,只能是 post,del,put,它会通过 Form 拦截,找到下面的 action 属性来匹配,get 请求会触发 loader

loader

不获取参数

警告

  1. 页面里面暴露出 loader,必须用{}包裹

  2. 组件里面通过使用 useLoaderData 来获取数据

  • page2.jsx
jsx
import { useLoaderData } from "react-router-dom";
export const loader = async () => {
  // const contact = await xxxx() 你自己获取数据的方法
  const contact = { name: "李四" };
  console.log(contact);
  return { contact }; // 返回联系人详细信息
};

function Page2() {
  const { contact } = useLoaderData();
  return (
    <div>
      路由2的页面
      <div>{contact.name}</div>
    </div>
  );
}

export default Page2;
  • 绑定到 router 上面,配置 loader 属性
jsx
import React from "react";

import { createBrowserRouter } from "react-router-dom";

import ErrorPage from "../error";

import LayOut from "../layOut/Layout";

import Page1 from "../views/Page1";

import Page2, { loader as page2Loader } from "../views/Page2";

// 默认页面

import IndexPage from "../views/index";

const router = createBrowserRouter([
  // 2. 路由配置
  {
    path: "/",
    element: <LayOut></LayOut>,
    errorElement: <ErrorPage></ErrorPage>,
    children: [
      {
        index: true,
        element: <IndexPage></IndexPage>,
      },
      {
        path: "/page1",
        element: <Page1></Page1>,
      },
      {
        path: "/page2",
        element: <Page2></Page2>,
        loader: page2Loader,
      },
    ],
  },
]);

export default router;

获取参数

    1. 创建新的路由
js
// 引入loader
import Page2, { loader as page2Loader } from "../views/Page2";
// 创建新的路由
{
  path: "/page2/:id",
  element: <Page2></Page2>,
  loader: page2Loader,
},
    1. 修改 loader

page2.jsx 修改 loader,通过 params 获取参数

js
export const loader = async ({ params }) => {
  // const contact = await xxxx() 你自己获取数据的方法
  if (params.id) {
    console.log(params.id);
    const contact = { name: `李四---${params.id}` };
    console.log(contact);
    return { contact };
  } else {
    const contact = { name: "李四" };
    console.log(contact);
    return { contact };
  }
};
    1. 组件渲染
jsx
function Page2() {
  const { contact } = useLoaderData();
  return (
    <div>
      路由2的页面
      <div>{contact.name}</div>
    </div>
  );
}

export default Page2;

action 用法

action 是拦截用户通过 Form 组件包裹的数据转发到 action 上面

创建 action

  • page2.jsx 里面创建 action
jsx
export const action = async ({ request, params }) => {
  const formData = await request.formData();
  const updates = Object.fromEntries(formData);
  console.log(updates); // 获取到你提交的数据
  // await updateContact(params.contactId, updates); // 这里就是你发送走的数据
  // return redirect(`/contacts/${params.contactId}`);
};

组件里面使用

  • 不加 action 的话 默认就是找的本页面的
jsx
<Form method="post">
  <input type="text" name="name" />
  <button type="submit">提交</button>
</Form>
  • 如果加 action 的 话 找的就是本页面+action 的

路径: /page2/edit

jsx
<Form method="post" action="edit">
  <input type="text" name="name" />
  <button type="submit">提交</button>
</Form>

绑定到 router 上面

jsx
// 引入
import Page2, {
  loader as page2Loader,
  action as page2Action,
} from "../views/Page2";
// 路由里面加载
{
  path: "/page2/:id",
  element: <Page2></Page2>,
  loader: page2Loader,
  action: page2Action,
},