React Router v4路由不起作用。

41

我对React比较新,正在尝试弄清楚如何使React路由器起作用。我有一个超级简单的测试应用程序,看起来像这样:

import React from 'react';
import ReactDOM from 'react-dom';

import {BrowserRouter as Router, Route, Switch, IndexRoute, Link} from 'react-router-dom';

const Home = () => <h1><Link to= "/about">Click Me</Link></h1>
const About = () => <h1>About Us</h1>

const Test = () => (
  <Router>
    <Switch>
    <Route path ="/" component = {Home} />
    <Route path ="/about" component = {About} />
    </Switch>
  </Router>
)

ReactDOM.render(<Test />, document.getElementById('app'));
当我运行该应用程序时,主页组件可以正常加载,但当我点击“Click Me”链接时,网址会改变为localhost/about,但是没有任何反应。如果我点击刷新,会出现“Cannot GET /about.”的提示。显然我做错了些什么,但我还没有找到问题所在。我也在使用Webpack。

控制台中有任何消息吗?这可能是About组件的问题,而不是路由器本身的问题。另外,尝试将About组件放在*/*路径上,看看会发生什么。 - gretro
回复:无法获取/about:考虑使用[create-react-app](https://github.com/facebookincubator/create-react-app)。它得到了 Facebook 的认可,在开发中可以立即使服务器部分正常工作,还有许多其他方便的开发功能。如果没有它,您需要自己管理将所有路由引导到index.html,或者使用react-router中的哈希路由。 - Alex Guerra
10个回答

82

你需要使用精确路径/,否则它也会匹配/about

<Route exact path="/" component={Home} />

如评论所述,对于这样简单的东西,我建议使用Create React App,它将确保您的服务器代码和webpack设置都是正确的。一旦您使用了create-react-app,您只需要使用npm来安装react路由器v4包,然后将您的代码放入App.js文件中,它应该就可以工作了。为了让代码在create-react-app 中正常运行,需要进行一些小的更改,如下所示:

// App.js
import React from 'react';

import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';

const Home = () => <h1><Link to="/about">Click Me</Link></h1>
const About = () => <h1>About Us</h1>

const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
    </Switch>
  </Router>
)

export default App;

React Router V4文档的快速入门指南所述内容基本与我刚才解释的一致。


4
不好意思,我也遇到了类似的问题,虽然我已经添加了“exact”但仍然无法正常工作。 - akshay kishore
@akshaykishore,你应该打开一个新的问题,并提供复现问题所使用的代码。 - Todd Chaffee
代码相似,只是我从另一个文件导入了组件。顺便说一下,在刷新第二页时会呈现组件。 - akshay kishore

37
如果你是在本地运行,需要在webpack配置文件中添加historyApiFallback: true。

这就是我的问题!!谢谢。 - Kate
14
稍微多提供一些相关信息会非常有帮助! - DanV
7
如果使用create-react-app,您该如何实现这一点?如果您的技术栈部署到公共服务器上会出现问题吗?我在本地和服务器上都遇到了同样的问题。 - Shazam
2
这需要添加到文档中,否则我永远不会知道。我已经因此苦恼了很久。 - Sierra Kilo
6
我没有webpack.config文件。我该怎么办? - Ashish Kirodian
显示剩余4条评论

10

如果添加exact无法解决问题,我已经用替换了它。

  <Route exact path="/" component={App} />
  <Route path="/login" component={Login} />
  <Route path="/register" component={Register} />

这个

  <Route exact path="/"> <App /> </Route>
  <Route path="/login"> <Login /> </Route>
  <Route path="/register"> <Register /> </Route>

将组件作为路由子组件可以解决我的页面路由问题,希望能对其他人有所帮助


不幸的是,这损坏了我的应用程序。 - averwhy

7
使用 Switch 时需要注意,我们要按照从最具体到最一般的顺序指定路由。 在您的情况下,您在"/about"之前指定了"/"。 因此,每次React正在查找"/about"但是向下移动,<Route "/"仍然适用于"/about"(因为"/about""/"的子路由)。 因此,请使用:"/about""/"之前。

这样你就可以省略exact

import React from 'react';
import ReactDOM from 'react-dom';

import {BrowserRouter as Router, Route, Switch, IndexRoute, Link} from 'react-router-dom';

const Home = () => <h1><Link to= "/about">Click Me</Link></h1>
const About = () => <h1>About Us</h1>

const Test = () => (
  <Router>
    <Switch>
        <Route path ="/about" component = {About} />
        <Route path ="/" component = {Home} />
    </Switch>
  </Router>
)

ReactDOM.render(<Test />, document.getElementById('app'));

6
你也可以通过将默认路由始终放在最后来解决此问题。 // 始终放在最后
无需使用“exact”关键字。

2
也许这可以帮助某些人。我忘了使用正确的history,而是用了BrowserRouter,它忽略属性history={...}并使用自己的history。我试图使用手动创建的history重定向页面,但是BrowserRouter正在使用它自己的history。"Original Answer"的翻译是"最初的回答"。

1

试一试

npm i react-router-dom 

App.js

import Dashboard from './Dashboard';
import { BrowserRouter, Routes , Route, Link, useRouteMatch } from 'react-router-dom';


  return (
    <BrowserRouter>
    <Routes>
      <Route exact path="/"  element={<Dashboard />}></Route>
      <Route path="/dashboard"  element={<Dashboard />}></Route>
    </Routes>
  </BrowserRouter>
  );
}

Dashboard.js

export default function Dashboard() {
    return (
      <>
        <h1>Welcome</h1>
      </>
    );
}

1
这是另一种可能发生的情况。这是一个愚蠢的错误,但在我的情况下就是问题所在。
我的问题是一个导入错误。最初,我有以下导入:
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';

我决定将BrowserRouter组件移动到更高的级别,但是在删除不再需要的Router组件时,我的导入变成了这样:

import { BrowserRouter as Switch, Route } from 'react-router-dom';

因此,实际上,我最终删除了 Switch 组件并将 BrowserRouter 作为 Switch 的别名。
Switch 不再按预期工作是正常的。

0
如果这些方法都不起作用,您可以尝试以下方式。我曾经遇到与React Router相同的问题。我使用的是React Router V6,并通过将Route标签包含在Routes标签中来解决该问题。
  • Route元素只能作为Routes元素的子元素使用。
import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom';

然后将其封装在Routes标签中

<Router>
    <Routes>
        <Route path ="/about" component = {About} />
        <Route path ="/" component = {Home} />
    </Routes>
</Router>


通过添加Routes标签,解决了我的问题。希望这对你有所帮助。

0
如果您正在使用React Router V6,并且您将路由设置为:

<Route path="/" component={Home} />

将其更改为使用元素:

<Route path="/" element={<Home />} />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接