Saya baru saja mengganti react-router
dari v3 ke v4.
Tetapi saya tidak yakin bagaimana cara menavigasi secara terprogram dalam fungsi anggota a Component
. yaitu dalam handleClick()
fungsi saya ingin menavigasi ke /path/some/where
setelah memproses beberapa data. Saya biasa melakukannya dengan:
import { browserHistory } from 'react-router'
browserHistory.push('/path/some/where')
Tapi saya tidak dapat menemukan antarmuka seperti itu di v4.
Bagaimana saya bisa bernavigasi menggunakan v4?
reactjs
ecmascript-6
react-router-v4
Colin Witkamp
sumber
sumber
Component
? Misalnya, di dalam tindakan redux.Jawaban:
Jika Anda menargetkan lingkungan browser, Anda harus menggunakan
react-router-dom
paket, bukanreact-router
. Mereka mengikuti pendekatan yang sama seperti React, untuk memisahkan inti, (react
) dan kode khusus platform, (react-dom
,react-native
) dengan perbedaan halus yang Anda tidak perlu menginstal dua paket terpisah, sehingga paket lingkungan berisi semuanya kamu membutuhkan. Anda dapat menambahkannya ke proyek Anda sebagai:yarn add react-router-dom
atau
npm i react-router-dom
Hal pertama yang perlu Anda lakukan adalah menyediakan
<BrowserRouter>
komponen induk paling top dalam aplikasi Anda.<BrowserRouter>
menggunakanhistory
API HTML5 dan mengaturnya untuk Anda, jadi Anda tidak perlu khawatir tentang instantiasi sendiri dan meneruskannya ke<BrowserRouter>
komponen sebagai penyangga (seperti yang perlu Anda lakukan di versi sebelumnya).Di V4, untuk bernavigasi secara terprogram Anda perlu mengakses
history
objek, yang tersedia melalui Reactcontext
, selama Anda memiliki komponen<BrowserRouter>
penyedia sebagai orang tua paling top dalam aplikasi Anda. Perpustakaan memperlihatkan melalui konteksrouter
objek, yang berisihistory
sebagai properti. Thehistory
antarmuka menawarkan beberapa metode navigasi, sepertipush
,replace
dangoBack
, antara lain. Anda dapat memeriksa seluruh daftar properti dan metode di sini .Catatan Penting untuk pengguna Redux / Mobx
Jika Anda menggunakan redux atau mobx sebagai pustaka manajemen negara Anda di aplikasi Anda, Anda mungkin telah menemukan masalah dengan komponen yang harus sadar lokasi tetapi tidak dirender kembali setelah memicu pembaruan URLItu terjadi karena
react-router
beralihlocation
ke komponen menggunakan model konteks.2 pendekatan untuk menyelesaikan ini adalah:
<Route />
.location
Objek saat ini adalah salah satu alat peraga yang<Route>
dilewatkan ke komponen yang direndernyawithRouter
tinggi, yang sebenarnya memiliki efek yang sama dan menyuntikkanlocation
sebagai penyanggaSelain itu, ada empat cara untuk bernavigasi secara terprogram, diurutkan berdasarkan rekomendasi:
1.- Menggunakan
Ini mempromosikan gaya deklaratif. Sebelum v4,<Route>
Komponen<Route />
komponen ditempatkan di bagian atas hirarki komponen Anda, harus memikirkan struktur rute Anda sebelumnya. Namun, sekarang Anda dapat memiliki<Route>
komponen di mana saja di pohon Anda, memungkinkan Anda untuk memiliki kontrol yang lebih baik untuk rendering bersyarat tergantung pada URL.Route
menyuntikkanmatch
,location
danhistory
sebagai penyangga ke komponen Anda. Metode navigasi (sepertipush
,replace
,goBack
...) yang tersedia sebagai properti darihistory
objek.Ada 3 cara untuk membuat sesuatu dengan
Route
, dengan menggunakan salah satucomponent
,render
atauchildren
alat peraga, tetapi jangan gunakan lebih dari satu cara yang samaRoute
. Pilihannya tergantung pada kasus penggunaan, tetapi pada dasarnya dua opsi pertama hanya akan membuat komponen Anda jikapath
cocok dengan lokasi url, sedangkan denganchildren
komponen akan ditampilkan apakah jalur cocok dengan lokasi atau tidak (berguna untuk menyesuaikan UI berdasarkan URL) sesuai).Jika Anda ingin menyesuaikan output rendering komponen Anda, Anda perlu membungkus komponen Anda dalam suatu fungsi dan menggunakan
render
opsi, untuk meneruskan ke komponen Anda alat peraga lain yang Anda inginkan, terlepas darimatch
,location
danhistory
. Contoh untuk menggambarkan:2.- Menggunakan
withRouter
HoCKomponen pesanan lebih tinggi ini akan menyuntikkan alat peraga yang sama dengan
Route
. Namun, ia membawa batasan bahwa Anda hanya dapat memiliki 1 HoC per file.3.- Menggunakan
Rendering aRedirect
komponen<Redirect>
akan menavigasi ke lokasi baru. Namun perlu diingat bahwa, secara default , lokasi saat ini diganti dengan yang baru, seperti pengalihan sisi-server (HTTP 3xx). Lokasi baru disediakan olehto
prop, yang bisa berupa string (URL untuk dialihkan ke) ataulocation
objek. Jika Anda ingin memasukkan entri baru ke histori , lewati jugapush
prop dan aturtrue
4.- Mengakses
Sedikit berkecil hati karena konteksnya masih merupakan API eksperimental dan kemungkinan akan pecah / berubah dalam rilis React di masa depanrouter
secara manual melalui konteksTak perlu dikatakan ada juga komponen Router lain yang dimaksudkan untuk ekosistem non browser, seperti
<NativeRouter>
yang mereplikasi tumpukan navigasi dalam memori dan target platform React Native, tersedia melaluireact-router-native
paket.Untuk referensi lebih lanjut, jangan ragu untuk melihat dokumen resmi . Ada juga video yang dibuat oleh salah satu penulis perpustakaan yang memberikan pengantar yang cukup keren untuk bereaksi-router v4, menyoroti beberapa perubahan besar.
sumber
withRouter
darireact-router-dom
withRouter
darireact-router-dom
. History.push memang mengubah url, tetapi sepertinya tidak memuat<Route>
sampai saya memaksakan menyegarkan laman ...<Router>
di dalam komponen Bereaksi yang dihiasi dengan@observer
, yang memicu masalah ini . Pekerjaan di sekitar adalah untuk memiliki@withRouter
pada setiap komponen Bereaksi tersebut.withRouter
hanyalah HOC yang menggunakanRoute
under hood. Yang berarti hanya menggunakan 3 alat peraga, riwayat, kecocokan, dan lokasi . Pada contoh di atas tampak bahwa itupush
adalah prop yangwithRouter
akan ditambahkanButtonToNavigate
, tetapi bukan itu masalahnya.props.history.push
harus digunakan sebagai gantinya. Semoga ini bisa membantu orang lain yang agak bingung.browserHistory.push('/path/some/where')
sepertinya jauh lebih sederhana. Para penulis mencoba untuk mencegah pemrograman imperatif, tetapi kadang-kadang hanya berfungsi lebih baik!Cara termudah untuk menyelesaikannya:
this.props.history.push("/new/url")
catatan:
history
prop
dari komponen induk ke komponen yang ingin Anda panggil tindakan jika tidak tersedia.sumber
this.props.history
tersedia di komponen Anda maka Anda dapatimport {withRouter} from 'react-router-dom'
dan kemudianexport default withRouter(MyComponent)
(atauconst MyComponent = withRouter(...)
) dan itu akan memasukkanhistory
item dalam alat peraga komponen Anda.history.push
dan hanya memicu pembaruan seperti ketika kita mengklik<Link>
Saya memiliki masalah serupa ketika bermigrasi ke React-Router v4 jadi saya akan mencoba menjelaskan solusi saya di bawah ini.
Tolong jangan menganggap jawaban ini sebagai cara yang tepat untuk menyelesaikan masalah, saya membayangkan ada peluang bagus sesuatu yang lebih baik akan muncul karena React Router v4 menjadi lebih matang dan meninggalkan beta (Bahkan mungkin sudah ada dan saya tidak menemukannya) .
Untuk konteks, saya punya masalah ini karena saya kadang-kadang menggunakan
Redux-Saga
untuk mengubah secara terprogram objek sejarah (katakanlah ketika pengguna berhasil mengotentikasi).Dalam dokumen React Router, lihat
<Router>
komponennya dan Anda dapat melihat Anda memiliki kemampuan untuk melewati objek sejarah Anda sendiri melalui alat peraga. Ini adalah inti dari solusi - kami menyediakan objek sejarah untukReact-Router
dari dunia modul.Langkah:
yarn add history
ataunpm install history --save
buat file yang disebut
history.js
diApp.js
folder level Anda (ini adalah preferensi saya)Tambahkan objek riwayat ini ke komponen Router Anda seperti itu
Sesuaikan URL seperti sebelumnya dengan mengimpor objek riwayat global Anda :
Semuanya harus tetap disinkronkan sekarang, dan Anda juga memiliki akses ke cara mengatur objek sejarah secara terprogram dan tidak melalui komponen / wadah.
sumber
Route
komponen.TL; DR:
Jawaban sederhana dan deklaratif adalah bahwa Anda harus menggunakan
<Redirect to={URL} push={boolean} />
dalam kombinasi dengansetState()
Contoh lengkap di sini . Baca lebih lanjut di sini .
PS. Contohnya menggunakan ES7 + Properti Inisialisasi untuk menginisialisasi keadaan. Lihat di sini juga, jika Anda tertarik.
sumber
history.push()
metode.Gunakan
useHistory
kait jika Anda menggunakan komponen fungsiAnda dapat menggunakan
useHistory
kait untuk mendapatkanhistory
contoh.The
useHistory
kait memberikan Anda akses ke contoh sejarah yang mungkin Anda gunakan untuk menavigasi.Gunakan
history
properti di dalam komponen halamanReact Router menyuntikkan beberapa properti termasuk
history
ke komponen halaman.Bungkus komponen anak
withRouter
untuk menyuntikkan properti routerwithRouter
wrapper menyuntikkan properti router ke komponen. Misalnya Anda dapat menggunakan pembungkus ini untuk menyuntikkan router ke komponen tombol logout yang ditempatkan di dalam menu pengguna.sumber
Anda juga bisa menggunakan alat peraga untuk mengakses objek riwayat:
this.props.history.push('new_url')
sumber
this.props.history
tersedia di komponen Anda maka Anda dapatimport {withRouter} from 'react-router-dom'
dan kemudianexport default withRouter(MyComponent)
(atauconst MyComponent = withRouter(...)
) dan itu akan memasukkanhistory
item dalam alat peraga komponen Anda.Langkah 1: Hanya ada satu hal untuk diimpor di atas:
Langkah 2: Di Rute Anda, sampaikan riwayat:
Langkah 3: sejarah diterima sebagai bagian dari alat peraga di Komponen berikutnya, sehingga Anda dapat:
Itu mudah dan sangat kuat.
sumber
Ini bekerja:
sumber
Jawaban saya mirip dengan jawaban Alex . Saya tidak yakin mengapa React-Router membuat ini sangat rumit. Mengapa saya harus membungkus komponen saya dengan HoC hanya untuk mendapatkan akses ke apa yang pada dasarnya global?
Lagi pula, jika Anda melihat bagaimana penerapannya
<BrowserRouter>
, itu hanya pembungkus kecil di sekitar sejarah .Kami dapat menarik sejarah itu sehingga kami dapat mengimpornya dari mana saja. Kuncinya, bagaimanapun, adalah jika Anda melakukan rendering sisi server dan Anda mencoba
import
modul histori, itu tidak akan berhasil karena menggunakan API khusus browser. Tapi tidak apa-apa karena kami biasanya hanya mengarahkan sebagai tanggapan terhadap klik atau acara sisi klien lainnya. Karena itu, boleh saja memalsukannya:Dengan bantuan webpack, kami dapat mendefinisikan beberapa vars sehingga kami tahu di lingkungan mana kita berada:
Dan sekarang kamu bisa
Dari mana-mana. Itu hanya akan mengembalikan modul kosong di server.
Jika Anda tidak ingin menggunakan magic vars ini, Anda hanya perlu berada
require
di objek global yang membutuhkannya (di dalam event handler Anda).import
tidak akan berfungsi karena hanya berfungsi di tingkat atas.sumber
Saya pikir @rgommezz mencakup sebagian besar kasus minus satu yang saya pikir cukup penting.
Ini memungkinkan saya untuk menulis layanan sederhana dengan tindakan / panggilan yang dapat saya panggil untuk melakukan navigasi dari komponen apa pun yang saya inginkan tanpa melakukan banyak HoC pada komponen saya ...
Tidak jelas mengapa tidak ada yang memberikan solusi ini sebelumnya. Saya harap ini membantu, dan jika Anda melihat masalah dengannya, beri tahu saya.
sumber
Saya telah menguji v4 selama beberapa hari sekarang dan .. Saya sangat menyukainya sejauh ini! Masuk akal setelah beberapa saat.
Saya juga memiliki pertanyaan yang sama dan saya menemukan penanganannya seperti yang berikut ini paling berhasil (dan bahkan mungkin seperti yang dimaksudkan). Ini menggunakan negara, operator ternary dan
<Redirect>
.Dalam konstruktor ()
Di render ()
Di clickhandler ()
Semoga ini bisa membantu. Biarkan aku tahu.
sumber
Saya berjuang dengan ini untuk sementara waktu - sesuatu yang sangat sederhana, namun sangat rumit, karena ReactJS hanyalah cara penulisan aplikasi web yang benar-benar berbeda, itu sangat asing bagi kami orang yang lebih tua!
Saya membuat komponen terpisah untuk abstrak kekacauan:
Kemudian tambahkan ke
render()
metode Anda :sumber
Karena tidak ada cara lain untuk menangani desain yang mengerikan ini, saya menulis komponen generik yang menggunakan pendekatan
withRouter
HOC . Contoh di bawah ini adalah membungkusbutton
elemen, tetapi Anda dapat mengubah ke elemen yang dapat diklik yang Anda butuhkan:Pemakaian:
sumber
Jika Anda belum menemukan this.props.history tersedia di komponen Anda, maka coba ini
sumber
Karena kadang-kadang saya lebih suka beralih rute dengan Aplikasi daripada dengan tombol, ini adalah contoh kerja minimal yang berfungsi untuk saya:
sumber
Bagi Anda yang perlu mengarahkan ulang sebelum sepenuhnya menginisialisasi router menggunakan
React Router
atauReact Router Dom
Anda dapat memberikan redirect dengan hanya mengakses objek sejarah dan mendorong negara baru ke dalamnya dalam konstruk Andaapp.js
. Pertimbangkan yang berikut ini:Di sini kami ingin mengubah Rute keluaran bergantung pada subdomain, dengan berinteraksi dengan objek riwayat sebelum komponen merender, kami dapat mengarahkan secara efektif sambil tetap meninggalkan rute kami dengan bijaksana.
sumber