React-Router:没有未找到的路由?

请考虑以下几点:

var AppRoutes = [
<Route handler={App} someProp="defaultProp">
<Route path="/" handler={Page} />
</Route>,


<Route  handler={App} someProp="defaultProp">
<Route path="/" handler={Header} >
<Route path="/withheader" handler={Page} />
</Route>
</Route>,


<Route handler={App} someProp="defaultProp">
<Route path=":area" handler={Area} />
<Route path=":area/:city" handler={Area} />
<Route path=":area/:city/:locale" handler={Area} />
<Route path=":area/:city/:locale/:type" handler={Area} />
</Route>
];

我有一个应用程序模板,一个HeaderTemplate,以及具有相同处理程序的参数化路由集(在应用程序模板中)。我希望能够在找不到东西时为404路由提供服务。例如,/CA/SanFrancisco应按区域查找和处理,而/SanFranciscoz应为404。

下面是我如何快速测试路线。

['', '/', '/withheader', '/SanFranciscoz', '/ca', '/CA', '/CA/SanFrancisco', '/CA/SanFrancisco/LowerHaight', '/CA/SanFrancisco/LowerHaight/condo'].forEach(function(path){
Router.run(AppRoutes, path, function(Handler, state){
var output = React.renderToString(<Handler/>);
console.log(output, '\n');
});
});

问题是/SanFranciscoZ始终由区域页面处理,但我希望它为404。此外,如果我将NotFoundRoute添加到第一个路由配置,则所有区域页面为404。

<Route handler={App} someProp="defaultProp">
<Route path="/" handler={Page} />
<NotFoundRoute handler={NotFound} />
</Route>,

我做错了什么?

这里有一个要点,可以下载和实验。

https://gist.github.com/adjavaherian/aa48e78279acddc25315.

310638 次浏览

我只是快速浏览了一下您的示例,但如果我理解正确的话,您正在尝试将404路由添加到动态段。几天前,我遇到了同样的问题,发现#458#1103,最后在渲染函数中进行了手工检查:

if (!place) return <NotFound />;

希望对你有帮助!

根据文档,路由已找到,即使该资源未找到。

注意:当找不到资源时,不应使用此选项。路由器找不到匹配的路径与有效的URL导致找不到资源是有区别的。URL课程/123是有效的URL,并且会产生匹配的路由,因此就路由而言,它是“找到的”。然后,如果我们获取一些数据并发现航线123不存在,我们就不想转换到新的航线。就像在服务器上一样,您继续提供URL,但呈现不同的UI(并使用不同的状态代码)。您不应该尝试转换到NotFoundRoute.

因此,您始终可以在Router.run()中,在React.render()之前添加一行,以检查资源是否有效。只需将属性向下传递给组件,或使用自定义属性覆盖“Handler ”组件,即可显示NotFound视图。

使用新版本的React路由器(现在使用2.0.1),您可以使用星号作为路由所有“其他路径”的路径。

所以它看起来像这样:

<Route route="/" component={App}>
<Route path=":area" component={Area}>
<Route path=":city" component={City} />
<Route path=":more-stuff" component={MoreStuff} />
</Route>
<Route path="*" component={NotFoundRoute} />
</Route>

在React-Router 1.0.0中删除了DefaultRoute和NotFoundRoute.

我想强调的是,在当前层次结构级别中,带有星号必须是最后一个。的默认路由可以正常工作。否则,它将覆盖树中出现在它后面的所有其他路由,因为它是第一个并且匹配每条路径。

对于反应路由器1、2和3

如果要显示404和保持路径(与NotFoundRoute的功能相同)

<Route path='*' exact={true} component={My404Component} />

如果要显示404页面,但更改URL(与DefaultRoute的功能相同)

<Route path='/404' component={My404Component} />
<Redirect from='*' to='/404' />

具有多个级别的示例:

<Route path='/' component={Layout} />
<IndexRoute component={MyComponent} />
<Route path='/users' component={MyComponent}>
<Route path='user/:id' component={MyComponent} />
<Route path='*' component={UsersNotFound} />
</Route>
<Route path='/settings' component={MyComponent} />
<Route path='*' exact={true} component={GenericNotFound} />
</Route>

对于反应路由器4和5

保持路径

<Switch>
<Route exact path="/users" component={MyComponent} />
<Route component={GenericNotFound} />
</Switch>

重定向到另一个路由(更改URL)

<Switch>
<Route path="/users" component={MyComponent} />
<Route path="/404" component={GenericNotFound} />
<Redirect to="/404" />
</Switch>

顺序很重要!

在React-Router的较新版本中,您希望将路由封装在交换机中,它只呈现第一个匹配的组件。否则,您将看到渲染的多个组件。

例如:

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


import App from './app/App';
import Welcome from './app/Welcome';
import NotFound from './app/NotFound';


const Root = () => (
<Router history={browserHistory}>
<Switch>
<Route exact path="/" component={App}/>
<Route path="/welcome" component={Welcome}/>
<Route component={NotFound}/>
</Switch>
</Router>
);


ReactDOM.render(
<Root/>,
document.getElementById('root')
);

此答案适用于React-Router-4。 您可以将所有路由包装在switch块中,其功能就像switch-case表达式一样,并使用第一个匹配的路由呈现组件。例如)

<Switch>
<Route path="/" component={home}/>
<Route path="/home" component={home}/>
<Route component={GenericNotFound}/> {/* The Default not found component */}
</Switch>

何时使用exact

没有精确的:

<Route path='/home'
component = {Home} />


{/* This will also work for cases like https://<domain>/home/anyvalue. */}

使用精确:

<Route exact path='/home'
component = {Home} />


{/*
This will NOT work for cases like https://<domain>/home/anyvalue.
Only for https://<url>/home and https://<domain>/home/
*/}

现在,如果您正在接受路由参数,并且结果不正确,您可以在目标组件本身中处理它。例如)

<Route exact path='/user/:email'
render = { (props) => <ProfilePage {...props} user={this.state.user} />} />

现在在ProfilePage.JS中

if(this.props.match.params.email != desiredValue)
{
<Redirect to="/notFound" component = {GenericNotFound}/>
//Or you can show some other component here itself.
}

有关更多详细信息,请参阅此代码:

应用程序.JS

ProfilePage.js

适用于使用React路由器V6的用户

Redirect组件已从React-Router版本6中删除。 对于react-router-dom V6,只需将Redirect更换为Navigate

迁移到V6

npm install react-router-dom@6

import {Routes, Route, Navigate } from "react-router-dom";


function App() {
return (
<div>
<Routes>
<Route path="/404" element={<div>Choose the correct path/div>} />
<Route path="*" element={<Navigate replace to="/404" />} />
</Routes>
</div>
);
}

上面的答案是正确的,对于之前的反应5。在REACT V6中,Switch不再存在。该溶液用于REACTV6

import {BrowserRouter as Router, Routes, Route, Link} from "react-router-dom";


...


<Router>
<ul>
<li>
<Link to="t1">component1</Link>
</li>
<li>
<Link to="t2">component2</Link>
</li>
</ul>


<Routes>
<Route path="/t1" exact element={<Component1/>}/>
<Route path="/t2" exact element={<Component2/>}/>
<Route path="*" element={<NotFound/>}/>
</Routes>


</Router>

React路由器V6

现场演示:使用React路由器重定向默认路由或404路由

示例代码:

<Router>
<Routes>
<Route path="users" element={<Users />} />
<Route path="posts" element={<Posts />} />
</Routes>
</Router>

要重定向并导航到我们选择的路由之一,我们可以使用React路由器中的<Navigate>组件。现在,我们可以在我们的路由配置下面声明空路由的情况,如下所示:

<Router>
<Routes>
<Route path="users" element={<Users />} />
<Route path="posts" element={<Posts />} />
<Route path="" element={<Navigate to="/users" />} />
</Routes>
</Router>

我有类似的问题,而不是使用*野生标识符或默认开关组件。我们可以只使用路由组件而不定义路径。

例子:

<Switch>
<Route path="/" component={Root} />
<Route path="/home" component={Home} />
<Route component={NotFoundPage} />
// Default Component To load If none  of the path matches.
</Switch>