React-Router:ルートが見つかりませんか?


132

以下を検討してください。

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

アプリテンプレート、ヘッダーテンプレート、およびパラメーター化された同じハンドラーを持つルートのセット(アプリテンプレート内)があります。何かが見つからないときに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が常にエリアページによって処理されていることですが、404にしたいです。また、NotFoundRouteを最初のルート構成に追加すると、すべてのエリアページが404になります。

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

何が悪いのですか?

ダウンロードして実験できる要点は次のとおりです。

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


この質問にたどり着く人々のために、以下の正しい答えは別として、この記事を読んでください。私は以前それを見つけました、そしてその人はそれを完全に説明すると思います。
Dimitris Damilos

回答:


248

DefaultRouteとNotFoundRouteは、react-router 1.0.0で削除されました。

アスタリスク付きのデフォルトルートが機能するには、現在の階層レベルの最後なければならないことを強調しておきます。それ以外の場合は、ツリーの最初にあり、すべてのパスに一致するため、ツリーの後に表示される他のすべてのルートをオーバーライドします。

反応ルーター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>

順序は重要です!


reduxアプリがある場合、どのようにすればよいですか:<Redirect from='*' to='/home' />この構文では:const routes = { component: Main, childRoutes: [ { path: '/', component: Home }, ], indexRoute: { component: Main, }, };
tatsu

1
あなたは404-Compontent用セットの小道具にしたい場合は、このコードを使用します<Route render={(props)=> <MyComponent myProp={someVar} {...props} />} />
マルコ・ウェーバー

500ページはどうですか?ロードされるはずのページのようですが、APIはエラーを出します。ルートを維持しているときに失敗したページの代わりにこれを表示するにはどうすればよいですか?
PixMach

<Redirect to = "/ 404" />により、react-router-dom 5.0.0で最大更新深度が超過します。ページ404が存在する場合でもリダイレクトします。
MiguelSlv

4
問題のあるURLをユーザーから隠すため、リダイレクトの使用は嫌いです。また、前のページに戻るには、2回戻る必要があります。
sdgfsdh

39

新しいバージョンの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')
);

12
path="*"NotFoundルートに含める必要はありません。省略pathすると、ルートは常に一致します。
chipit24

1
遅い時間に来る人にとって、@ chipit24は正しいです。混乱を避けるためpathに、不明なルートを完全に省略してください
Altair312

14

新しいバージョンの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>

10

この回答は、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


6

ドキュメントによると、リソースが見つからなかったにもかかわらず、ルート見つかりました。

:これは、リソースが見つからない場合に使用するためのものではありません。一致するパスが見つからないルーターと、リソースが見つからない有効なURLとの間には違いがあります。URLコース/ 123は有効なURLであり、ルートが一致するため、ルーティングに関する限り「発見」されました。次に、データをフェッチしてコース123が存在しないことを発見した場合、新しいルートに移行したくありません。サーバーと同じように、先に進んでURLを提供しますが、異なるUIをレンダリングします(そして異なるステータスコードを使用します)。NotFoundRouteに移行しようとするべきではありません。

したがって、リソースが有効かどうかを確認Router.run()するReact.render()ために、前の行を常に追加できます。HandlerNotpropビューを表示するには、コンポーネントにプロップを渡すか、コンポーネントをカスタムのものでオーバーライドするだけです。


感謝の@brad、あなたは右、あなたがコンポーネントにこれを処理し、またはrouter.run前にハンドラをオーバーライドする必要があります
4m1r

3
NotFoundは廃止されましたgithub.com/reactjs/react-router/releases/tag/v1.0.0<Route path="*" to="/dest" />または<Redirect from="*" to="/dest" />一致する最後のサブルートとして使用するか、私は信じています
ptim

5

私はあなたの例をざっと見ましたが、私がそれを正しい方法で理解していれば、404のルートを動的セグメントに追加しようとしているのです。私は数日前に同じ問題を抱えていて、#458#1103を見つけて、レンダリング機能内で手作りのチェックが行われました。

if (!place) return <NotFound />;

お役に立てば幸いです。


@jornのおかげで、私はあなたが正しいと思います。これはコンポーネントレベルからのみアドレス指定できるようです
4m1r
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.