Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #1265 Updated example for react-router v6.4 #1266

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 153 additions & 1 deletion docs/example-react-router.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,159 @@ id: example-react-router
title: React Router
---

This example demonstrates React Router v6. For previous versions see below.
This example demonstrates React Router v6.4 and above. For previous versions see below.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very familiar with this, but I assume createBrowserRouter is added in v6.4?


```jsx
// App.jsx
import {
createBrowserRouter,
Form,
Link,
Outlet,
redirect,
RouterProvider,
useLoaderData,
useLocation,
} from 'react-router-dom';

// Method to introduce an artificial delay
export function sleep(n = 500) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you clean this example up please?
sleep doesn't really add any value here, it's just introduces clutter.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is a modified form of the example in react router examples source code I wanted this to be close to the original doc and hence left it.

return new Promise((r) => setTimeout(r, n));
}

// Loader to return after a small delay
export async function homeLoader() {
await sleep();
return {
message: 'home',
};
}

// Action to get user input
export async function aboutAction({ request }) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can also be left out, or there should be a test that verifies its behavior.

await sleep();
let formData = await request.formData();
let name = formData.get('name');
console.log(name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

// Call an async method to add and so on
return redirect('/');
}

export const About = () => {
return (
<>
<div>You are on the about page</div>
<Form method="post">
<input name="person" placeholder="Name" />
<button type="submit">Submit</button>
</Form>
</>
);
};

export const Home = () => {
let data = useLoaderData();
return <div>You are {data.message}</div>;
};

export const NoMatch = () => <div>No match</div>;

export const LocationDisplay = () => {
const location = useLocation();

return <div data-testid="location-display">{location.pathname}</div>;
};

export const Layout = () => (
<div>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Outlet />
<LocationDisplay />
</div>
);

export const routes = [
{
path: '/',
element: <Layout />,
children: [
{
index: true,
element: <Home />,
loader: homeLoader,
},
{
path: '/about',
element: <About />,
action: aboutAction,
},
{
path: '*',
element: <NoMatch />,
},
],
},
];

const router = createBrowserRouter(routes);

const App = () => <RouterProvider router={router}></RouterProvider>;

export default App;
```

```jsx
// App.test.jsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import '@testing-library/jest-dom';
import {
createBrowserRouter,
createMemoryRouter,
RouterProvider,
} from 'react-router-dom';
import { routes } from './App';

test('full app rendering/navigating', async () => {
const router = createBrowserRouter(routes);
render(<RouterProvider router={router}></RouterProvider>);

const user = userEvent.setup();
// We need to wait for the loader data and then assert presence
expect(await screen.findByText(/you are home/i)).toBeInTheDocument();

// verify page content for expected route after navigating
await user.click(screen.getByText(/about/i));
expect(screen.getByText(/you are on the about page/i)).toBeInTheDocument();
});

test('landing on a bad page', () => {
const badRoute = '/some/bad/route';
const router = createMemoryRouter(routes, { initialEntries: [badRoute] });

// use createMemoryRouter when you want to manually control the history
render(<RouterProvider router={router}></RouterProvider>);

// verify navigation to "no match" route
expect(screen.getByText(/no match/i)).toBeInTheDocument();
});

test('rendering a component that uses useLocation', () => {
const route = '/some-route';
const router = createMemoryRouter(routes, { initialEntries: [route] });

// use createMemoryRouter when you want to manually control the history
render(<RouterProvider router={router}></RouterProvider>);

// verify location display is rendered
expect(screen.getByTestId('location-display')).toHaveTextContent(route);
});
```
Refer to [this working example](https://stackblitz.com/edit/vitejs-vite-dnutcg?file=src%2FApp.test.jsx,src%2FApp.jsx)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because other examples don't have a stackblitz I was thinking on removing this?

Copy link
Author

@maruhgar maruhgar Aug 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Te reason for having that was, I couldn't get other examples to run without making code changes


## Testing Library and React Router v6

```jsx
// app.js
Expand Down