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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 14:27:57