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

React-Router: No Not Found Route?

考虑以下几点:

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>
];

我有一个 App 模板、一个 HeaderTemplate 和一组具有相同处理程序的参数化路由(在 App 模板中)。当找不到东西时,我希望能够提供 404 路由。例如,/CA/SanFrancisco 应该由 Area 找到并处理,而 /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 始终由 Area 页面处理,但我希望它为 404。此外,如果我将 NotFoundRoute 添加到第一个路由配置,则所有 Area 页面都为 404。

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

我做错了什么?

这是一个可以下载和试验的要点。

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

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

if (!place) return <NotFound />;

希望对您有所帮助!

根据 documentation,已找到 路线 ,即使未找到资源。

Note: This is not intended to be used for when a resource is not found. There is a difference between the router not finding a matched path and a valid URL that results in a resource not being found. The url courses/123 is a valid url and results in a matched route, therefore it was "found" as far as routing is concerned. Then, if we fetch some data and discover that the course 123 does not exist, we do not want to transition to a new route. Just like on the server, you go ahead and serve the url but render different UI (and use a different status code). You shouldn't ever try to transition to a NotFoundRoute.

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

使用新版本的React Router(现在使用2.0.1),你可以使用星号作为路径来路由所有'other paths'.

所以它看起来像这样:

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

DefaultRoute 和 NotFoundRoute 在 react-router 1.0.0 中被移除。

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

对于 react-router 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>

对于 react-router 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 中,您希望 wrap the routes in a Switch 仅呈现第一个匹配的组件。否则你会看到渲染了多个组件。

例如:

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.
}

更多详细信息,您可以查看此代码:

App.js

ProfilePage.js

对于那些正在使用 react router v6 的人

重定向组件已从 react-router 版本 6 中删除。 对于 react-router-dom v6,只需将 Redirect 替换为 Navigate

Migrating up to 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>
    );
}

以上答案都是正确的,并且是针对之前的react 5。在 React v6 中,Switch 不再存在。此解决方案适用于 v6:

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 Router v6

现场演示:Redirect Default or 404 Routes with React Router

示例代码:

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

要重定向并导航到我们选择的路由之一,我们可以使用来自 React Router 的 <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>