React-Router: Rute Tidak Ditemukan?

132

Pertimbangkan hal berikut:

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

Saya memiliki Templat Aplikasi, HeaderTemplate, dan kumpulan rute Parameterized dengan penangan yang sama (dalam template Aplikasi). Saya ingin bisa melayani 404 rute ketika sesuatu tidak ditemukan. Misalnya, / CA / SanFrancisco harus ditemukan dan ditangani berdasarkan Area, sedangkan / SanFranciscoz harus 404.

Inilah cara saya menguji rute dengan cepat.

['', '/', '/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');
    });
});

Masalahnya adalah / SanFranciscoz selalu ditangani oleh halaman Area, tetapi saya menginginkannya ke 404. Juga, jika saya menambahkan NotFoundRoute ke konfigurasi rute pertama, semua halaman Area 404.

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

Apa yang saya lakukan salah?

Berikut adalah inti yang dapat diunduh dan diujicobakan.

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

4m1r
sumber
Untuk referensi di masa mendatang bagi orang-orang yang akhirnya memiliki pertanyaan ini, selain jawaban yang benar di bawah ini, baca artikel ini . Saya menemukannya sebelumnya dan saya pikir orang itu menjelaskannya dengan sempurna.
Dimitris Damilos

Jawaban:

251

DefaultRoute dan NotFoundRoute telah dihapus di react-router 1.0.0.

Saya ingin menekankan bahwa rute default dengan tanda bintang harus yang terakhir di tingkat hierarki saat ini agar berfungsi. Jika tidak, ini akan menimpa semua rute lain yang muncul setelahnya di pohon karena ini pertama dan cocok dengan setiap jalur.

Untuk react-router 1, 2 dan 3

Jika Anda ingin menampilkan 404 dan mempertahankan jalur (Fungsionalitas yang sama seperti NotFoundRoute)

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

Jika Anda ingin menampilkan halaman 404 tetapi mengubah url (Fungsionalitas yang sama seperti DefaultRoute)

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

Contoh dengan banyak tingkatan:

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

Untuk react-router 4 dan 5

Pertahankan jalannya

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

Alihkan ke rute lain (ubah url)

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

Urutan penting!

Janne Annala
sumber
jika Anda memiliki aplikasi redux, bagaimana Anda melakukannya: <Redirect from='*' to='/home' />dalam sintaks ini:const routes = { component: Main, childRoutes: [ { path: '/', component: Home }, ], indexRoute: { component: Main, }, };
tatsu
1
jika Anda ingin menyetel properti untuk 404-Compontent gunakan kode ini:<Route render={(props)=> <MyComponent myProp={someVar} {...props} />} />
Marco Weber
Bagaimana dengan 500 halaman? Seperti halaman yang seharusnya dimuat tetapi API memberikan kesalahan. Bagaimana cara menampilkan ini alih-alih halaman yang gagal saat mempertahankan rute?
PixMach
<Redirect to = "/ 404" /> menyebabkan Kedalaman pembaruan maksimum melebihi pada react-router-dom 5.0.0. Bahkan jika halaman 404 keluar, itu mengalihkan.
MiguelSlv
5
Saya tidak suka menggunakan pengalihan karena menyembunyikan URL bermasalah dari pengguna. Ini juga membutuhkan memukul balik dua kali untuk kembali ke halaman sebelumnya.
sdgfsdh
39

Dalam versi react-router yang lebih baru, Anda ingin menggabungkan rute di Switch yang hanya menampilkan komponen pertama yang cocok. Jika tidak, Anda akan melihat beberapa komponen dirender.

Sebagai contoh:

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')
);
metakermit
sumber
12
Anda tidak perlu menyertakan path="*"di Rute NotFound. Menghilangkan pathakan menyebabkan Rute selalu cocok.
chipit24
1
Untuk orang yang datang terlambat, @ chipit24 benar, untuk menghindari kebingungan, hilangkan saja pathrute yang tidak diketahui seluruhnya
Altair312
14

Dengan versi baru React Router (sekarang menggunakan 2.0.1), Anda dapat menggunakan tanda bintang sebagai jalur untuk merutekan semua 'jalur lain'.

Jadi akan terlihat seperti ini:

<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>
dejakob
sumber
10

Jawaban ini untuk react-router-4. Anda dapat menggabungkan semua rute dalam blok Switch, yang berfungsi seperti ekspresi kasus sakelar, dan membuat komponen dengan rute pertama yang cocok. misalnya)

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

Kapan digunakan exact

Tanpa tepat:

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

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

Dengan tepat:

<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/
*/}

Sekarang jika Anda menerima parameter perutean, dan jika ternyata salah, Anda dapat menanganinya di komponen target itu sendiri. misalnya)

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

Sekarang di ProfilePage.js

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

Untuk lebih jelasnya Anda bisa melalui kode ini:

App.js

ProfilePage.js

Pransh Tiwari
sumber
6

Menurut dokumentasi , rute itu ditemukan, meskipun sumber daya itu tidak.

Catatan : Ini tidak dimaksudkan untuk digunakan ketika sumber daya tidak ditemukan. Ada perbedaan antara router tidak menemukan jalur yang cocok dan URL valid yang menyebabkan sumber daya tidak ditemukan. Kursus url / 123 adalah url yang valid dan menghasilkan rute yang cocok, oleh karena itu "ditemukan" sejauh menyangkut perutean. Kemudian, jika kita mengambil beberapa data dan menemukan bahwa jalur 123 tidak ada, kita tidak ingin berpindah ke rute baru. Sama seperti di server, Anda melanjutkan dan menyajikan url tetapi membuat UI yang berbeda (dan menggunakan kode status yang berbeda). Anda tidak boleh mencoba beralih ke NotFoundRoute.

Jadi, Anda selalu dapat menambahkan baris di Router.run()before React.render()untuk memeriksa apakah sumber daya valid. Cukup teruskan prop ke komponen atau ganti Handlerkomponen dengan yang khusus untuk menampilkan tampilan NotFound.

Brad B
sumber
terima kasih @brad, Anda benar, Anda harus menangani ini dengan komponen dan atau menimpa handler sebelum router.run
4m1r
3
NotFound tidak digunakan lagi github.com/reactjs/react-router/releases/tag/v1.0.0 , sekarang digunakan <Route path="*" to="/dest" />atau <Redirect from="*" to="/dest" />sebagai sub rute terakhir yang cocok, saya yakin
ptim
5

Saya baru saja melihat sekilas contoh Anda, tetapi jika saya memahaminya dengan cara yang benar, Anda mencoba menambahkan rute 404 ke segmen dinamis. Saya mengalami masalah yang sama beberapa hari yang lalu, menemukan # 458 dan # 1103 dan berakhir dengan pemeriksaan tangan dalam fungsi render:

if (!place) return <NotFound />;

semoga membantu!

Jörn
sumber
terima kasih @jorn, saya pikir Anda benar, ini tampaknya hanya dapat dialamatkan dari tingkat komponen
4m1r