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

React Router:动态路由参数无效时如何返回404页面?

解决React Router中无效pageId导致应用崩溃并跳转到404页面的方案

嘿,这个问题我之前做项目的时候也碰到过,其实可以通过几种方式来处理,既避免应用崩溃,又能优雅地跳转到404页面,具体看你用的React Router版本:

方式一:在Template组件内处理API响应并手动重定向

这是最通用的方案,不管是React Router v5还是v6都适用,核心思路是在请求API后判断返回结果,如果页面不存在,就触发重定向。

如果使用React Router v5

用useHistory钩子来实现跳转:

import { useHistory, useParams } from 'react-router-dom';
import { useState, useEffect } from 'react';

function Template() {
  const { pageId } = useParams();
  const history = useHistory();
  const [pageContent, setPageContent] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const fetchPage = async () => {
      try {
        const res = await fetch(`/your-api-url/${pageId}`);
        // 先判断请求是否成功(比如API返回404状态码)
        if (!res.ok) {
          throw new Error('Requested page does not exist');
        }
        const content = await res.json();
        setPageContent(content);
      } catch (err) {
        // 捕获到错误后,重定向到404页面
        history.push('/404');
      } finally {
        setIsLoading(false);
      }
    };

    fetchPage();
  }, [pageId, history]);

  if (isLoading) {
    return <div>Loading page content...</div>;
  }

  return <div>{pageContent?.content}</div>;
}

如果使用React Router v6

v6里把useHistory换成了useNavigate钩子:

import { useNavigate, useParams } from 'react-router-dom';
import { useState, useEffect } from 'react';

function Template() {
  const { pageId } = useParams();
  const navigate = useNavigate();
  const [pageContent, setPageContent] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const fetchPage = async () => {
      try {
        const res = await fetch(`/your-api-url/${pageId}`);
        if (!res.ok) {
          throw new Error('Requested page does not exist');
        }
        const content = await res.json();
        setPageContent(content);
      } catch (err) {
        // 重定向到404页面
        navigate('/404');
      } finally {
        setIsLoading(false);
      }
    };

    fetchPage();
  }, [pageId, navigate]);

  if (isLoading) {
    return <div>Loading page content...</div>;
  }

  return <div>{pageContent?.content}</div>;
}

方式二:用React Router v6的errorElement实现优雅错误捕获

如果你的项目用的是React Router v6.4+,可以用官方提供的errorElement来统一处理路由级别的错误,这种方式更简洁:

  1. 首先定义一个404/错误页面组件:
import { useRouteError, Link } from 'react-router-dom';

function ErrorPage() {
  const error = useRouteError();
  console.error('Page error:', error);

  return (
    <div className="error-page">
      <h1>Oops! Page Not Found</h1>
      <p>Sorry, the page you're looking for doesn't exist.</p>
      <Link to="/">Go back to homepage</Link>
    </div>
  );
}
  1. 然后在路由配置里给/:pageId路由加上errorElement:
import { Routes, Route } from 'react-router-dom';
import Template from './Template';
import ErrorPage from './ErrorPage';

function AppRoutes() {
  return (
    <Routes>
      <Route path="/:pageId" element={<Template />} errorElement={<ErrorPage />} />
      {/* 也可以单独配置404路由,处理其他无效路径 */}
      <Route path="*" element={<ErrorPage />} />
    </Routes>
  );
}
  1. 最后在Template组件里,当API请求失败时直接抛出错误,errorElement会自动捕获并渲染错误页面:
import { useParams } from 'react-router-dom';
import { useState, useEffect } from 'react';

function Template() {
  const { pageId } = useParams();
  const [pageContent, setPageContent] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const fetchPage = async () => {
      try {
        const res = await fetch(`/your-api-url/${pageId}`);
        if (!res.ok) {
          throw new Error('Page not found');
        }
        const content = await res.json();
        setPageContent(content);
      } catch (err) {
        // 抛出错误,让errorElement捕获
        throw err;
      } finally {
        setIsLoading(false);
      }
    };

    fetchPage();
  }, [pageId]);

  if (isLoading) {
    return <div>Loading page content...</div>;
  }

  return <div>{pageContent?.content}</div>;
}

额外注意点

  • 不管用哪种方式,都要确保你的路由配置里已经有对应的404页面路由(比如/404或者path="*")。
  • 处理API请求时,不仅要判断response.ok(覆盖HTTP错误状态码),还要捕获网络请求失败的情况(比如断网),这些情况都会进入catch块,从而触发重定向。

内容的提问来源于stack exchange,提问作者ahols

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:31:18