React Router路由跳转时组件不加载及刷新404问题求助
1. Login组件不加载的原因及修复
你代码里踩了一个React Router的常见坑:在App和Header中分别嵌套了<BrowserRouter>。<BrowserRouter>是路由上下文的提供者,每个实例都会维护独立的路由状态——Header里的<Link>属于内层Router的上下文,而App里的<Route>属于外层Router的上下文,两者完全脱节。所以点击Link时URL虽然变了,但外层的Route根本没收到路由变化的通知,自然不会渲染Login组件。
修复起来很简单:只保留一个根级的<BrowserRouter>,把所有路由相关组件(包括Header)都放在它内部,让它们共享同一个路由上下文。修改后的代码如下:
修改后的App.tsx
import React from 'react'; import {BrowserRouter as Router, Route} from 'react-router-dom'; import Header from './components/Header/Header'; import Login from './components/Login/Login'; const App = () => { return ( <Router> {/* 仅保留这一个Router作为根容器 */} <Header /> <Route path="/login" exact component={Login} /> </Router> ); }; export default App;
修改后的Header.tsx
import React from 'react'; import {Link} from 'react-router-dom'; // 移除多余的BrowserRouter const Header = () => { return ( <Link to="/login">login</Link> ); }; export default Header;
这样调整后,点击Header里的链接,Router就能正确感知路由变化,自动渲染对应的Login组件了。
2. 刷新/login页面显示Cannot GET /login的解决方法
这个问题源于<BrowserRouter>使用的HTML5 History模式:刷新页面时,浏览器会直接向服务器发送GET /login的请求,但你的服务器(比如webpack-dev-server)并没有配置这个路径的响应,所以返回404错误。
解决思路是让服务器在收到任何未知路径的请求时,都返回SPA的入口文件(通常是index.html),把路由控制权交还给React Router:
如果你用webpack-dev-server
在webpack.config.js中添加historyApiFallback配置:
module.exports = { // ...其他配置项 devServer: { historyApiFallback: true, // 启用该配置,自动重定向到index.html // 也可以更精确配置: // historyApiFallback: { // index: '/index.html' // } } };
如果你用Express等后端服务器
添加一个通配路由,将所有请求重定向到index.html:
const express = require('express'); const path = require('path'); const app = express(); // 静态文件服务,托管打包后的资源 app.use(express.static(path.join(__dirname, 'build'))); // 通配路由:所有未匹配的请求都返回index.html app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'build', 'index.html')); }); app.listen(8080);
配置完成后,刷新/login页面时,服务器会返回index.html,React Router就能正确解析路由并渲染Login组件了。
内容的提问来源于stack exchange,提问作者Peter Boomsma

