@@ -3,7 +3,159 @@ id: example-react-router
3
3
title : React Router
4
4
---
5
5
6
- This example demonstrates React Router v6. For previous versions see below.
6
+ This example demonstrates React Router v6.4 and above. For previous versions see below.
7
+
8
+ ``` jsx
9
+ // App.jsx
10
+ import {
11
+ createBrowserRouter ,
12
+ Form ,
13
+ Link ,
14
+ Outlet ,
15
+ redirect ,
16
+ RouterProvider ,
17
+ useLoaderData ,
18
+ useLocation ,
19
+ } from ' react-router-dom' ;
20
+
21
+ // Method to introduce an artificial delay
22
+ export function sleep (n = 500 ) {
23
+ return new Promise ((r ) => setTimeout (r, n));
24
+ }
25
+
26
+ // Loader to return after a small delay
27
+ export async function homeLoader () {
28
+ await sleep ();
29
+ return {
30
+ message: ' home' ,
31
+ };
32
+ }
33
+
34
+ // Action to get user input
35
+ export async function aboutAction ({ request }) {
36
+ await sleep ();
37
+ let formData = await request .formData ();
38
+ let name = formData .get (' name' );
39
+ console .log (name);
40
+ // Call an async method to add and so on
41
+ return redirect (' /' );
42
+ }
43
+
44
+ export const About = () => {
45
+ return (
46
+ <>
47
+ < div> You are on the about page< / div>
48
+ < Form method= " post" >
49
+ < input name= " person" placeholder= " Name" / >
50
+ < button type= " submit" > Submit< / button>
51
+ < / Form>
52
+ < / >
53
+ );
54
+ };
55
+
56
+ export const Home = () => {
57
+ let data = useLoaderData ();
58
+ return < div> You are {data .message }< / div> ;
59
+ };
60
+
61
+ export const NoMatch = () => < div> No match< / div> ;
62
+
63
+ export const LocationDisplay = () => {
64
+ const location = useLocation ();
65
+
66
+ return < div data- testid= " location-display" > {location .pathname }< / div> ;
67
+ };
68
+
69
+ export const Layout = () => (
70
+ < div>
71
+ < Link to= " /" > Home< / Link>
72
+ < Link to= " /about" > About< / Link>
73
+ < Outlet / >
74
+ < LocationDisplay / >
75
+ < / div>
76
+ );
77
+
78
+ export const routes = [
79
+ {
80
+ path: ' /' ,
81
+ element: < Layout / > ,
82
+ children: [
83
+ {
84
+ index: true ,
85
+ element: < Home / > ,
86
+ loader: homeLoader,
87
+ },
88
+ {
89
+ path: ' /about' ,
90
+ element: < About / > ,
91
+ action: aboutAction,
92
+ },
93
+ {
94
+ path: ' *' ,
95
+ element: < NoMatch / > ,
96
+ },
97
+ ],
98
+ },
99
+ ];
100
+
101
+ const router = createBrowserRouter (routes);
102
+
103
+ const App = () => < RouterProvider router= {router}>< / RouterProvider> ;
104
+
105
+ export default App ;
106
+ ```
107
+
108
+ ``` jsx
109
+ // App.test.jsx
110
+ import { render , screen } from ' @testing-library/react' ;
111
+ import userEvent from ' @testing-library/user-event' ;
112
+ import React from ' react' ;
113
+ import ' @testing-library/jest-dom' ;
114
+ import {
115
+ createBrowserRouter ,
116
+ createMemoryRouter ,
117
+ RouterProvider ,
118
+ } from ' react-router-dom' ;
119
+ import { routes } from ' ./App' ;
120
+
121
+ test (' full app rendering/navigating' , async () => {
122
+ const router = createBrowserRouter (routes);
123
+ render (< RouterProvider router= {router}>< / RouterProvider> );
124
+
125
+ const user = userEvent .setup ();
126
+ // We need to wait for the loader data and then assert presence
127
+ expect (await screen .findByText (/ you are home/ i )).toBeInTheDocument ();
128
+
129
+ // verify page content for expected route after navigating
130
+ await user .click (screen .getByText (/ about/ i ));
131
+ expect (screen .getByText (/ you are on the about page/ i )).toBeInTheDocument ();
132
+ });
133
+
134
+ test (' landing on a bad page' , () => {
135
+ const badRoute = ' /some/bad/route' ;
136
+ const router = createMemoryRouter (routes, { initialEntries: [badRoute] });
137
+
138
+ // use createMemoryRouter when you want to manually control the history
139
+ render (< RouterProvider router= {router}>< / RouterProvider> );
140
+
141
+ // verify navigation to "no match" route
142
+ expect (screen .getByText (/ no match/ i )).toBeInTheDocument ();
143
+ });
144
+
145
+ test (' rendering a component that uses useLocation' , () => {
146
+ const route = ' /some-route' ;
147
+ const router = createMemoryRouter (routes, { initialEntries: [route] });
148
+
149
+ // use createMemoryRouter when you want to manually control the history
150
+ render (< RouterProvider router= {router}>< / RouterProvider> );
151
+
152
+ // verify location display is rendered
153
+ expect (screen .getByTestId (' location-display' )).toHaveTextContent (route);
154
+ });
155
+ ```
156
+ Refer to [ this working example] ( https://stackblitz.com/edit/vitejs-vite-dnutcg?file=src%2FApp.test.jsx,src%2FApp.jsx )
157
+
158
+ ## Testing Library and React Router v6
7
159
8
160
``` jsx
9
161
// app.js
0 commit comments