React Router
React Router
Installation ................................................................................................................................................ 0
Routers ........................................................................................................................................................ 5
Code Splitting............................................................................................................................................ 15
Philosophy .................................................................................................................................................... 21
BackStory.................................................................................................................................................22
Testing ........................................................................................................................................................... 29
Context ..................................................................................................................................................... 29
i
Starting at specific routes .......................................................................................................... 30
Navigating ............................................................................................................................................. 30
Hooks.............................................................................................................................................................. 36
useHistory............................................................................................................................................... 36
useLocation .......................................................................................................................................... 36
useParams .............................................................................................................................................37
useRouteMatch .................................................................................................................................. 38
<BrowserRouter> .................................................................................................................................... 40
getUserConfirmation: func......................................................................................................... 40
Children: node...................................................................................................................................... 41
<HashRouter> ........................................................................................................................................... 42
getUserConfirmation: function................................................................................................ 42
Children: node..................................................................................................................................... 43
<Link> .............................................................................................................................................................. 44
to: function............................................................................................................................................. 44
ii
innerRef: RefObject .......................................................................................................................... 45
Others ....................................................................................................................................................... 46
<NavLink> ..................................................................................................................................................... 47
location: object................................................................................................................................... 48
<Prompt> ..................................................................................................................................................... 50
<MemoryRouter> ..................................................................................................................................... 51
initialIndex: number.......................................................................................................................... 51
getUserConfirmation: function................................................................................................. 51
Children: node..................................................................................................................................... 52
<Redirect> ................................................................................................................................................... 53
to String ................................................................................................................................................... 53
sensitive: boolean............................................................................................................................. 55
<Route> ......................................................................................................................................................... 56
iii
component ........................................................................................................................................... 57
render: function.................................................................................................................................. 58
location: object................................................................................................................................... 62
sensitive: boolean............................................................................................................................. 62
<Router> ....................................................................................................................................................... 63
Children: node..................................................................................................................................... 64
<StaticRouter> .......................................................................................................................................... 65
location: object................................................................................................................................... 66
Children: node..................................................................................................................................... 67
<Switch> ....................................................................................................................................................... 68
location: object................................................................................................................................... 69
generatePath ............................................................................................................................................. 71
Params: object...................................................................................................................................... 71
History ............................................................................................................................................................. 72
History is mutable..............................................................................................................................73
Location ........................................................................................................................................................ 74
Match ............................................................................................................................................................. 76
iv
matchPath ................................................................................................................................................. 78
pathname .............................................................................................................................................. 78
props ......................................................................................................................................................... 78
returns ...................................................................................................................................................... 78
withRouter................................................................................................................................................... 80
Component.WrappedComponent........................................................................................ 81
v
Dokumentasi React Router Dom Web
https://reactrouter.com/web/
Quick Start
Untuk memulai dengan React Router di sebuah aplikasi web, anda akan
perlu sebuah aplikasi React web. Jika anda perlu untuk membuatnya.
Kami merekomendasikan anda mencoba Create React App. Create React
App adalah sebuah alat populer yang bekerja sangat baik dengan React
Router.
Installation
Anda dapat install React Router dari the public npm registry dengan npm
atau yarn. Karena kita membangun sebuah aplikasi web, kita akan
menggunakan `react-router-dom` di panduan ini.
lalu, salin / tempel salah satu dari contoh berikut ke dalam `src/App.js`.
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Users() {
1
return <h2>Users</h2>;
}
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/topics">
<Topics />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
2
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Topics() {
let match = useRouteMatch();
return (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/components`}>Components</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
function Topic() {
let { topicId } = useParams();
return <h3>Requested topic ID: {topicId}</h3>;
}
3
Keep Going!
Semoga contoh ini memberi anda sebuah rasa seperti apa nampaknya
membuat sebuah aplikasi web dengan React Router. Lanjutkan membaca
lebih banyak tentang komponen utama di React Router!.
4
Primay Components
Ada tiga jenis komponen utama di React Router:
Semua komponen yang anda gunakan di sebuah aplikasi web harus telah
diimpor dari `react-router-dom`.
Routers
Pada intinya semua aplikasi React Router harus menjadi sebuah
komponen router. Untuk proyek web, `react-router-dom` menenyediakan
router `<BrowserRouter>` dan `<HashRouter>`. Perbedaan utama antara
keduanya adalah cara mereka menyimpan URL dan
mengkomunikasikannya dengan peladen (server) web anda.
function App() {
return <h1>Hello React Router</h1>;
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
Router Matchers
Ada dua komponen pencocok route: `Switch` dan `Route`. Ketika sebuah
<Switch> dirender, <Swtich> mencari melalui semua elemen anak <Route>`
untuk menemukan path mana yang cocok dengan URL saat ini. Ketika
<Switch> menemukannya, dia akan me-render <Route> tersebut dengan
path khusus (biasanya lebih lama) sebelum yang kurang-khusus.
Jika tidak ada <Route> yang cocok, <Switch> tidak merender apapun (null).
function App() {
return (
<div>
<Switch>
{/* jika URL saat ini adalah /about, route ini akan dirender
sementara sisanya tidak dipedulikan*/}
<Route path="/about">
<About />
</Route>
{/* Jika tidak ada rute sebelumnya yang merender apa pun,
route akan menjadi sebuah fallback.
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById("root")
);
Satu hal penting yang perlu dicatat bahwa sebuah <Route path> cocok
dengan awalan dari URL, bukan semuanya. Jadi sebuah <Route path="/">
akan selalu cocok dengan URL. Karena itu, kita biasanya menempatkan
<Route> ini diakhir dari `<Switch>` kita. Solusi lain yang mungkin adalah
menggunakan `<Route exact path="/">` yang akan melakukan
pencocokan dengan seluruh URL.
7
<Link to="/">Home</Link>
// <a href="/">Home</a>
<NavLink> adalah tipe khusus dari <Link> yang dapat bergaya sendiri
sebagai “active” ketika props `to` cocok dengan lokasi saat ini.
8
Server Rendering
Rendering di server sedikit berbeda karena semuanya tanpa state
(stateless). Ide dasarnya adalah kita membungkus sebuah aplikasi di
dalam sebuah <StaticRouter> stateless alih-alih sebuah <BrowserRouter>.
Kita mengopernya didalam requested url dari server jadi routes akan
cocok dan sebuah props `context` yang akan kita bahas nanti.
// client
<BrowserRouter>
<App/>
</BrowserRouter>
if (context.url) {
// pada suatu tempat sebuah `<Redirect>` telah dirender
redirect(301, context.url);
} else {
// kami baik-baik saja, kirim response
}
9
Adding app specific context information
Router hanya pernah menambahkan `context.url`. tapi anda mungkin ingin
beberapa redirect menjadi ke 301 dan lainnya ke 302. Atau mungkin anda
ingin untuk mengirim sebuah response 404 jika beberapa cabang
(branch) khusus dari UI (user interface) dirender, atau sebuah 401 jika
mereka tidak memiliki otoriasasi. Prop context milik anda, jadi anda dapat
mengubahnya. Ini adalah cara untuk membedakan antara redirect 301
dan 301:
// di server
const context = {};
10
if (context.url) {
// kita menggunakan `context.status` yang
//kita tambahkan di RedirectWithStatus
redirect(context.status, context.url);
}
function NotFound() {
return (
<Status code={404}>
<div>
<h1>Sorry, can’t find that.</h1>
</div>
</Status>
);
}
function App() {
return (
<Switch>
<Route path="/about" component={About} />
<Route path="/dashboard" component={Dashboard} />
<Route component={NotFound} />
</Switch>
);
}
11
Putting it all together
Ini bukan sebuah aplikasi nyata, tapi ini menunjukkan bagian umum yang
anda akan butuhkan untuk menempatkan semuanya bersama.
http
.createServer((req, res) => {
const context = {};
if (context.url) {
res.writeHead(301, {
Location: context.url
});
res.end();
} else {
res.write(`
<!doctype html>
<div id="app">${html}</div>
`);
res.end();
}
})
.listen(3000);
Dan kemudia di client:
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("app")
);
12
Data Loading
Ada banyak pendekatan berbeda untuk melakukan pemuatan (loading)
data, dan belum ada praktik terbaik yang jelas. Jadi kita mencari yang
bisa di komposisi dengan pendekatan apapun, dan tidak menentukan
atau condong ke arah satu dengan lainnya. Kami percaya router dapat
cocok didalam batasan aplikasi anda.
Batasan utama adalah anda ingin memuat data sebelum anda me-
render. React Router mengekspor fungsi statis `matchPath` yang
digunakan secara internal untuk mencocokkan lokasi dengan route. Anda
dapat menggunakan fungsi ini di server untuk membantu menentukan
apa data depencencies anda yang akan ada sebelum rendering.
Inti pendekatan ini bergantung pada sebuah konfigurasi route statis yang
digunakan ke keduanya me-render route anda dan mencocokkannya
sebelum rendering untuk menentukan data depencencies.
const routes = [
{
path: "/",
component: Root,
loadData: () => getSomeData()
}
// dan lain-lain.
];
Kemudian menggunakan konfigurasi ini untuk me-render route anda di
aplikasi:
function App() {
return (
<Switch>
{routes.map(route => (
<Route {...route} />
))}
</Switch>
);
}
Lalu pada server anda memiliki sesuatu seperti:
13
const promises = [];
// gunakan `some` untuk meniru perilaku `<Switch>` memilih hanya
// pertama yang cocok
routes.some(route => {
// gunakan `matchPath` disini
const match = matchPath(req.path, route);
if (match) promises.push(route.loadData(match));
return match;
});
Promise.all(promises).then(data => {
// lakukan sesuatu dengan data sehingga client
//dapat mengaksesnya kemudian render aplikasi
});
Dan akhirnya, client butuh mengambil data. Lagi, kita tidak berurusan
dengan menentukan sebuah pola muat data untuk aplikasi anda, tapi ini
adalah titik sentuh yang anda perlu untuk menerapkannya.
Anda mungkin tertarik dengan package React Router Config anda untuk
membantu muat data dan rendering server dengan konfigurasi route
statis.
14
Code Splitting
Satu fitur hebat dari web adalah kita tidak harus membuat pengunjung
kita mengunduh seluruh aplikasi sebelum mereka menggunakannya.
Anda dapat berpikir pemisah kode (code splitting) sebagai mengunduh
aplikasi bertahap. Untuk mencapai ini kita akan menggunakan
webpack, @babel/plugin-syntax-dynamic-import, dan loadable-
components.
{
"presets": ["@babel/preset-react"],
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
loadable-components adalah sebuah library untuk memuat komponen
dengan impor dinamis. Library ini menangani semua macam kasus
secara otomatis dan membuat code splitting menjadi sederhana! Ini
adalah sebuah contoh cara menggunakan loadable-components:
15
adalah sebuah komponen placeholder untuk ditampilkan saat komponen
nyata sedang dimuat.
16
Scroll Restoration
Pada React Router versi terdahulu kami menyediakan dukungan out-of-
the-box untuk pemulihan gulir (scroll restoration) dan orang-orang telah
memintanya sejak saat itu. Mudah-mudahan dokumen ini membantu
anda mendapat apa yang anda butuh dari scroll bar dan routing!
Scroll to top
Kebanyakan semua yang anda butuhkan adalah “gulir ke atas” karena
anda memiliki halaman konten yang panjang, yang saat dinavigasi, tetap
gulir kebawah. Ini jelas untuk menangani dengan komponen <ScrollToTop>
yang akan menggulir window keatas setiap navigasi:
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
return null;
}
Jika anda belum menjalakan React 16.8, anda dapat melakukan hal
serupa dengan sebuah subclass `React.Component`:
17
componentDidUpdate(prevProps) {
if (
this.props.location.pathname !== prevProps.location.pathname
) {
window.scrollTo(0, 0);
}
}
render() {
return null;
}
}
function App() {
return (
<Router>
<ScrollToTop />
<App />
</Router>
);
}
Jika anda memiliki sebuah tab antarmuka (interface) tersambung ke
router, lalu anda mungkin tidak ingin gulir ke atas ketika browser menukar
tabs. Alih-alih, bagaimana tentang sebuah <ScrollToTopOnMount> di
tempat khusus yang anda butuhkan?
function ScrollToTopOnMount() {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return null;
}
render() {
return null;
}
}
Generic Solution
Untuk sebuah solusi umum (dan apa yang browser mulai untuk diterapkan
secara native) kita membicaran tentang dua hal:
Disatu titik kita ingin mengirim ke API umum. Ini adalah apa yang kita tuju:
19
<Router>
<ScrollRestoration>
<div>
<h1>App</h1>
<RestoredScroll id="bunny">
<div style={{ height: "200px", overflow: "auto" }}>
I will overflow
</div>
</RestoredScroll>
</div>
</ScrollRestoration>
</Router>
Pertama, `ScrollRestoration` akan menggulir window ke atas pada navigasi.
Kedua, ` ScrollRestoration` akan menggunakan `location.key` untuk
menyimpan posisi gulir window dan posisi gulir dari komponen
`RestoredScroll` ke `sessionStorage`. Lalu, ketika komponen
`ScrollRestoration` atau `RestoredScoll` mount. Mereka akan melihat ke
posisi mereka dari `sessionStorage`.
Bagian yang sulit adalah menentukan API `opt-out` ketika anda tidak ingin
gulir window diatur. Contoh, jika anda memiliki beberapa tab navigasi
mengambang didalam konten dari halaman anda anda mungkin tidak
ingin untuk gulir ke atas (tabs mungkin bergulir keluar view!).
Ketika kita belajar bahwa Chrome mengatur posisi gulir untuk kita
sekarang, dan menyadari bahwa aplikasi berbeda akan memiliki
kebutuhan gulir yang berbeda. Kita agak kehilangan kepercayaan bahwa
kita butuh untuk menyediakan sesuatu-khususnya ketika orang-orang
hanya ingin gulir ke atas ( yang anda lihat jelas untuk ditambahkan ke
aplikasi anda oleh anda sendiri).
Berdasarkan hal ini, kita tidak lagi meresa cukup kuat untuk melakukan
kerja kita sendiri (seperti anda memiliki waktu terbatas!). Tapi, kami
senang membantu siapapun yang merasa cenderung untuk menerapkan
sebuah solusi umum. Sebuah solusi solid dapat bahkan hidup di proyek.
Hubungi kami jika Anda memulainya :)
20
Philosophy
Tujuan panduan ini adalah untuk menjelaskan model mental untuk dimiliki
ketika menggunakan React Router. Kami menyebutknya “Dynamic
Routing”, yang sangat berbeda dari “Static Routing” yang mungkin anda
telah terbiasa dengannya.
Static Routing
Jika anda menggunakan Rail, Express, Ember, Angular dll. Anda telah
menggunkana routing statis. Di kerangka kerja (framework) ini, anda
mendeklarasikan route anda sebagai awalan aplikasi anda sebelum
rendering apapun dilakukan. React Router pre-v4 juga statis (hampir
semua). Mari lihat bagaimana konfigurasi route di express:
app.listen();
Perhatikan bagaimana route dideklarasikan sebelum app listens, router
client side yang telah kita gunakan mirip. Di Angular anda
mendeklarasikan route anda didepan dan mengimpornya ke top-level
AppModule sebelum rendering:
@NgModule({
imports: [RouterModule.forRoot(appRoutes)]
})
export class AppModule {}
Ember memiliki sebuah konvensional file `routes.js` yang membangun
reads dan import ke aplikasi anda. Lagi, ini terjadi sebelum aplikasi anda
dirender.
BackStory
Sejujurnya kami sangat frustasi dengan arah yang kami telah ambil Reat
Router v2. Kami (Michael dan Ryan) merasa terbatasi oleh API, telah kami
akui kami mengimplementasikan ulang bagian React (lifecycles, dan
lainnya), dan itu tidak cocok dengan mental model React yang telah
berikan ke kita untuk perancangan (composing) UI.
22
Hanya kurun waktu beberapa jam dalam pengembangan kami memiliki
sebuah bukti-dari-konsep yang kami tahu merupakan masa depan yang
kami ingin untuk routing. Kami berakhir dengan API yang tidak ada di “luar”
React. Sebuah API yang disusun, atau secara alami jatuh ke tempatnya,
dengan sisa React. Kami pikir anda akan menyukainya.
Dynamic Routing
Ketika kita mengatakan route dinamis, kami maksut adlah routing yang
mengambil bagian saat aplikasi anda di-render. Bukan sebuah
konfigurasi atau konversi diluar dari sebuah aplikasi yang sedang berjalan.
Yang berarti hampir semuanya merupakan sebuah komponen di React
Router. Ini adalah 60 detik tinjauan API untuk melihat bagaimana cara
kerjanya:
// react-native
import { NativeRouter } from "react-router-native";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
el
);
Lalu, ambil komponen link untuk link ke sebuah lokasi baru:
23
<Link to="/dashboard">Dashboard</Link>
</nav>
<div>
<Route path="/dashboard" component={Dashboard} />
</div>
</div>
);
Route akan render <Dashboard {…props}/> dimana props merupakan
router khusus yang tampak seperti `{match, location, history}`. Jika
pengguna tidak berada di /dashboard kemudian Route akan me-render
`null`. Itu cukup banyak untuk itu.
Nested Routes
Banyak router yang memiliki beberapa konsep “route bersarang”. Jika
anda telah menggunakan versi React Router sebelum v4, anda akan tahu
juga! Ketika anda berpindah dari sebuah konfigurasi route statis ke
dinamis, merender route, bagaimana anda “route bersarang”? oke,
bagaimana anda membuat sebuah `div` bersarang?
24
Responsive Routes
Meninjau seorang pengguna navigasi ke `/invoice`. Aplikasi anda
beradaptasi ke ukuran layar berbeda, ukuran layar memiliki sebuah
viewport sempit, dan anda hanya menampilkan daftar dari tagihan dan
sebuah link dashboard tagihan. Mereka dapat bernavigasi lebih dalam
dari sini.
Small Screen
url: /invoices
+----------------------+
| |
| Dashboard |
| |
+----------------------+
| |
| Invoice 01 |
| |
+----------------------+
| |
| Invoice 02 |
| |
+----------------------+
| |
| Invoice 03 |
| |
+----------------------+
| |
| Invoice 04 |
| |
+----------------------+
Pada sebuah layar yang lebih besar kita suka menampilkan sebuah
tampilan master-detail saat navigasi pada sis kiri dan dashboard atau
invoices khusus tampil di kanan.
Large Screen
url: /invoices/dashboard
+----------------------+---------------------------+
| | |
| Dashboard | |
| | Unpaid: 5 |
+----------------------+ |
| | Balance: $53,543.00 |
| Invoice 01 | |
| | Past Due: 2 |
25
+----------------------+ |
| | |
| Invoice 02 | |
| | +-------------------+ |
+----------------------+ | | |
| | | + + + | |
| Invoice 03 | | | + | | | |
| | | | | | + | + | |
+----------------------+ | | | | | | | | |
| | +--+-+--+--+--+--+--+ |
| Invoice 04 | |
| | |
+----------------------+---------------------------+
Kini berhenti sejenak untuk semenit dan pikirkan tentang url `incoives`
untuk kedua ukuran layar. Apakah itu sebuah route valid untuk sebuah
layar besar? Apa yang harus kita tempatkan pada sisi kanan?
Large Screen
url: /invoices
+----------------------+---------------------------+
| | |
| Dashboard | |
| | |
+----------------------+ |
| | |
| Invoice 01 | |
| | |
+----------------------+ |
| | |
| Invoice 02 | ??? |
| | |
+----------------------+ |
| | |
| Invoice 03 | |
| | |
+----------------------+ |
| | |
| Invoice 04 | |
| | |
+----------------------+---------------------------+
Pada layar besar, `/invoices` bukan merupakan sebuah route valid, tapi
pada sebuah layar kecil iya. Untuk membuat hal ini lebih menarik,
bayangkan seseorang dengan sebuah smartphone raksasa. Mereka
dapat mencari di `/invoices` di orientasi portrait dan lalu merotasi
smartphone mereka menjadi landscape. Tiba-tiba, kami memiliki sebuah
26
ruang untuk menampilkan UI master-detail, jadi anda harusnya me-
redirect ke kanan.
<Media query={PRETTY_SMALL}>
{screenIsSmall =>
screenIsSmall ? (
// layar kecil tidak di redirect
<Switch>
<Route
exact
path="/invoices/dashboard"
component={Dashboard}
/>
<Route path="/invoices/:id" component={Invoice} />
</Switch>
) : (
//layar besar iya!
<Switch>
<Route
exact
path="/invoices/dashboard"
component={Dashboard}
/>
<Route path="/invoices/:id" component={Invoice} />
<Redirect from="/invoices" to="/invoices/dashboard" />
</Switch>
)
}
</Media>
</Layout>
27
);
Ini hanya sebuah contoh. Ada banyak yang lainnya kami dapat
mendiskusikannya tapi kami akan merangkumnya dengan saran ini: untuk
mendapat intuisi anda segais dengan pemikiran React Router tentang
komponen, bukan route statis. Pikirkan tentang bagaimana cara untuk
menyelesaikan masalah dengan koposisi deklaratifnya React karena
hampir setiap “pertanyaan React Router” kemungkinan sebuah
“pertanyaan React”.
28
Testing
React Router bergantung pada React context untuk berfungsi. Ini berakibat
cara anda dapat melakukan pengujian komponen anda yang
menggunakan komponen kita.
Context
Jika anda mencoba untuk melakukan pengujian (test) unit dari komponen
anda yang merender sebuah <Link> atau sebuah <Route>, dll. Anda akan
mendapat beberapa error dan peringatan tentang context. Ketika anda
mungkin tergoda untuk mematikan context router anda sendiri, kami
merekomendasikan anda membungkus unit test anda di sebuah
komponen Router: base Router dengan sebuah prop `history`, atau sebuah
<StaticRouter>, <MemoryRouter>, atau <BrowserRouter> (jika
`window.history` tersedia sebagai sebah global dalam lingkungan test).
// rusak
test("it expands when the button is clicked", () => {
render(<Sidebar />);
click(theButton);
expect(theThingToBeOpen);
});
// diperbaiki!
29
test("it expands when the button is clicked", () => {
render(
<MemoryRouter>
<Sidebar />
</MemoryRouter>
);
click(theButton);
expect(theThingToBeOpen);
});
Navigating
Kita memiliki banyak test yang route berkerja ketika lokasi berubah, jadi
anda mungkin tidak butuh test seperti ini. Tapi jika anda butuh untuk
menguji navigasi dengan aplikasi anda, anda dapat melakukannya
seperti ini:
// app.test.js
it("navigates home when you click the logo", async => {
//di test nyata renderer seperti "@testing-library/react"
// akan mengurus epngaturan DOM elements
const root = document.createElement('div');
document.body.appendChild(root);
// Render app
render(
<MemoryRouter initialEntries={['/my/initial/route']}>
<App />
</MemoryRouter>,
root
);
31
Checking location in tests
Anda tidak harus mengakses objek `location` atau `history` sesering
mungkin di test. Tapi jika anda melakukannya (seperti untuk memvalidasi
query params baru tersebut diatur di url bar), anda dapat menambahkan
sebuah route yang memperbarui sebuah variable didalam test:
// app.test.js
test("clicking filter links updates product query params", () => {
let testHistory, testLocation;
render(
<MemoryRouter initialEntries={["/my/initial/route"]}>
<App />
<Route
path="*"
render={({ history, location }) => {
testHistory = history;
testLocation = location;
return null;
}}
/>
</MemoryRouter>,
node
);
act(() => {
// contoh klik <Link> ke `/products?id=1234`
});
Altenatif:
33
Deep Redux Integration
Redux adalah sebuah bagian penting dari ekosistem React. Kami ingin
membuat integrasi React Router dan Redux semulus mungkin untuk orang
–orang yang ingin menggunakan keduanya. Untuk itu, beberapa orang
ingin:
Rekomendasi kami adalah tidak menjaga route anda di Redux store anda
sama sekali. Ini alasan kami:
Tapi jka adan merasa yakin tentang synchronizing route anda dengan
store anda, anda mungkin ingin mencoba Connected React Router,
sebuah pihak ketiga mengikat untuk React Router dan Redux.
34
Static Routes
Pada versi React Router sebelumnya menggunakan route statis untuk
mengkonfigurasi routing aplikasi anda. Statis route ini memungkinkan
untuk inspeksi dan pencocokan route sebelum rendering. Sejak v4
berpindah ke komponen dinamis alih-alih konfigurasi route, beberapa
kasus penggunaan sebelumnya menjadi kurang jelas dan sulit.
35
API
Hooks
React Router mengirim dengan beberapa hooks yang memungkinkan
anda mengakses state dari router dan melakukan navigasi dari dalam
komponen anda.
useHistory
useLocation
useParams
useRouteMatch
useHistory
hook useHistroy memberikan anda akses ke instance `history` yang anda
mungkin gunakan untuk navigasi.
function HomeButton() {
let history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
useLocation
hook useLocation mengembalikan object `location` yang mewakili URL saat
ini. Anda mungkin berpikir tetang hook ini seperti sebuah `useState` yang
mengembalikan location baru kapanpun URL berubah.
36
Hook ini dapat sangat berguna contoh dalam situasi ketika anda ingin
memicu sebuah event “page view” baru menggunakan alat analitik web
anda kapanpun sebauh halaman baru dimuat, seperti contoh berikut:
function usePageViews() {
let location = useLocation();
React.useEffect(() => {
ga.send(["pageview", location.pathname]);
}, [location]);
}
function App() {
usePageViews();
return <Switch>...</Switch>;
}
ReactDOM.render(
<Router>
<App />
</Router>,
node
);
useParams
useParams mengembalikan sebuah objek dari pasangan key/value dari
parameter URL. Yang digunakan untuk mengakses `match.params` di
<Route> saat ini.
function BlogPost() {
37
let { slug } = useParams();
return <div>Now showing post {slug}</div>;
}
ReactDOM.render(
<Router>
<Switch>
<Route exact path="/">
<HomePage />
</Route>
<Route path="/blog/:slug">
<BlogPost />
</Route>
</Switch>
</Router>,
node
);
useRouteMatch
hook useRouterMatch mencoba untuk `match` URL saat ini dengan cara
yang sama dengan yang <Route> lakukan. Hook ini sangat berguna untuk
mendapatkan akses ke pencocokan data tanpa rendering sebuah
<Router> yang sebenarnya.
Kini, alih-alih
function BlogPost() {
return (
<Route
path="/blog/:slug"
render={({ match }) => {
// lakukan apapun yang anda ingin dengan match...
return <div />;
}}
/>
);
}
Anda bisa saja
function BlogPost() {
let match = useRouteMatch("/blog/:slug");
38
// lakukan apapun yang anda ingin dengan match...
return <div />;
}
Salah satu hook useRouteMatch:
39
<BrowserRouter>
Sebuah <Router> yang menggunakan history API HTML5 (`pushState`,
`replaceState` dan event `popstate`) untuk menjaga UI anda sinkron
dengan URL.
<BrowserRouter
basename={optionalString}
forceRefresh={optionalBool}
getUserConfirmation={optionalFunc}
keyLength={optionalNumber}
>
<App />
</BrowserRouter>
basename: string
Base URL untuk semua locations. Jika aplikasi anda disajikan dari sebuah
sub-direktori pada server anda, anda ingin mengatur ini ke sub-direktori.
Sebuah basename yang diformat dengan benar harus memilik sebuah
garis miring utama, tapi bukan garis miring saja.
<BrowserRouter basename="/calendar">
<Link to="/today"/> // renders <a href="/calendar/today">
<Link to="/tomorrow"/> // renders <a href="/calendar/tomorrow">
...
</BrowserRouter>
getUserConfirmation: func
sebuah fungsi digunakan untuk konfirmasi navigasi. Default untuk
menggunakan `window.confirm`.
<BrowserRouter
getUserConfirmation={(message, callback) => {
//ini adalah perilaku default
const allowTransition = window.confirm(message);
callback(allowTransition);
}}
/>
forceRefresh: boolean
jika `true` router akan menggunakan menyegarkan satu halaman penuh di
halaman navigasi. Anda mungkin ingin menggunakan ini untuk meniru
40
cara aplikasi tradisional server-rendered bekerja dengan menyegarkan
halaman penuh antar halaman navigasi.
keyLength: number
Panjang dari `location.key`. Default-nya 6.
Children: node
Elemen child untuk render
Catat: pada React < 16 anda harus menggunakan sebuah element anak
tunggal karena sebuah metode render tidak dapat mengembalikan lebih
dari satu element. Jika anda butuh lebih dari satu elemen, anda mungkin
harus mencoba membungkusnya dalam sebuah <div> tambahan.
41
<HashRouter>
Sebuah <Router> yang menggunakan bagian hash dari URL (yaitu
`window.location.hash`) untuk menjaga UI anda sinkron dengan URL.
<HashRouter
basename={optionalString}
getUserConfirmation={optionalFunc}
hashType={optionalString}
>
<App />
</HashRouter>
basename: string
base URL untuk semua lokasi. Sebuah basename yang diformat dengan
benar harus memiliki sebuah garis miring utama, tapi tidak ada garis
miring tambahan.
<HashRouter basename="/calendar"/>
<Link to="/today"/> // renders <a href="#/calendar/today">
getUserConfirmation: function
sebuah fungsi untuk menggunakan konfirmasi navigasi. Default yang
digunakan `window.confirm`.
<HashRouter
getUserConfirmation={(message, callback) => {
// ini adalah perilaku default
const allowTransition = window.confirm(message);
callback(allowTransition);
}}
/>
42
hashType: string
tipe dari encoding untuk menggunakan `window.location.hash`. nilai yang
tersedia adalah:
Children: node
Sebuah element anak tunggal untuk di-render.
43
<Link>
Menyediakan deklaratif, navigasi yang dapat diakses disekitar aplikasi
anda.
<Link to="/about">About</Link>
to: string
sebuah string yang mewakili lokasi Link, dibuat oleh gabungan propserti
pathname-nya location, search, dan hash.
to: object
sebuah objek yang dapat diikuti oleh properti apapun:
<Link
to={{
pathname: "/courses",
search: "?sort=name",
hash: "#the-hash",
state: { fromDashboard: true }
}}
/>
to: function
sebuah fungsi yang location saat ini dioper sebagai argument dan harus
mengembalikan location yang mewakili berupa sebuah string atau
sebuah objek.
44
<Link to={location => ({ ...location, pathname: "/courses" })} />
replace: boolean
Ketika `true`, mengklik link akan mengganti masukan saat ini didalam
history stack alih-alih menambahkan dengan yang lain.
innerRef: function
mulai dari React Router 5.1., jika anda menggunakan React 16 anda
harusnya tidak butuh prop ini Karena forward the ref ke `<a>` yang
mendasari. Sebagai gantinya gunakan sebuah ref normal.
<Link
to="/"
innerRef={node => {
// `node` refers to the mounted DOM element
// atau null ketika unmounted
}}
/>
innerRef: RefObject
Mulai dari React Router 5.1., jika anda menggunakan React 16 anda
harusnya tidak butuh prop ini Karena forward the ref ke `<a>` yang
mendasari. Sebagai gantinya gunakan sebuah ref normal.
45
component: React.Component
Jika anda suka menggunakan komponen navigasi anda sendiri, anda bisa
dengan mudah melakukannya dengan mengopernya melalui prop
komponen.
Others
Anda dapat juga mengoper props yang anda suka ke `<a>` seperti `title.id`,
`className`, dan lain-lain.
46
<NavLink>
Sebuah <Link> versi special yang akan menambahkan attibure style untuk
elemen yang telah dirender ketika cocok dengan URL saat ini.
<NavLink to="/about">About</NavLink>
activeClassName: string
class yang diberi ke elemen ketika <NavLink> aktif. Default class yang
diberikan adalah `active`. Class ini akan digabungkan dengan prop
`className`.
activeStyle: object
style untuk diterapkan ke element ketika elemen aktif.
<NavLink
to="/faq"
activeStyle={{
fontWeight: "bold",
color: "red"
}}
>
FAQs
</NavLink>
exact: boolean
ketika `true`, class/style yang aktif hanya akan diterapka jika lokasi cocok
sama persis.
47
strict: boolean
Ketika `true`, garis miring terakhir (trailing) pada pathname-nya location
akan dipertimbangkan ketika menentukan jika lokasi cocok dengan URL
saat ini. Liat dokumentasi <Route sctrict> untuk informasi lebih lanjut.
isActive: function
sebuah fungsi untuk menambahkan logika ekstra untuk menentukan
apakah link active. Fungsi ini harus digunakan jika anda ingin melakukan
hal lebih dari sekedar verifikasi pathname-nya link yang cocok dengan
pathname-nya URL saat ini.
<NavLink
to="/events/123"
isActive={(match, location) => {
if (!match) {
return false;
}
location: object
isActive membandingkan history location saat ini (biasanya URL browser
saat ini). Untuk dibandingkan dengan sebuah location yang berbeda,
sebuah location dapat dioper.
aria-current: string
nilai dari atribut `aria-current` digunakan pada sebuah link yang aktif. Nilai
yang tersedia adalah:
“page” – gunakan untuk indikasi sebuah link dengan satu set link
paginasi.
48
“step” – digunakan untuk indikasi sebuah link dengan sebuah
indikator langkah untuk sebuah langkah-bersarkan proses.
“location” – digunakan untuk indikasi sebuah gambar yang disorot
secara visual sebagai komponen saat ini dari sebuah flow chart.
“date” – digunakan untuk indikasi tanggal saat ini dalam sebuah
kalender
“time” – digunakan untuk indikasi waktu dalam sebuah table waktu.
“true” – digunakan untuk indikasi jika Navlink aktif .
“false” – digunakan untuk mencegah teknologi bantuan dari
bereasksi ke sebuah link saat ini (mencegah banyak tags aria-
current pada satu halaman)
49
<Prompt>
Di eksport ulang dari inti Prompt
50
<MemoryRouter>
Sebuah <Router> yang menjaga history dari “URL” anda di memory (bukan
membaca atau menulis address bar). Berguna dalam test dan lingkungan
non-broswer seperti React Navite.
<MemoryRouter
initialEntries={optionalArray}
initialIndex={optionalNumber}
getUserConfirmation={optionalFunc}
keyLength={optionalNumber}
>
<App />
</MemoryRouter>
initialEntries: array
sebuah arrat dari location didalam history stack. Ini mungkin jadi objek
location penuh dengan `{ pathname, search, hash, state } atau URL string
sederhana.
<MemoryRouter
initialEntries={["/one", "/two", { pathname: "/three" }]}
initialIndex={1}
>
<App />
</MemoryRouter>
initialIndex: number
index-nya initial location di dalam array dari `initialEntries`.
getUserConfirmation: function
sebuah fungsi yang digunakan untuk konfirmasi navigasi. Anda harus
mengunakan opsi ini ketika menggunakan <MemoryRouter> secara
langsung dengan sebuah <Prompt>.
keyLength: number
panjang location.key. nilai defaultnya 6
51
Children: node
Elemen anda untuk render
Catat: pada React < 16 anda harus menggunakan sebuah elemen anak
tunggal karena sebuah metode render tidak dapat mengembalikan lebih
dari satu elemen. Jika anda butuh lebih banyak dari satu elemen, anda
mungkin mencoba untuk membungkusnya kedalam `<div>` tambahan.
52
<Redirect>
Rendering sebuah <Redirect> akan navigasi ke sebuah lokasi baru. Lokasi
baru akan menimpa lokasi saat ini didalam history stack. Sepeti server-
side redirects (HTTP 3xx) lakukan.
to String
URL untuk redirect. Path URL valid apapun yang dipahami oleh path-to-
regexp@^1.7.0. Semua parameter URL yang digunakan harus ditutup dari.
to: object
Sebuah lokasi yang dialihkan ke pathname dapat menjadi path URL valid
yang dipahami oleh path-to-regexp@^1.7.0
<Redirect
to={{
pathname: "/login",
search: "?utm=your+face",
state: { referrer: currentLocation }
}}
/>
Objek state dapat diakses melalui `this.props.location.state` di komponen
yang diredirect. Referrer key baru (yang buka sebuah nama special) akan
dapat diakses melalui `this.props.location.state.referrer` di komponen Login
ditunjuk oleh pathname `/login`.
push: boolean
Ketika `true`, redirecting akan mendorong sebuah masukan baru ke history
alih-alih menggati yang telah ada.
53
from: string
Sebuah pathname untuk pengalihan dari (redirect from). Path URL valid
apapun yang dipahami path-to-regexp@^1.7.0. Semua parameter URL
yang cocok disedikan untuk pola didalam `to`. Harus berisi semua
parameter yang digunakan didalam `to`. Parameter tambahan tidak
digunakan oleh `to` akan diabaikan.
<Switch>
<Redirect from="/old-path" to="/new-path" />
<Route path="/new-path">
<Place />
</Route>
</Switch>
exact: boolean
Pencocokan `from` yang sama persis; setara dengan Route.exact.
Catat: excat ini hanya dapat gunakan didalam kata sambung dengan
`from` ke sebuah lokasi yang sama persis ketika rendering sebuah
<Redirect> dalam sebuah <Switch>. Lihat <Switch children> untuk lebih
detailnya.
<Switch>
<Redirect exact from="/" to="/home" />
<Route path="/home">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
</Switch>
54
strict: boolean
<Switch>
<Redirect strict from="/one/" to="/home" />
<Route path="/home">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
</Switch>
sensitive: boolean
Pencocokan `from` case sensitive; setara dengan Route.sensitive.
55
<Route>
Komponen Route mungkin adalah komponen paling penting di React
Router untuk memahami dan mempelajari cara menggunakannya.
Tanggung jawab dasar route adalah untuk render beberapa UI ketika
path-nya cocok dengan URL saat ini.
ReactDOM.render(
<Router>
<div>
<Route exact path="/">
<Home />
</Route>
<Route path="/news">
<NewsFeed />
</Route>
</div>
</Router>,
node
);
Jika lokasi dari aplikasi dalah `/` lalu hierarki UI akan menjadi seperti ini:
<div>
<Home />
<!-- react-empty: 2 -->
</div>
Dan jika lokasi dari aplikasi adalah `/news` lalu UI hierakri akan menjadi:
<div>
<!-- react-empty: 1 -->
<NewsFeed />
</div>
Komen “react-empty” hanya implementasi detail dari `null` rendering-nya
React. Tapi untuk tujuan kita, ini edukatif. Sebuah route selalu secara teknis
“rendered” meskipun rendering `null`. Ketika path-nya <Route> cocok
dengan URL, route render anaknya (komponen anda).
Jika komponen yang sama digunkan sebagai anak dari beberapa <route>
yang sama di komponen tree. React akan melihat route ini sebagai
komponen contoh dan state-nya komponen akan menjadi jaga antar
56
perubahan route. Jika bukan ini yang diinginkan, sebuah key prop unik
ditambahkan ke setiap route komponen yang akan menyebabkan React
membuat kembali komponen istance ketika route berubah.
<Route component>
<Route render>
<Route children> function
Route props
Ketiga metode render semuanya akan mengoper tiga props route yang
sama
match
location
history
component
sebuah React komponen render hanya ketika lokasi cocok, komponen
akan dirender dengan route props.
57
ReactDOM.render(
<Router>
<Route path="/user/:username" component={User} />
</Router>,
node
);
Ketika anda menggunakan komponen (alih-alih `render` atau `children`,
dibawah) route menggunakan React.createElement untuk membuat
sebuah React element baru dari komponen yang diberikan. Ini berarti jika
anda menyediakan sebuah fungsi inline ke prop komponen, anda akan
membuat sebuah komponen baru setiap kali render. Hasil ini didalam
komponen yang ada unmounting dan komponen baru mounting alih-alih
hanya memperbarui komponen yang telah ada. Ketika menggunakan
sebuah fungsi inline atau rendering inline, gunakan render atau children
prop (dibawah).
render: function
fungsi ini memungkinkan rendering inline yang sesuai dan
membungkusnya tanpa remounting yang tidak dinginkan seperti yang
telah dijelaskan diatas.
Alih-alih memiliki sebuah element React baru yang dibuat untuk anda
menggunakan prop component. Anda dapat mengoper dalam sebuah
fungsi untuk dipanggil ketika lokasi cocok. Fungsi render prop memiliki
akses ke semua route props yang sama (match, location, dan history)
sebagai komponen render prop.
// membungkus/menyusun
// anda dapat menyebarkan routeProps untuk membautanya tersedia ke rendered
// Component anda
58
function FadingRoute({ component: Component, ...rest }) {
return (
<Route
{...rest}
render={routeProps => (
<FadeIn>
<Component {...routeProps} />
</FadeIn>
)}
/>
);
}
ReactDOM.render(
<Router>
<FadingRoute path="/cool" component={Something} />
</Router>,
node
);
Peringatan: <Route component> lebih diutamakan dibanding <Route
render> jadi jangan gunakan keduanya di <Route> yang sama.
children: function
Terkadang anda butuh untuk render jika path cocok dengan lokasi atau
tidak. Pada kasus ini, anda dapat menggunakan fungsi `children` prop.
Fungsi ini bekerja persis seperti render kecuali yang fungsi dipanggil jika
ada yang cocok atau tidak.
`children` render prop menerima semua route prop yang sama sebagai
komponen dan render motode, kecuali ketika sebuah route gagal untuk
cocok dengan URL, lalu `match` adalah null. Ini mengizinkan anda untuk
secara dinamis mengatur UI anda berdasarkan pada ada tidaknya route
yang cocok. Disini kita menambahkan sebuha class `active` jika route
cocok.
59
<Route
path={to}
children={({ match }) => (
<li className={match ? "active" : ""}>
<Link to={to} {...rest} />
</li>
)}
/>
);
}
ReactDOM.render(
<Router>
<ul>
<ListItemLink to="/somewhere" />
<ListItemLink to="/somewhere-else" />
</ul>
</Router>,
node
);
Ini dapat juga berguna untuk animasi:
<Route
children={({ match, ...rest }) => (
{/* Animate will akan selalu render,jadi anda dapat menggunakan lifecycles
untuk animate its child in and out */}
<Animate>
{match && <Something {...rest}/>}
</Animate>
)}
/>
Peringatan: <Route children> lebih didahulukan dari kedua <Route
component> dan <Route render> jadi jangan gunakan lebih dari satu
didalam <Route> yang sama.
<Route path="/users/:id">
<User />
</Route>
60
Route tanpa sebuah path selalu cocok.
exact: boolean
Ketika `true`, hanya akan cocok jika path cocok sama persis dengan
`location.pathname`.
strict: boolean
Ketika `true` sebuah path yang memiliki garis miring dibelakang hanya
akan cocok dengan sebuah `location.pathname` dengan sebuah garis
mirip dibelakang. Ini tidak memiliki dampak ketika ada bagian URL
tambahan di `location.pathname`.
61
location: object
Sebuah element <Route> mencoba pencocokan dengan path ke lokasi
history saat ini (biasanya URL browser saat ini). Namun, sebuah location
dengan pathname berbeda dapat juga dioper untuk pencocokan.
Location berguna pada kasus saat anda butuh untuk mencocokan sebuah
<Route> ke sebuah location bukan location history saat ini, seperti yang
ditampilkan pada contoh Animated Transitions.
Jika sebuah elemen <Route> dibungkus dalam sebuah <Switch> dan cocok
dengan location yang dioper ke <Switch> (atau history location saat ini),
lalu location prop dioper ke <Route> akan ditindih oleh satu yang
digunakan oleh <Swicth> (diberikan disini).
sensitive: boolean
Ketika `true`, akan cocok jika path adalah case sensitive.
62
<Router>
Antarmuka low-level yang umum untuk semua komponen router.
Biasanya aplikasi akan menggunakan satu dari router high-level :
<BrowserRouter>
<HashRouter>
<MemoryRouter>
<NativeRouter>
<StaticRouter>
ReactDOM.render(
<Router history={history}>
<App />
</Router>,
node
);
history: object
Sebuah objek history digunakan untuk navigasi
63
Children: node
Sebuah elemen anak untuk render.
<Router>
<App />
</Router>
64
<StaticRouter>
Sebuah <Router> yang tidak pernah mengubah location.
Ini adalah sebuah contoh node server yang mengirim sebuah status 302
untuk <Redirect> dan HTML biasa untuk request lain.
http
.createServer((req, res) => {
// context object ini berisi hasil dari render
const context = {};
65
basename: string
Base URL untuk semua location. Sebuah basename yang diformat dengan
benar harusnya memiliki sebuah garis miring didepan, bukan garis miring
dibelakang.
<StaticRouter basename="/calendar">
<Link to="/today"/> // renders <a href="/calendar/today">
</StaticRouter>
location: string
URL server yang diterima, mungkin req.url pada sebuah server node.
<StaticRouter location={req.url}>
<App />
</StaticRouter>
location: object
Sebuah objek location bentuknya seperti { pathname, search, hash, state }
context: object
Sebuah objek JavaScript. Selama render, komponen dapat ditambahkan
properti objek untuk menyimpan informasi tentang render.
const context = {}
<StaticRouter context={context}>
<App />
</StaticRouter>
Ketika sebuah <Route> cocok, itu akan mengoper objek context ke
komponen itu render sebuah prop `staticContext`. Periksa panduan Server
Rendering untuk informasi lebih cara melakukannya sendiri.
66
Children: node
Catat: pada React < 16 anda harus menggunakan sebuah anak elemen
tunggal karena sebuah metode render tidak dapat mengembalikan lebih
dari satu elemen. Jika anda butuh lebih dari satu elemen, anda mungkin
coba membungkusnya didalam <div> tambahan.
67
<Switch>
Render anak pertama <Route> atau <Redirect> yang cocok dengan
location.
<Switch> unik dalam hal itu, <Switch> render sebuah route secara khusus.
Berdeda, setiap <Route> yang cocok dengan location render secara
inklusif. Perhatikan route ini:
let routes = (
<div>
<Route path="/about">
<About />
</Route>
<Route path="/:user">
<User />
</Route>
<Route>
<NoMatch />
</Route>
</div>
);
Jika URL adalah `/about`, lalu <About>, <User>, dan <NoMatch> akan
dirender semua karena mereka semua cocok dengan path. Ini oleh design,
memungkinkan kita untuk menyusun <Route> kedalam aplikasi kita
dengan banyak cara, seperti sidebars dan breadcrums, boostrap tap, dan
lain-lain.
let routes = (
<Switch>
<Route exact path="/">
<Home />
</Route>
68
<Route path="/about">
<About />
</Route>
<Route path="/:user">
<User />
</Route>
<Route>
<NoMatch />
</Route>
</Switch>
);
Kini, jika kita ada di `/about`, <Swtich> akan memulai mencari sebuah
<Route> yang cocok. <Route path=”/about”/> akan cocok dan <Switch>
akan berhenti mencari pencocokan dan render <About>. Demikian pula,
jika kita pada `/michael` lalu <User> akan dirender.
Ini juga berguna untuk transisi animasi karena <Route> yang cocok
dirender dalam posisi yang sama dengan yang sebelumnya.
let routes = (
<Fade>
<Switch>
{/* hanya akan ada satu child disni */}
<Route />
<Route />
</Switch>
</Fade>
);
let routes = (
<Fade>
{/* akan selalu dua children disini,
satu mungkin render null though, membuat transisi
sedikit lebuh cumbersome to work out */}
<Route />
<Route />
</Fade>
);
location: object
Sebuah objek location digunakan untuk pencocokan anak elemen alih-
alih history location saat ini (biasanya URL browser saat ini).
69
children: node
Semua anak dari <Swtich> harus berupa elemen <Route> atau <Redirect>.
Hanya anak pertama yang cocok dengan location saat ini yang akan
dirender.
Jika sebuah prop `location` diberikan ke <Switch>, ini akan menindih prop
`location` pada pencocokan elemen anak.
let routes = (
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/users">
<Users />
</Route>
<Redirect from="/accounts" to="/users" />
<Route>
<NoMatch />
</Route>
</Switch>
);
70
generatePath
fungsi generatePath dapat digunakan untuk generate URL ke route. Secara
internal library path-to-regexp digunakan.
generatePath("/user/:id/:entity(posts|comments)", {
id: 1,
entity: "posts"
});
// Will return /user/1/posts
Hasil dari penyusunan path kedalam regular expression di cache. Jadi
tidak ada overhead pada generate banyak path dengan pola yang sama.
pattern: string
`generatePath` butuh 2 argumen. Pertama sebuah pola yang disediakan
sebagai attibure path ke komponen Route.
Params: object
Argument kedua adalah sebuah objek yang sesuai dengan params untuk
pola yang digunakan.
Jika params disediakan dan path tidak cocok, sebuah error akan muncul:
71
History
Istilah “history” dan “history object” pada dokumentasi ini merujuk pada
the history package , yang merupakan salah satu dari 2 dependencies
utama React Router (disamping React itu sendiri), yang menyediakan
beberapa impementasi berbeda untuk menggelola history session di
JavaScript dalam lingkungan berbeda.
73
Location
Locations menggambarkan letak aplikasi anda saat ini, kemana anda
ingin pergi, atau mungkin dimana tadi. Itu tampak seperti ini:
{
key: 'ac3df4', // not with HashHistory!
pathname: '/somewhere',
search: '?some=search-string',
hash: '#howdy',
state: {
[userDefined]: true
}
}
Router akan menyediakan anda dengan sebuha objek location di
beberapa tempat:
componentWillReceiveProps(nextProps) {
if (nextProps.location !== this.props.location) {
// navigated!
}
}
Anda dapat menyediakan location alih-alih string ke beberapa tempat
yang menavigasi:
Web Link to
Navite Link to
Redirect to
`history.push`
`history.replace`
74
Pada umumnya anda hanya menggunakan sebuah string, tapi jika anda
butuh untuk menambahkan beberapa “state location” yang akan
menerima apapun yang dikembalikan ke location khusus, sebagai
gantinya anda dapat menggunakan sebuah objek location. Objek location
berguna jika anda ingin cabang UI berdasarkan history navigasi ali-alih
hanya `path` (seperti modal).
<Link to={location}/>
<Redirect to={location}/>
history.push(location)
history.replace(location)
akhirnya, anda dapat mengoper sebuah `location` diikuti komponen:
Route
Switch
Ini akan mencegah mereka dari menggunakan lokasi asli didalam state-
nya router. Ini berguna untuk animasi dan menunda navigasi, atau
kapanpun anda ingin untuk menipu sebuah komponen ke rendering saat
sebuah location berbeda bukan yang sebenarnya.
75
Match
Sebuah objek match berisi informasi tentang cara sebuah <Route path>
dicocokkan URL. Objek match berisi property berikut:
jika sebuah Route tidak memiliki sebuah path, dan karena itu selalu cocok,
anda akan mendapat pencocokan induk terdekat. Sama halnya dengan
`withRouter`.
null matches
Sebuah <Route> yang menggunakan prop `children` akan memanggil
fungsi `children` meski ketika path-nya route tidak cocok dengan location
saat ini. Pada kasus ini, `match` akan menjadi `null`. Mampu untuk render
sebuah konten <Route> ketika cocok dapat berguna, tapi tantangan
tertentu hadir dari situasi ini.
76
jika anda mencoba melakukan ini ketika `match` bernilai `null`, anda akan
berakhir dengan sebuah TypeError. Ini berarti dianggap tidak aman untuk
mencoba menggabungkan path “relative” didalam sebuah <Route> ketika
menggunakan prop `children`.
Mirip, tapi situasi yang lebih halus terjadi ketika anda menggunakan
sebuah <Route> tanpa path didalam sebuah <Route> yang generate
sebuah objek match `null`.
// location.pathname = '/matches'
<Route path="/does-not-match"
children={({ match }) => (
// match === null
<Route
render={({ match: pathlessMatch }) => (
// pathlessMatch === ???
)}
/>
)}
/>
<Route> tanpa path mewarisi objek `match` mereka dari induknya. Jika
induk mereka `match` bernilai `null`, lalu `match` mereka juga akan
menjadi `null`. Ini berarti bahwa a) child route/links apapun akan menjadi
absolute karena disana tidak ada induk untuk untuk menyelesaikannya
dan b) sebuah route tanpa path yang induk `match` dapat menjadi `null`
akan butuh untuk menggunakan prop `children` untuk render.
77
matchPath
Ini mengizinkan anda menggunakan pencocokan kode yang sama yang
<Route> gunakan kecuali diluar dari nomal siklus render. Seperti
berkumpulnya depencies data sebelum render di server.
pathname
Argument pertama adakah pathname anda ingin dicocokan. Jika anda
menggunakan ini deserver dengan Node.js. ini akan menjadi `req.path`.
props
Argument kedua adalah props untuk pencocokan, mereka mirip dengan
prop yang dicocokan yang diterima Route. Ini dapat juga menjadi sebuah
string atau sebuah array dari string sebagai jalan pintas untuk `{ path }`:
{
path, // seperti /users/:id; salah satu dari single string atau array dari s
trings
strict, // optional, defaults to false
exact, // optional, defaults to false
}
returns
Ini mengembalikan sebuah objek ketika disediakan pathname yang cocok
dengan prop path.
matchPath("/users/2", {
path: "/users/:id",
exact: true,
strict: true
});
// {
// isExact: true
// params: {
78
// id: "2"
// }
// path: "/users/:id"
// url: "/users/2"
// }
Ini akan mengembalikan `null` ketika pathname yang disediakan tidak
cocok dengan prop `path`.
matchPath("/users", {
path: "/users/:id",
exact: true,
strict: true
});
// null
79
withRouter
Anda dapat akses untuk propertinya objek history dan match-nya <Route>
terdekat melalui high-order komponen `withRouter`. `withRouter` akan
mengoper props `match`, `location`, dan `history` untuk membungkus
komponen kapanpun withRouter.
render() {
const { match, location, history } = this.props;
80
Component.WrappedComponent
Komponen pembungkus tidak tersembunyi sebagai property statis
WrappedComponent pada komponen yang dikembalikan, yang dapat
digunakan untuk komponen testing dalam isolasi, diantara lainnya.
// MyComponent.js
export default withRouter(MyComponent)
// MyComponent.test.js
import MyComponent from './MyComponent'
render(<MyComponent.WrappedComponent location={{...}} ... />)
wrappedComponentRef: function
sebuah fungsi yang akan dioper sebagai prop `ref` untuk membungkus
komponen.
render() {
return (
<MyComponent wrappedComponentRef={c => (this.component = c)} />
);
}
}
81