使用react-router-dom的defer时无法触发errorElement处理错误的问题求助
使用react-router-dom的defer时无法触发errorElement处理错误的问题求助
各位大佬好!我最近在学习react-router,做了个简单的小应用,尝试用数据加载器(data loaders)在组件渲染前获取数据,还用到了defer来延迟数据获取,配合Suspense和Await组件处理异步加载逻辑。
我在根路由path="/"里定义了errorElement={<Error/>},本来预期数据获取出错时会自动渲染这个错误组件,但实际情况是,每次fetch数据出问题时,这个Error组件根本不渲染,反而会显示组件里的错误提示。我排查后发现错误是从loader函数里抛出的——就是这个返回defer的loader:export function loader() { return defer({ bookmarks: getBookmarks() }); }。有没有懂的朋友帮我看看哪里出问题了呀?
相关代码如下:
Home.js
import React, { Suspense } from "react"; import { getBookmarks } from "./api"; import { useLoaderData, defer, Await } from "react-router-dom"; export function loader() { return defer({ bookmarks: getBookmarks() }); } export default function Home() { const dataPromise = useLoaderData(); function renderBookMarks(bookmarks) { console.log(bookmarks); const bookmarksArr = bookmarks.data; const bookmarksElements = bookmarksArr.map(bookmark =>{ return( <div key={bookmark.id} className="bookmark"> <a target="#" href={bookmark.url} className="bookmark-element">{bookmark.title}</a> </div> ) }) return( <div className="bookmark-container"> <h1>Search bookmarks</h1> {bookmarksElements} </div> ) } return ( <div> <Suspense fallback={<h2>Loading...</h2>}> <Await resolve={dataPromise.bookmarks}> {renderBookMarks} </Await> </Suspense> </div>) }
api.js
import config from "./config"; const apiUrl = config.apiUrl; const apiPort = config.apiPort; const joinUrl = (baseUrl, url) => { return `${baseUrl}/${url}`; }; const domain = `${apiUrl}:${apiPort}/api/bookmarks`; export async function getBookmarks(url = "") { url = joinUrl(domain, URL); const res = await fetch(URL); if (!res.ok) { throw Object.assign(new Error("Failed to fetch data"), { message: "Failed to fetch data", statusText: res.statusText, status: res.status, }); } const data = await res.json(); return data; }
Error.js
import React from "react"; import { useRouteError } from "react-router-dom"; export default function Error() { const error = useRouteError(); console.log({error}) return (<div> <h1>Oops! Something Went Wrong</h1> <h1>{error.message}</h1> </div>) }
Index.jsx
import React from 'react'; import ReactDOM from 'react-dom/client'; import Layout from './components/Layout'; import Error from './components/Error'; import './index.css'; import { RouterProvider, createHashRouter, createRoutesFromElements, Route, } from "react-router-dom"; import Home,{loader as bookmarksLoader} from './Home'; import AddBookMark from './AddBookMark'; const hashRouter = createHashRouter(createRoutesFromElements( <Route path="/" element={<Layout/>} errorElement={<Error/>}> <Route index element={<Home/>} loader={bookmarksLoader} /> <Route path='addBookMarks' element={<AddBookMark/>}/> </Route> )) function App() { return ( <RouterProvider router={hashRouter} /> ) } ReactDOM.createRoot(document.getElementById('root')).render(<App />);
备注:内容来源于stack exchange,提问作者manjosh
相关产品推荐
相关产品推荐

