From 792a761d7173433238551defc5c4d3a177d90af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Best?= Date: Thu, 16 Jan 2025 15:08:57 +0100 Subject: [PATCH] test: Reuse the route component in React Router v6 See #862. --- .../v6/cypress/e2e/repro-862.cy.ts | 36 ++++++++++++ .../e2e/react-router/v6/src/react-router.tsx | 10 +++- .../react-router/v6/src/routes/repro-862.tsx | 55 +++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 packages/e2e/react-router/v6/cypress/e2e/repro-862.cy.ts create mode 100644 packages/e2e/react-router/v6/src/routes/repro-862.tsx diff --git a/packages/e2e/react-router/v6/cypress/e2e/repro-862.cy.ts b/packages/e2e/react-router/v6/cypress/e2e/repro-862.cy.ts new file mode 100644 index 00000000..e84aef3c --- /dev/null +++ b/packages/e2e/react-router/v6/cypress/e2e/repro-862.cy.ts @@ -0,0 +1,36 @@ +/// + +import { createTest } from 'e2e-shared/create-test' + +const testRepro862RouteComponentReuse = createTest( + 'Repro for issue #862 - Route component reuse', + ({ path }) => { + it('clears state when navigating to another route with the same component but no search params', () => { + cy.visit(path) + cy.contains('#hydration-marker', 'hydrated').should('be.hidden') + cy.get('#setup').click() + cy.get('#navigate-clear').click() + cy.get('#state').should('be.empty') + cy.location('search').should('be.empty') + }) + + it('persists state when navigating to another route with the search params in the target navigation', () => { + cy.visit(path) + cy.contains('#hydration-marker', 'hydrated').should('be.hidden') + cy.get('#setup').click() + cy.get('#navigate-persist').click() + cy.get('#state').should('have.text', 'pass') + cy.location('search').should('eq', '?test=pass') + }) + } +) + +testRepro862RouteComponentReuse({ + path: '/repro-862/useQueryState', + hook: 'useQueryState' +}) + +testRepro862RouteComponentReuse({ + path: '/repro-862/useQueryStates', + hook: 'useQueryStates' +}) diff --git a/packages/e2e/react-router/v6/src/react-router.tsx b/packages/e2e/react-router/v6/src/react-router.tsx index 702acce0..caced029 100644 --- a/packages/e2e/react-router/v6/src/react-router.tsx +++ b/packages/e2e/react-router/v6/src/react-router.tsx @@ -6,6 +6,10 @@ import { RouterProvider } from 'react-router-dom' import RootLayout from './layout' +import { + Repro862UseQueryState, + Repro862UseQueryStates +} from './routes/repro-862' // Adapt the RRv7 / Remix default export for component into a Component export for v6 function load(mod: Promise<{ default: any; [otherExports: string]: any }>) { @@ -47,7 +51,11 @@ const router = createBrowserRouter( {/* Reproductions */} - + + } /> + } /> + } /> + } /> )) diff --git a/packages/e2e/react-router/v6/src/routes/repro-862.tsx b/packages/e2e/react-router/v6/src/routes/repro-862.tsx new file mode 100644 index 00000000..b98bc53b --- /dev/null +++ b/packages/e2e/react-router/v6/src/routes/repro-862.tsx @@ -0,0 +1,55 @@ +import { parseAsString, useQueryState, useQueryStates } from 'nuqs' +import { useNavigate } from 'react-router-dom' + +type Repro862Props = { + targetPath: string +} + +export function Repro862UseQueryState({ targetPath }: Repro862Props) { + const navigate = useNavigate() + const [state, setState] = useQueryState('test') + return ( + <> + + + +
{state}
+ + ) +} + +export function Repro862UseQueryStates({ targetPath }: Repro862Props) { + const navigate = useNavigate() + const [{ state }, setState] = useQueryStates( + { + state: parseAsString + }, + { urlKeys: { state: 'test' } } + ) + return ( + <> + + + +
{state}
+ + ) +}