You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router v6:如何在Loader中使用Context的getPet函数?

解决方案

1. 提取独立的宠物数据服务函数

getPet 仅负责调用Firestore接口,不依赖Context内部状态,可抽成独立工具函数,让路由loader直接调用:

创建src/services/petService.js:

import { doc, getDoc } from "firebase/firestore";
import { firestore } from "../your-firebase-config-path"; // 替换为你的Firebase配置路径

export const getPet = async (petID) => {
  const docRef = doc(firestore, 'pets_data', petID);
  const docSnap = await getDoc(docRef);
  
  if (docSnap.exists()) {
    return { ...docSnap.data(), id: docSnap.id };
  } else {
    throw new Error("宠物不存在"); // 抛出具体错误信息,便于错误页展示
  }
};

2. 更新Context文件,导入并暴露getPet

修正Context中遗漏的getPet暴露问题,确保组件仍能通过Context获取该函数:

import { getPet } from "../services/petService"; // 导入工具函数

// ... 其他原有代码不变

const PetShopProvider = ({ children }) => {
  // ... 现有状态和函数保持不变

  return (
    <PetShopContext.Provider
      value={{
        data,
        setData,
        getData,
        getPet, // 新增该行,将getPet加入Context
      }}
    >
      {children}
    </PetShopContext.Provider>
  );
};

3. 配置路由的loader函数

在main.js中导入getPet,并配置到目标路由的loader中:

import { getPet } from "./services/petService"; // 导入工具函数

// ... 其他原有代码不变

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />,
    errorElement: <ErrorPage />,
    children: [
      // ... 其他路由保持不变
      {
        path: 'pets/:id',
        element: <PetInfoPage />,
        errorElement: <PetInfoErrorPage />,
        loader: async ({ params }) => {
          // 从路由参数中获取宠物ID,调用getPet获取数据
          return getPet(params.id);
        },
      },
    ],
  },
]);

4. 更新PetInfoPage,使用loader返回的数据

移除原有的useEffect请求逻辑,改用React Router的useLoaderData获取预加载数据:

import { useLoaderData, useParams, useNavigate } from 'react-router-dom';
import { PetShopContext } from '../context/PetShopContext.jsx';

const PetInfoPage = () => {
  const navigate = useNavigate();
  const { id } = useParams();
  const { deleteService } = React.useContext(PetShopContext);
  // 直接获取loader预加载的宠物数据
  const currentPet = useLoaderData();
  const [currentPetService, setCurrentPetService] = React.useState();
  const [formModal, setFormModal] = React.useState(false);
  const [alertModal, setAlertModal] = React.useState(false);

  // 移除原有的useEffect请求代码

  // ... 其他业务逻辑保持不变
};

错误处理说明

当getPet抛出错误时,React Router会自动渲染该路由配置的errorElement(即PetInfoErrorPage),可在错误页中用useRouteError获取错误信息:

// PetInfoErrorPage.jsx
import { useRouteError } from "react-router-dom";

const PetInfoErrorPage = () => {
  const error = useRouteError();
  
  return (
    <div>
      <h2>加载宠物信息失败</h2>
      <p>{error.message || "未知错误"}</p>
    </div>
  );
};

export default PetInfoErrorPage;

内容的提问来源于stack exchange,提问作者Yuri da Paz Simonin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 12:05:14