React-Router:没有找到路由?

4m1*_*m1r 109 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>
];
Run Code Online (Sandbox Code Playgroud)

我有一个App Template,一个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');
    });
});
Run Code Online (Sandbox Code Playgroud)

问题是/ SanFranciscoz总是由Area页面处理,但我希望它为404.另外,如果我将NotFoundRoute添加到第一个路由配置,所有Area页面404.

<Route handler={App} someProp="defaultProp">
    <Route path="/" handler={Page} />
    <NotFoundRoute handler={NotFound} />
</Route>,
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

这是一个可以下载和实验的要点.

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

Jan*_*ala 194

Dejakob的答案是正确的,在反应路由器1.0.0中删除了DefaultRoute和NotFoundRoute.我想强调的是,带星号的默认路由必须是当前层次结构级别的最后一个才能工作.否则,它将匹配树中显示在其后面的所有路由.

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

如果要显示404并保留路径(与NotFoundRoute功能相同)

<Route path='*' exact={true} component={My404Component} />
Run Code Online (Sandbox Code Playgroud)

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

<Route path='/404' component={My404Component} />
<Redirect from='*' to='/404' />
Run Code Online (Sandbox Code Playgroud)

多个级别的示例:

<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>
Run Code Online (Sandbox Code Playgroud)

对于react-router 4

保持路径

<Switch>
    <Route exact path="/users" component={MyComponent} />
    <Route component={GenericNotFound} />
</Switch>
Run Code Online (Sandbox Code Playgroud)

重定向到另一条路线(更改网址)

<Switch>
    <Route path="/users" component={MyComponent} />
    <Route path="/404" component={GenericNotFound} />
    <Redirect to="/404" />
</Switch>
Run Code Online (Sandbox Code Playgroud)

  • 我不喜欢使用重定向,因为它向用户隐藏了有问题的 URL。它还需要回击两次才能返回上一页。 (7认同)
  • 如果要为 404 组件设置道具,请使用以下代码:`&lt;Route render={(props)=&gt; &lt;MyComponent myProp={someVar} {...props} /&gt;} /&gt;` (2认同)

met*_*mit 30

在较新版本的react-router中,您希望将路由包装在仅呈现第一个匹配组件的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 path="*" component={NotFound}/>
    </Switch>
  </Router>
);

ReactDOM.render(
  <Root/>,
  document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)

  • 您不需要在NotFound路由上包含`path ="*"`.省略`path`将导致Route始终匹配. (9认同)
  • 对于迟到的人来说,@chipit24 是对的,为了避免混淆,只需完全省略未知路线的“路径” (2认同)

小智 16

对于那些使用 React Router v6 的人

重定向组件已从react-router版本6中删除。对于react-router-domv6,只需替换RedirectNavigate

迁移到 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>
    );
}
Run Code Online (Sandbox Code Playgroud)


小智 12

使用新版本的React Router(现在使用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>
Run Code Online (Sandbox Code Playgroud)


Par*_*saN 8

上面的答案是正确的并且适用于之前的react 5。在 React v6 中,Switch不再存在。该解决方案适用于 React 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>
Run Code Online (Sandbox Code Playgroud)


Pra*_*ari 6

该答案适用于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>
Run Code Online (Sandbox Code Playgroud)

何时使用 exact

没有确切:

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

{/* This will also work for cases like https://<domain>/home/anyvalue. */}
Run Code Online (Sandbox Code Playgroud)

确切的说:

<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/
*/}
Run Code Online (Sandbox Code Playgroud)

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

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

现在在ProfilePage.js中

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

有关更多详细信息,您可以查看以下代码:

App.js

ProfilePage.js


Jör*_*örn 5

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

if (!place) return <NotFound />;
Run Code Online (Sandbox Code Playgroud)

希望有帮助!


Bra*_*ugh 5

根据该文件,该航线发现,即使资源没有。

注意:不适用于找不到资源的情况。路由器未找到匹配的路径与导致无法找到资源的有效URL之间存在差异。urlcourses / 123是有效的url,并导致匹配的路由,因此就路由而言,它是“找到的”。然后,如果我们获取一些数据并发现路线123不存在,则我们不想过渡到新路线。就像在服务器上一样,您可以继续提供网址,但是呈现不同的UI(并使用不同的状态代码)。您不应该尝试过渡到NotFoundRoute。

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

  • NotFound已弃用https://github.com/reactjs/react-router/releases/tag/v1.0.0,现在使用`&lt;Route path =“ *” to =“ / dest” /&gt;`或`&lt;Redirect from =我相信“ *” to =“ / dest” /&gt;`是要匹配的最后一条子路线 (3认同)

Chi*_*hor 5

反应路由器 v6

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

示例代码:

<Router>
  <Routes>
    <Route path="users" element={<Users />} />
    <Route path="posts" element={<Posts />} />
  </Routes>
</Router>
Run Code Online (Sandbox Code Playgroud)

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

<Router>
  <Routes>
    <Route path="users" element={<Users />} />
    <Route path="posts" element={<Posts />} />
    <Route path="" element={<Navigate to="/users" />} />
  </Routes>
</Router>
Run Code Online (Sandbox Code Playgroud)