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
相关产品推荐
相关产品推荐

