️ Dokumen ini hanya untuk Wouter V3. Silakan temukan dokumentasi untuk [email protected] di sini
<Router /> tingkat atas, ini sepenuhnya opsional .Route , Link , Switch dan Redirect yang akrab.useLocation , useRoute dan useRouter . ... Saya suka wouter. Ini kecil, sepenuhnya memeluk kait, dan memiliki API intuitif dan barebones. Saya dapat mencapai semua yang saya bisa dengan react-router dengan Wouter, dan itu hanya terasa lebih minimalis sementara tidak tidak nyaman.
Matt Miller , ekosistem bereaksi lengkap untuk tahun 2020
Wouter menyediakan API sederhana yang dihargai banyak pengembang dan penulis perpustakaan. Beberapa proyek penting yang menggunakan Wouter: Ultra , React-Three-Fiber , Sunmao UI , Million dan banyak lagi.
Memulai
Wouter API
Hooks API
useRoute : pencocokan rute dan parameteruseLocation : Bekerja dengan SejarahuseParams : mengekstraksi parameter yang cocokuseSearch : String kueriuseRouter : Mengakses Objek RouterAPI Komponen
<Route path={pattern} /><Link href={path} /><Switch /><Redirect to={path} /><Router hook={hook} parser={fn} base={basepath} />Resep FAQ dan kode
Ucapan Terima Kasih
Pertama, tambahkan wouter ke proyek Anda.
npm i wouter Atau, jika Anda menggunakan preact penggunaan perintah berikut npm i wouter-preact .
Lihat aplikasi demo sederhana ini di bawah ini. Itu tidak mencakup kait dan fitur lain seperti routing bersarang, tetapi ini adalah titik awal yang baik bagi mereka yang bermigrasi dari reaksi router.
import { Link , Route , Switch } from "wouter" ;
const App = ( ) => (
< >
< Link href = "/users/1" > Profile </ Link >
< Route path = "/about" > About Us </ Route >
{ /*
Routes below are matched exclusively -
the first matched route gets rendered
*/ }
< Switch >
< Route path = "/inbox" component = { InboxPage } />
< Route path = "/users/:name" >
{ ( params ) => < > Hello, { params . name } ! </ > }
</ Route >
{ /* Default route in a switch */ }
< Route > 404: No such page! </ Route >
</ Switch >
</ >
) ; Perpustakaan ini dirancang untuk kompatibilitas ES2020+ . Jika Anda perlu mendukung browser yang lebih lama, pastikan Anda mentranspile node_modules . Selain itu, versi TypeScript minimum yang didukung adalah 4.1 untuk mendukung inferensi parameter rute.
Wouter hadir dengan tiga jenis API: kait lokasi mandiri tingkat rendah, kait untuk routing dan pencocokan pola dan API berbasis komponen yang lebih tradisional mirip dengan React Router.
Anda bebas memilih apa pun yang cocok untuk Anda: Gunakan kait lokasi ketika Anda ingin menjaga aplikasi Anda sekecil mungkin dan tidak perlu pencocokan pola; Gunakan kait perutean saat Anda ingin membangun komponen perutean khusus; Atau jika Anda membangun aplikasi tradisional dengan halaman dan navigasi - komponen mungkin berguna.
Lihat juga resep FAQ dan kode untuk hal-hal yang lebih canggih seperti tautan aktif, rute default, rendering sisi server dll.
Kait lokasi
Ini dapat digunakan secara terpisah dari modul utama dan memiliki antarmuka yang mirip dengan useState . Kait ini tidak mendukung sarang, jalur dasar, pencocokan rute.
import { useBrowserLocation } from "wouter/use-browser-location" -memungkinkan untuk memanipulasi lokasi saat ini di bilah alamat browser, pembungkus kecil di sekitar API sejarah.import { useHashLocation } from "wouter/use-hash-location" -Demikian pula, mendapat lokasi dari bagian hash dari alamat, yaitu string setelah # .import { memoryLocation } from "wouter/memory-location" -kait lokasi dalam memori dengan dukungan riwayat, navigasi eksternal, dan mode abadi untuk pengujian. Perhatikan nama modul karena ini adalah kait orde tinggi. Lihat bagaimana lokasi memori dapat digunakan dalam pengujian.Routing hooks
Impor dari modul wouter .
useRoute - menunjukkan apakah halaman saat ini cocok dengan pola yang disediakan atau tidak.useLocation - memungkinkan untuk memanipulasi lokasi router saat ini, secara default berlangganan lokasi browser. Catatan: Ini tidak sama dengan useBrowserLocation , baca di bawah ini.useParams - Mengembalikan objek dengan parameter yang cocok dari rute terdekat.useSearch - Mengembalikan string pencarian - semua yang terjadi setelah ? .useRouter - Mengembalikan objek router global yang memegang konfigurasi. Hanya gunakan jika Anda ingin menyesuaikan perutean.Komponen
Impor dari modul wouter .
<Route /> - secara kondisional membuat komponen berdasarkan pola.<Link /> - wraps <a> , memungkinkan untuk memperparah navigasi.<Switch /> - Routing eksklusif, hanya membuat rute yang cocok pertama.<Redirect /> - Ketika diberikan, melakukan navigasi langsung.<Router /> -Komponen tingkat atas opsional untuk konfigurasi routing lanjutan. useRoute : pencocokan rute dan parameter Periksa apakah lokasi saat ini cocok dengan pola yang disediakan dan mengembalikan objek dengan parameter. Ini ditenagai oleh perpustakaan regexparam yang indah, sehingga semua sintaks polanya didukung sepenuhnya.
Anda dapat menggunakan useRoute untuk melakukan routing manual atau mengimplementasikan logika khusus, seperti transisi rute, dll.
import { useRoute } from "wouter" ;
const Users = ( ) => {
// `match` is a boolean
const [ match , params ] = useRoute ( "/users/:name" ) ;
if ( match ) {
return < > Hello, { params . name } ! </ > ;
} else {
return null ;
}
} ;Lembar cheat cepat dari jenis segmen apa yang didukung:
useRoute ( "/app/:page" ) ;
useRoute ( "/app/:page/:section" ) ;
// optional parameter, matches "/en/home" and "/home"
useRoute ( "/:locale?/home" ) ;
// suffixes
useRoute ( "/movies/:title.(mp4|mov)" ) ;
// wildcards, matches "/app", "/app-1", "/app/home"
useRoute ( "/app*" ) ;
// optional wildcards, matches "/orders", "/orders/"
// and "/orders/completed/list"
useRoute ( "/orders/*?" ) ;
// regex for matching complex patterns,
// matches "/hello:123"
useRoute ( / ^[/]([a-z]+):([0-9]+)[/]?$ / ) ;
// and with named capture groups
useRoute ( / ^[/](?<word>[a-z]+):(?<num>[0-9]+)[/]?$ / ) ; Item kedua dalam pasangan params adalah objek dengan parameter atau nol jika tidak ada kecocokan. Untuk segmen wildcard, nama parameter adalah "*" :
// wildcards, matches "/app", "/app-1", "/app/home"
const [ match , params ] = useRoute ( "/app*" ) ;
if ( match ) {
// "/home" for "/app/home"
const page = params [ "*" ] ;
}useLocation : Bekerja dengan Sejarah Untuk mendapatkan jalur saat ini dan menavigasi antar halaman, hubungi Hook useLocation . Demikian pula dengan useState , ia mengembalikan nilai dan setter: Komponen akan membuat ulang ketika lokasi berubah dan dengan menelepon navigate Anda dapat memperbarui nilai ini dan melakukan navigasi.
Secara default, menggunakan useBrowserLocation di bawah kap, meskipun Anda dapat mengonfigurasi ini dalam komponen Router tingkat atas (misalnya, jika Anda memutuskan pada suatu titik untuk beralih ke perutean berbasis hash). useLocation juga akan mengembalikan jalur cakupan saat digunakan dalam rute bersarang atau dengan pengaturan jalur dasar.
import { useLocation } from "wouter" ;
const CurrentLocation = ( ) => {
const [ location , navigate ] = useLocation ( ) ;
return (
< div >
{ `The current page is: ${ location } ` }
< a onClick = { ( ) => navigate ( "/somewhere" ) } > Click to update </ a >
</ div >
) ;
} ; Semua komponen secara internal memanggil hook useLocation .
Metode setter useLocation juga dapat menerima objek opsional dengan parameter untuk mengontrol bagaimana pembaruan navigasi akan terjadi.
Ketika lokasi browser digunakan (default), hook useLocation menerima flag replace untuk memberi tahu kait untuk memodifikasi entri riwayat saat ini alih -alih menambahkan yang baru. Itu sama dengan memanggil replaceState .
const [ location , navigate ] = useLocation ( ) ;
navigate ( "/jobs" ) ; // `pushState` is used
navigate ( "/home" , { replace : true } ) ; // `replaceState` is used Selain itu, Anda dapat memberikan opsi state untuk memperbarui history.state saat menavigasi:
navigate ( "/home" , { state : { modal : "promo" } } ) ;
history . state ; // { modal: "promo" } Secara default, Wouter menggunakan hook useLocation yang bereaksi terhadap navigasi pushState dan replaceState navigasi melalui useBrowserLocation .
Untuk menyesuaikan ini, bungkus aplikasi Anda dalam komponen Router :
import { Router , Route } from "wouter" ;
import { useHashLocation } from "wouter/use-hash-location" ;
const App = ( ) => (
< Router hook = { useHashLocation } >
< Route path = "/about" component = { About } />
...
</ Router >
) ; Karena kait ini memiliki nilai pengembalian yang mirip dengan useState , mudah dan menyenangkan untuk membangun kait lokasi Anda sendiri: useCrossTabLocation , useLocalStorage , useMicroFrontendLocation dan logika perutean apa pun yang ingin Anda dukung di aplikasi. Cobalah!
useParams : mengekstraksi parameter yang cocok Pengait ini memungkinkan Anda untuk mengakses parameter yang terpapar melalui segmen dinamis yang cocok. Secara internal, kami cukup membungkus komponen Anda dalam penyedia konteks yang memungkinkan Anda untuk mengakses data ini di mana saja dalam komponen Route .
Ini memungkinkan Anda untuk menghindari "pengeboran prop" saat berhadapan dengan komponen yang sangat bersarang di dalam rute. Catatan: useParams hanya akan mengekstraksi parameter dari rute induk terdekat.
import { Route , useParams } from "wouter" ;
const User = ( ) => {
const params = useParams ( ) ;
params . id ; // "1"
// alternatively, use the index to access the prop
params [ 0 ] ; // "1"
} ;
< Route path = "/user/:id" component = { User } > / >Itu sama untuk jalur regex. Grup Capture dapat diakses dengan indeksnya, atau jika ada grup penangkapan bernama, yang dapat digunakan sebagai gantinya.
import { Route , useParams } from "wouter" ;
const User = ( ) => {
const params = useParams ( ) ;
params . id ; // "1"
params [ 0 ] ; // "1"
} ;
< Route path = { / ^[/]user[/](?<id>[0-9]+)[/]?$ / } component = { User } > / >useSearch : String kueri Gunakan kait ini untuk mendapatkan nilai string pencarian (kueri) saat ini. Ini akan menyebabkan komponen Anda hanya menanamkan kembali ketika string itu sendiri dan bukan pembaruan lokasi lengkap. String pencarian yang dikembalikan tidak mengandung ? karakter.
import { useSearch } from "wouter" ;
// returns "tab=settings&id=1"
// the hook for extracting search parameters is coming soon!
const searchString = useSearch ( ) ; Untuk SSR, gunakan prop ssrSearch yang diteruskan ke router.
< Router ssrSearch = { request . search } > { /* SSR! */ } </ Router >Lihat rendering sisi server untuk info lebih lanjut tentang rendering dan hidrasi.
useRouter : Mengakses Objek Router Jika Anda membangun integrasi canggih, misalnya kait lokasi khusus, Anda mungkin ingin mendapatkan akses ke objek router global. Router adalah objek sederhana yang memiliki opsi perutean yang Anda konfigurasi di komponen Router .
import { useRouter } from "wouter" ;
const Custom = ( ) => {
const router = useRouter ( ) ;
router . hook ; // `useBrowserLocation` by default
router . base ; // "/app"
} ;
const App = ( ) => (
< Router base = "/app" >
< Custom />
</ Router >
) ; <Route path={pattern} /> Route mewakili bagian dari aplikasi yang diterjemahkan secara kondisional berdasarkan path pola. Pola memiliki sintaks yang sama dengan argumen yang Anda berikan kepada useRoute .
Perpustakaan menyediakan banyak cara untuk mendeklarasikan tubuh rute:
import { Route } from "wouter" ;
// simple form
< Route path = "/home" > < Home /> </ Route >
// render-prop style
< Route path = "/users/:id" >
{ params => < UserPage id = { params . id } /> }
</ Route >
// the `params` prop will be passed down to <Orders />
< Route path = "/orders/:status" component = { Orders } /> Rute tanpa jalur dianggap selalu cocok, dan itu sama dengan <Route path="*" /> . Saat mengembangkan aplikasi Anda, gunakan trik ini untuk mengintip konten rute tanpa navigasi.
- <Route path="/some/page">
+ <Route>
{/* Strip out the `path` to make this visible */}
</Route> Nesting adalah fitur inti dari Wouter dan dapat diaktifkan pada rute melalui nest Prop. Ketika prop ini hadir, rute cocok dengan segala sesuatu yang dimulai dengan pola yang diberikan dan menciptakan konteks perutean bersarang. Semua rute anak akan menerima lokasi relatif terhadap pola itu.
Mari kita lihat contoh ini:
< Route path = "/app" nest >
< Route path = "/users/:id" nest >
< Route path = "/orders" />
</ Route >
</ Route > Rute pertama ini akan aktif untuk semua jalur yang dimulai dengan /app , ini setara dengan memiliki jalur dasar di aplikasi Anda.
Yang kedua menggunakan pola dinamis untuk mencocokkan jalur seperti /app/user/1 , /app/user/1/anything dan sebagainya.
Akhirnya, rute paling dalam hanya akan bekerja untuk jalur yang terlihat seperti /app/users/1/orders . Pertandingannya ketat, karena rute itu tidak memiliki prop nest dan berfungsi seperti biasa.
Jika Anda menghubungi useLocation() di dalam rute terakhir, itu akan kembali /orders dan bukan /app/users/1/orders . Ini menciptakan isolasi yang bagus dan membuatnya lebih mudah untuk membuat perubahan pada rute orang tua tanpa khawatir bahwa sisa aplikasi akan berhenti bekerja. Namun, jika Anda perlu menavigasi ke halaman tingkat atas, Anda dapat menggunakan awalan ~ untuk merujuk ke jalur absolut:
< Route path = "/payments" nest >
< Route path = "/all" >
< Link to = "~/home" > Back to Home </ Link >
</ Route >
</ Route > Catatan: Prop nest tidak mengubah regex yang diteruskan ke jalur regex. Sebaliknya, nest prop hanya akan menentukan apakah rute bersarang akan cocok dengan sisa jalur atau jalur yang sama. Untuk membuat jalur yang ketat Regex, gunakan pola regex seperti /^[/](your pattern)[/]?$/ (Ini cocok dengan slash ujung opsional dan ujung string). Untuk membuat regex sarang, gunakan pola regex seperti /^[/](your pattern)(?=$|[/])/ (Ini cocok dengan akhir dari string atau slash untuk segmen masa depan).
<Link href={path} /> Komponen tautan membuat elemen <a /> yang, saat diklik, melakukan navigasi.
import { Link } from "wouter"
< Link href = "/" > Home </ Link >
// `to` is an alias for `href`
< Link to = "/" > Home < / Link>
// all standard `a` props are proxied
< Link href = "/" className = "link" aria-label = "Go to homepage" > Home </ Link >
// all location hook options are supported
< Link href = "/" replace state = { { animate : true } } / > Tautan akan selalu membungkus anak -anaknya dalam tag <a /> , kecuali jika asChild prop disediakan. Gunakan ini ketika Anda perlu memiliki komponen khusus yang membuat <a /> di bawah kap.
// use this instead
< Link to = "/" asChild >
< UIKitLink />
</ Link >
// Remember, `UIKitLink` must implement an `onClick` handler
// in order for navigation to work! Ketika Anda melewati suatu fungsi sebagai penyangga className , itu akan dipanggil dengan nilai boolean yang menunjukkan apakah tautan aktif untuk rute saat ini. Anda dapat menggunakan ini untuk menata tautan aktif (misalnya untuk tautan di menu navigasi)
< Link className = { ( active ) => ( active ? "active" : "" ) } > Nav </ Link >Baca lebih lanjut tentang tautan aktif di sini.
<Switch /> Ada kasus ketika Anda ingin memiliki perutean eksklusif: untuk memastikan bahwa hanya satu rute yang ditampilkan pada saat itu, bahkan jika rute memiliki pola yang tumpang tindih. Itulah yang dilakukan Switch : Ini hanya membuat rute pencocokan pertama .
import { Route , Switch } from "wouter" ;
< Switch >
< Route path = "/orders/all" component = { AllOrders } />
< Route path = "/orders/:status" component = { Orders } />
{ /*
in wouter, any Route with empty path is considered always active.
This can be used to achieve "default" route behaviour within Switch.
Note: the order matters! See examples below.
*/ }
< Route > This is rendered when nothing above has matched </ Route >
</ Switch > ; Ketika tidak ada rute di Switch Matches, Route kosong terakhir akan digunakan sebagai fallback. Lihat bagian resep FAQ dan kode untuk dibaca tentang rute default.
<Redirect to={path} /> Saat dipasang melakukan pengalihan ke path yang disediakan. Menggunakan Hook useLocation secara internal untuk memicu navigasi di dalam blok useEffect .
Redirect juga dapat menerima alat peraga untuk menyesuaikan bagaimana navigasi akan dilakukan, misalnya untuk menetapkan keadaan sejarah saat menavigasi. Opsi ini khusus untuk kait lokasi yang saat ini digunakan.
< Redirect to = "/" />
// arbitrary state object
< Redirect to = "/" state = { { modal : true } } / >
// use `replaceState`
< Redirect to = "/" replace /> Jika Anda memerlukan logika yang lebih canggih untuk navigasi, misalnya, untuk memicu pengalihan di dalam penangan event, pertimbangkan untuk menggunakan hook useLocation sebagai gantinya:
import { useLocation } from "wouter" ;
const [ location , setLocation ] = useLocation ( ) ;
fetchOrders ( ) . then ( ( orders ) => {
setOrders ( orders ) ;
setLocation ( "/app/orders" ) ;
} ) ;<Router hook={hook} parser={fn} base={basepath} hrefs={fn} />Tidak seperti React Router , rute di Wouter tidak harus dibungkus dengan komponen tingkat atas . Objek router internal akan dibangun sesuai permintaan, sehingga Anda dapat mulai menulis aplikasi Anda tanpa mencemari dengan kaskade penyedia tingkat atas. Namun ada kasus, ketika perilaku perutean perlu disesuaikan.
Kasus-kasus ini termasuk perutean berbasis hash, dukungan basepath, fungsi pencocokan khusus dll.
import { useHashLocation } from "wouter/use-hash-location" ;
< Router hook = { useHashLocation } base = "/app" >
{ /* Your app goes here */ }
</ Router > ; Router adalah objek sederhana yang menahan opsi konfigurasi perutean. Anda selalu dapat memperoleh objek ini menggunakan kait useRouter . Daftar opsi yang tersedia saat ini:
hook: () => [location: string, setLocation: fn] - adalah fungsi react hook yang berlangganan perubahan lokasi. Ini mengembalikan sepasang string location saat ini EG /app/users dan fungsi setLocation untuk navigasi. Anda dapat menggunakan kait ini dari komponen aplikasi apa pun dengan memanggil hook useLocation() . Lihat Menyesuaikan kait lokasi.
searchHook: () => [search: string, setSearch: fn] - Mirip dengan hook , tetapi untuk mendapatkan string pencarian saat ini.
base: string - Pengaturan opsional yang memungkinkan untuk menentukan jalur dasar, seperti /app . Semua rute aplikasi akan relatif terhadap jalur itu. Untuk menavigasi ke jalur absolut, awalkan jalan Anda dengan ~ . Lihat FAQ.
parser: (path: string, loose?: boolean) => { pattern, keys } - fungsi parsing pola. Menghasilkan regexp untuk mencocokkan lokasi saat ini dengan pola yang ditentukan pengguna seperti /app/users/:id . Memiliki antarmuka yang sama dengan fungsi parse dari regexparam . Lihat contoh ini yang menunjukkan fitur parser khusus.
ssrPath: string dan ssrSearch: string Gunakan ini saat merender aplikasi Anda di server.
hrefs: (href: boolean) => string - fungsi untuk mengubah atribut href dari elemen <a /> yang diberikan oleh Link . Ini digunakan untuk mendukung perutean berbasis hash. Secara default, atribut href sama dengan href atau to Link . Hook lokasi juga dapat menentukan properti hook.hrefs , dalam hal ini href akan disimpulkan.
Anda bisa! Bungkus aplikasi Anda dengan komponen <Router base="/app" /> dan itu harus melakukan trik:
import { Router , Route , Link } from "wouter" ;
const App = ( ) => (
< Router base = "/app" >
{ /* the link's href attribute will be "/app/users" */ }
< Link href = "/users" > Users </ Link >
< Route path = "/users" > The current path is /app/users! </ Route >
</ Router >
) ; Memanggil useLocation() dalam rute di aplikasi dengan jalur dasar akan mengembalikan jalur yang dilingkari ke pangkalan. Berarti bahwa ketika basis adalah "/app" dan pathname adalah "/app/users" string yang dikembalikan adalah "/users" . Dengan demikian, Calling navigate akan secara otomatis menambahkan pangkalan ke argumen jalur untuk Anda.
Ketika Anda memiliki beberapa router bersarang, jalur dasar diwarisi dan ditumpuk.
< Router base = "/app" >
< Router base = "/cms" >
< Route path = "/users" > Path is /app/cms/users! </ Route >
</ Router >
</ Router > Salah satu pola umum dalam perutean aplikasi adalah memiliki rute default yang akan ditampilkan sebagai fallback, jika tidak ada rute lain yang cocok (misalnya, jika Anda perlu membuat pesan 404). Di Wouter ini dapat dengan mudah dilakukan sebagai kombinasi komponen <Switch /> dan rute default:
import { Switch , Route } from "wouter" ;
< Switch >
< Route path = "/about" > ... </ Route >
< Route > 404, Not Found! </ Route >
</ Switch > ;Catatan: Urutan sakelar anak -anak penting, rute default harus selalu datang terakhir.
Jika Anda ingin memiliki akses ke segmen jalur yang cocok, Anda dapat menggunakan parameter wildcard:
< Switch >
< Route path = "/users" > ... </ Route >
{ /* will match anything that starts with /users/, e.g. /users/foo, /users/1/edit etc. */ }
< Route path = "/users/*" > ... </ Route >
{ /* will match everything else */ }
< Route path = "*" >
{ ( params ) => `404, Sorry the page ${ params [ "*" ] } does not exist!` }
</ Route >
</ Switch >▶ Demo Sandbox
Alih -alih string className reguler, berikan fungsi untuk menggunakan kelas khusus ketika tautan ini cocok dengan rute saat ini. Perhatikan bahwa itu akan selalu melakukan kecocokan yang tepat (IE /users tidak akan aktif untuk /users/1 ).
< Link className = { ( active ) => ( active ? "active" : "" ) } > Nav link </ Link > Jika Anda perlu mengontrol alat peraga lain, seperti aria-current atau style , Anda dapat menulis sendiri <Link /> wrapper Anda dan mendeteksi jika jalurnya aktif dengan menggunakan hook useRoute .
const [ isActive ] = useRoute ( props . href ) ;
return (
< Link { ... props } asChild >
< a style = { isActive ? { color : "red" } : { } } > { props . children } </ a >
</ Link >
) ;▶ Demo Sandbox
Jika slash trailing penting untuk perutean aplikasi Anda, Anda dapat menentukan parser khusus. Parser adalah metode yang mengambil string pola dan mengembalikan regexp dan array kunci parsed. Ini menggunakan tanda tangan fungsi parse dari regexparam .
Mari kita tulis parser khusus berdasarkan paket path-to-regexp yang populer yang mendukung opsi rute yang ketat.
import { pathToRegexp } from "path-to-regexp" ;
/**
* Custom parser based on `pathToRegexp` with strict route option
*/
const strictParser = ( path , loose ) => {
const keys = [ ] ;
const pattern = pathToRegexp ( path , keys , { strict : true , end : ! loose } ) ;
return {
pattern ,
// `pathToRegexp` returns some metadata about the keys,
// we want to strip it to just an array of keys
keys : keys . map ( ( k ) => k . name ) ,
} ;
} ;
const App = ( ) => (
< Router parser = { strictParser } >
< Route path = "/foo" > ... </ Route >
< Route path = "/foo/" > ... </ Route >
</ Router >
) ;▶ Demo Sandbox
Ya! Rute apa pun dengan prop nest yang ada menciptakan konteks bersarang. Perlu diingat, bahwa lokasi di dalam rute bersarang akan dilingkupi.
const App = ( ) => (
< Router base = "/app" >
< Route path = "/dashboard" nest >
{ /* the href is "/app/dashboard/users" */ }
< Link to = "/users" />
< Route path = "/users" >
{ /* Here `useLocation()` returns "/users"! */ }
</ Route >
</ Route >
</ Router >
) ;▶ Demo Sandbox
Ya, fungsi navigate diekspos dari modul "wouter/use-browser-location" :
import { navigate } from "wouter/use-browser-location" ;
navigate ( "/" , { replace : true } ) ;Ini adalah fungsi yang sama yang digunakan secara internal.
Ya! Meskipun proyek tidak ditulis dalam TypeScript, file definisi tipe dibundel dengan paket.
Mari kita lihat bagaimana rute wouter dapat dianimasikan dengan framer-motion . Animating Enter Transitions mudah, tetapi transisi keluar membutuhkan sedikit lebih banyak pekerjaan. Kami akan menggunakan komponen AnimatePresence yang akan menyimpan halaman di DOM sampai animasi keluar selesai.
Sayangnya, AnimatePresence hanya menjiwai anak -anak langsungnya , jadi ini tidak akan berhasil:
import { motion , AnimatePresence } from "framer-motion" ;
export const MyComponent = ( ) => (
< AnimatePresence >
{ /* This will not work! `motion.div` is not a direct child */ }
< Route path = "/" >
< motion . div
initial = { { opacity : 0 } }
animate = { { opacity : 1 } }
exit = { { opacity : 0 } }
/>
</ Route >
</ AnimatePresence >
) ; Solusi adalah untuk mencocokkan rute ini secara manual dengan useRoute :
export const MyComponent = ( { isVisible } ) => {
const [ isMatch ] = useRoute ( "/" ) ;
return (
< AnimatePresence >
{ isMatch && (
< motion . div
initial = { { opacity : 0 } }
animate = { { opacity : 1 } }
exit = { { opacity : 0 } }
/>
) }
</ AnimatePresence >
) ;
} ; Contoh yang lebih kompleks melibatkan penggunaan hook useRoutes (mirip dengan bagaimana reaksi router melakukannya), tetapi Wouter tidak mengirimkannya di luar kotak. Silakan merujuk masalah ini untuk solusi.
Ekspor Preact tersedia melalui paket terpisah bernama wouter-preact (atau di dalam namespace wouter/preact , namun metode ini tidak disarankan karena membutuhkan reaksi sebagai ketergantungan rekan):
- import { useRoute, Route, Switch } from "wouter";
+ import { useRoute, Route, Switch } from "wouter-preact";Anda mungkin perlu memastikan Anda memiliki versi terbaru Preact X dengan dukungan untuk kait.
▶ Demo Sandbox
Untuk membuat aplikasi Anda di server, Anda harus membungkus aplikasi Anda dengan router tingkat atas dan menentukan prop ssrPath (biasanya, berasal dari permintaan saat ini). Secara opsional, Router menerima parameter ssrSearch jika perlu memiliki akses ke string pencarian di server.
import { renderToString } from "react-dom/server" ;
import { Router } from "wouter" ;
const handleRequest = ( req , res ) => {
// top-level Router is mandatory in SSR mode
const prerendered = renderToString (
< Router ssrPath = { req . path } ssrSearch = { req . search } >
< App />
</ Router >
) ;
// respond with prerendered html
} ; Tip: Wouter dapat mengisi ssrSearch , jika ssrPath berisi ? karakter. Jadi ini setara:
< Router ssrPath = "/goods?sort=asc" /> ;
// is the same as
< Router ssrPath = "/goods" ssrSearch = "sort=asc" /> ; Pada klien, markup statis harus terhidrasi agar aplikasi Anda menjadi interaktif. Perhatikan bahwa untuk menghindari peringatan hidrasi, JSX yang diberikan pada klien harus cocok dengan yang digunakan oleh server, sehingga komponen Router harus ada.
import { hydrateRoot } from "react-dom/client" ;
const root = hydrateRoot (
domNode ,
// during hydration, `ssrPath` is set to `location.pathname`,
// `ssrSearch` set to `location.search` accordingly
// so there is no need to explicitly specify them
< Router >
< App />
</ Router >
) ;▶ Demo
Pengujian dengan Wouter tidak berbeda dengan menguji aplikasi React reguler. Anda sering membutuhkan cara untuk menyediakan perlengkapan untuk lokasi saat ini untuk membuat rute tertentu. Ini dapat dengan mudah dilakukan dengan menukar kait lokasi normal dengan memoryLocation . Ini adalah fungsi inisialisasi yang mengembalikan kait yang kemudian dapat Anda tentukan dalam Router tingkat atas.
import { render } from "@testing-library/react" ;
import { memoryLocation } from "wouter/memory-location" ;
it ( "renders a user page" , ( ) => {
// `static` option makes it immutable
// even if you call `navigate` somewhere in the app location won't change
const { hook } = memoryLocation ( { path : "/user/2" , static : true } ) ;
const { container } = render (
< Router hook = { hook } >
< Route path = "/user/:id" > { ( params ) => < > User ID: { params . id } </ > } </ Route >
</ Router >
) ;
expect ( container . innerHTML ) . toBe ( "User ID: 2" ) ;
} ) ; Kait dapat dikonfigurasi untuk merekam riwayat navigasi. Selain itu, ia dilengkapi dengan fungsi navigate untuk navigasi eksternal.
it ( "performs a redirect" , ( ) => {
const { hook , history , navigate } = memoryLocation ( {
path : "/" ,
// will store navigation history in `history`
record : true ,
} ) ;
const { container } = render (
< Router hook = { hook } >
< Switch >
< Route path = "/" > Index </ Route >
< Route path = "/orders" > Orders </ Route >
< Route >
< Redirect to = "/orders" />
</ Route >
</ Switch >
</ Router >
) ;
expect ( history ) . toStrictEqual ( [ "/" ] ) ;
navigate ( "/unknown/route" ) ;
expect ( container . innerHTML ) . toBe ( "Orders" ) ;
expect ( history ) . toStrictEqual ( [ "/" , "/unknown/route" , "/orders" ] ) ;
} ) ; Kami punya kabar baik untuk Anda! Jika Anda seorang pengembara ukuran bundel minimalis dan Anda memerlukan perutean sederhana di aplikasi Anda, Anda bisa menggunakan kait lokasi telanjang. Misalnya, useBrowserLocation Hook yang hanya 650 byte Gzipped dan secara manual cocok dengan lokasi saat ini:
import { useBrowserLocation } from "wouter/use-browser-location" ;
const UsersRoute = ( ) => {
const [ location ] = useBrowserLocation ( ) ;
if ( location !== "/users" ) return null ;
// render the route
} ;Moto Wouter adalah "ramah minimalis" .
Ilustrasi wouter dan logo dibuat oleh Katya Simacheva dan Katya Vakulenko. Terima kasih untuk @jeetiss dan semua kontributor luar biasa untuk membantu perkembangannya.