@@ -3,7 +3,159 @@ id: example-react-router
33title : React Router
44---
55
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
7159
8160``` jsx
9161// app.js
0 commit comments