diff --git a/packages/one/src/router/router.ts b/packages/one/src/router/router.ts index bd9cf5d271..98764fdaf2 100644 --- a/packages/one/src/router/router.ts +++ b/packages/one/src/router/router.ts @@ -585,6 +585,7 @@ function getNavigateAction( const didActionAndCurrentStateDiverge = actionStateRoute.name !== stateRoute.name || + !deepEqual(actionStateRoute.params, stateRoute.params) || !childState || !nextNavigationState || (dynamicName && actionStateRoute.params?.[dynamicName] !== stateRoute.params?.[dynamicName]) diff --git a/tests/test/app/hooks/contents/_layout.tsx b/tests/test/app/hooks/contents/_layout.tsx index 58361a07d5..1e8f4c6b97 100644 --- a/tests/test/app/hooks/contents/_layout.tsx +++ b/tests/test/app/hooks/contents/_layout.tsx @@ -1,22 +1,24 @@ -import { Link, Slot, usePathname } from 'one' +import { Slot, useParams, usePathname } from 'one' import { View, Text } from 'tamagui' +import { HooksTestingLinks } from '~/features/hooks-testing/HooksTestingLinks' export default function HooksTestingLayout() { const pathname = usePathname() + const params = useParams() + return ( - Layout `usePathname()`: {pathname} + + Layout `usePathname()`: {pathname} + + + Layout `useParams()`:{' '} + {JSON.stringify(params)} + + - - Go to page-1 - - - Go to page-2 - - - Go to index - + ) } diff --git a/tests/test/app/hooks/contents/page-1.tsx b/tests/test/app/hooks/contents/page-1.tsx index c4e54d021b..c90c644e6d 100644 --- a/tests/test/app/hooks/contents/page-1.tsx +++ b/tests/test/app/hooks/contents/page-1.tsx @@ -1,13 +1,5 @@ -import { Link, usePathname } from 'one' -import { View, Text } from 'tamagui' +import { HooksTestingPageContent } from '~/features/hooks-testing/HooksTestingPageContent' export default function HooksTestingPage() { - const pathname = usePathname() - - return ( - - This is page-1 - Page `usePathname()`: {pathname} - - ) + return } diff --git a/tests/test/app/hooks/contents/page-2.tsx b/tests/test/app/hooks/contents/page-2.tsx index c4e54d021b..98f43cd029 100644 --- a/tests/test/app/hooks/contents/page-2.tsx +++ b/tests/test/app/hooks/contents/page-2.tsx @@ -1,13 +1,5 @@ -import { Link, usePathname } from 'one' -import { View, Text } from 'tamagui' +import { HooksTestingPageContent } from '~/features/hooks-testing/HooksTestingPageContent' export default function HooksTestingPage() { - const pathname = usePathname() - - return ( - - This is page-1 - Page `usePathname()`: {pathname} - - ) + return } diff --git a/tests/test/app/hooks/contents/with-nested-slug/[folderSlug]/[fileSlug]+ssr.tsx b/tests/test/app/hooks/contents/with-nested-slug/[folderSlug]/[fileSlug]+ssr.tsx new file mode 100644 index 0000000000..515bfde000 --- /dev/null +++ b/tests/test/app/hooks/contents/with-nested-slug/[folderSlug]/[fileSlug]+ssr.tsx @@ -0,0 +1,5 @@ +import { HooksTestingPageContent } from '~/features/hooks-testing/HooksTestingPageContent' + +export default function HooksTestingPage() { + return +} diff --git a/tests/test/app/hooks/contents/with-nested-slug/[folderSlug]/_layout.tsx b/tests/test/app/hooks/contents/with-nested-slug/[folderSlug]/_layout.tsx new file mode 100644 index 0000000000..be18fd6d6c --- /dev/null +++ b/tests/test/app/hooks/contents/with-nested-slug/[folderSlug]/_layout.tsx @@ -0,0 +1,22 @@ +import { Slot, useParams, usePathname } from 'one' +import { View, Text, HR } from 'tamagui' + +export default function HooksTestingSlugLayout() { + const pathname = usePathname() + const params = useParams() + + return ( + + + Slug layout `usePathname()`:{' '} + {pathname} + + + Slug layout `useParams()`:{' '} + {JSON.stringify(params)} + + + + + ) +} diff --git a/tests/test/app/hooks/contents/with-slug/[slug]+ssr.tsx b/tests/test/app/hooks/contents/with-slug/[slug]+ssr.tsx new file mode 100644 index 0000000000..0dfac61607 --- /dev/null +++ b/tests/test/app/hooks/contents/with-slug/[slug]+ssr.tsx @@ -0,0 +1,5 @@ +import { HooksTestingPageContent } from '~/features/hooks-testing/HooksTestingPageContent' + +export default function HooksTestingPage() { + return +} diff --git a/tests/test/app/hooks/index.tsx b/tests/test/app/hooks/index.tsx index 3323f41a5f..cb9ae4f5a0 100644 --- a/tests/test/app/hooks/index.tsx +++ b/tests/test/app/hooks/index.tsx @@ -1,18 +1,12 @@ -import { Link } from 'one' -import { View, Text } from 'tamagui' +import { View, H1 } from 'tamagui' +import { HooksTestingLinks } from '~/features/hooks-testing/HooksTestingLinks' export default function HooksTestingIndexPage() { return ( - - Go to page-1 - - - Go to page-2 - - - Go to index - +

Hooks Testing Index

+ +
) } diff --git a/tests/test/app/index.tsx b/tests/test/app/index.tsx index ab477993d5..827f7cd77e 100644 --- a/tests/test/app/index.tsx +++ b/tests/test/app/index.tsx @@ -46,6 +46,10 @@ export default () => { + + + + ) diff --git a/tests/test/features/hooks-testing/HooksTestingLinks.tsx b/tests/test/features/hooks-testing/HooksTestingLinks.tsx new file mode 100644 index 0000000000..12e4a0da01 --- /dev/null +++ b/tests/test/features/hooks-testing/HooksTestingLinks.tsx @@ -0,0 +1,33 @@ +import { Link } from 'one' +import { View, Text } from 'tamagui' + +export function HooksTestingLinks() { + return ( + + + Go to page-1 + + + Go to page-2 + + + + Go to with-slug/slug-page-foo + + + Go to with-slug/slug-page-bar + + + + Go to with-nested-slug/foo/bar + + + Go to with-nested-slug/abc/def + + + + Go to index + + + ) +} diff --git a/tests/test/features/hooks-testing/HooksTestingPageContent.tsx b/tests/test/features/hooks-testing/HooksTestingPageContent.tsx new file mode 100644 index 0000000000..be7760136d --- /dev/null +++ b/tests/test/features/hooks-testing/HooksTestingPageContent.tsx @@ -0,0 +1,23 @@ +import { useParams, usePathname } from 'one' +import { View, Text, H1 } from 'tamagui' + +type Props = { + pageName: string +} + +export function HooksTestingPageContent({ pageName }: Props) { + const pathname = usePathname() + const params = useParams() + + return ( + +

This is {pageName}

+ + Page `usePathname()`: {pathname} + + + Page `useParams()`: {JSON.stringify(params)} + +
+ ) +} diff --git a/tests/test/routes.d.ts b/tests/test/routes.d.ts index 23b6085d35..df8b9f449a 100644 --- a/tests/test/routes.d.ts +++ b/tests/test/routes.d.ts @@ -7,8 +7,8 @@ declare module 'one' { export namespace OneRouter { export interface __routes extends Record { StaticRoutes: `/` | `/(auth-guard)` | `/(auth-guard)/auth-guard` | `/(blog)` | `/(blog)/blog/my-first-post` | `/(marketing)/about` | `/(sub-page-group)` | `/(sub-page-group)/sub-page` | `/(sub-page-group)/sub-page/sub` | `/(sub-page-group)/sub-page/sub2` | `/_sitemap` | `/about` | `/auth-guard` | `/blog/my-first-post` | `/expo-video` | `/hooks` | `/hooks/contents` | `/hooks/contents/page-1` | `/hooks/contents/page-2` | `/layouts` | `/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]/` | `/loader` | `/loader/other` | `/middleware` | `/not-found/deep/test` | `/not-found/fallback/test` | `/not-found/test` | `/server-data` | `/sheet` | `/spa/spapage` | `/ssr/basic` | `/sub-page` | `/sub-page/sub` | `/sub-page/sub2` | `/web-extensions` - DynamicRoutes: `/dynamic-folder-routes/${OneRouter.SingleRoutePart}/${OneRouter.SingleRoutePart}` | `/layouts/nested-layout/with-slug-layout-folder/${OneRouter.SingleRoutePart}` | `/not-found/+not-found` | `/not-found/deep/+not-found` | `/routes/subpath/${string}` | `/segments-stable-ids/${string}` | `/spa/${OneRouter.SingleRoutePart}` | `/ssr/${OneRouter.SingleRoutePart}` | `/ssr/${string}` - DynamicRouteTemplate: `/dynamic-folder-routes/[serverId]/[channelId]` | `/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]` | `/not-found/+not-found` | `/not-found/deep/+not-found` | `/routes/subpath/[...subpath]` | `/segments-stable-ids/[...segments]` | `/spa/[spaparams]` | `/ssr/[...rest]` | `/ssr/[param]` + DynamicRoutes: `/dynamic-folder-routes/${OneRouter.SingleRoutePart}/${OneRouter.SingleRoutePart}` | `/hooks/contents/with-nested-slug/${OneRouter.SingleRoutePart}` | `/hooks/contents/with-nested-slug/${OneRouter.SingleRoutePart}/${OneRouter.SingleRoutePart}` | `/hooks/contents/with-slug/${OneRouter.SingleRoutePart}` | `/layouts/nested-layout/with-slug-layout-folder/${OneRouter.SingleRoutePart}` | `/not-found/+not-found` | `/not-found/deep/+not-found` | `/routes/subpath/${string}` | `/segments-stable-ids/${string}` | `/spa/${OneRouter.SingleRoutePart}` | `/ssr/${OneRouter.SingleRoutePart}` | `/ssr/${string}` + DynamicRouteTemplate: `/dynamic-folder-routes/[serverId]/[channelId]` | `/hooks/contents/with-nested-slug/[folderSlug]` | `/hooks/contents/with-nested-slug/[folderSlug]/[fileSlug]` | `/hooks/contents/with-slug/[slug]` | `/layouts/nested-layout/with-slug-layout-folder/[layoutSlug]` | `/not-found/+not-found` | `/not-found/deep/+not-found` | `/routes/subpath/[...subpath]` | `/segments-stable-ids/[...segments]` | `/spa/[spaparams]` | `/ssr/[...rest]` | `/ssr/[param]` IsTyped: true } } diff --git a/tests/test/tests/hooks.test.ts b/tests/test/tests/hooks.test.ts index 38d3eac5bd..4dbc9ca1da 100644 --- a/tests/test/tests/hooks.test.ts +++ b/tests/test/tests/hooks.test.ts @@ -58,3 +58,34 @@ test('hooks', async () => { await page.close() }) + +test('useParams in _layout', async () => { + const page = await context.newPage() + await page.goto(serverUrl + '/hooks') + + const link1 = await page.$('a[href="/hooks/contents/with-slug/slug-page-foo"]') + await link1?.click({ + force: true, + }) + await page.waitForURL('**/hooks/contents/with-slug/slug-page-foo', { timeout: 5_000 }) + const pageUseParamsJsonString1 = (await page.getByTestId('page-useParams').textContent()) || '{}' + const pageUseParamsJson1 = JSON.parse(pageUseParamsJsonString1) + expect(pageUseParamsJson1.slug).toBe('slug-page-foo') + const layoutUseParamsJsonString1 = + (await page.getByTestId('layout-useParams').textContent()) || '{}' + const layoutUseParamsJson1 = JSON.parse(layoutUseParamsJsonString1) + expect(layoutUseParamsJson1.slug).toBe('slug-page-foo') + + const link2 = await page.$('a[href="/hooks/contents/with-slug/slug-page-bar"]') + await link2?.click({ + force: true, + }) + await page.waitForURL('**/hooks/contents/with-slug/slug-page-bar', { timeout: 5_000 }) + const pageUseParamsJsonString2 = (await page.getByTestId('page-useParams').textContent()) || '{}' + const pageUseParamsJson2 = JSON.parse(pageUseParamsJsonString2) + expect(pageUseParamsJson2.slug).toBe('slug-page-bar') + const layoutUseParamsJsonString2 = + (await page.getByTestId('layout-useParams').textContent()) || '{}' + const layoutUseParamsJson2 = JSON.parse(layoutUseParamsJsonString2) + expect(layoutUseParamsJson2.slug).toBe('slug-page-bar') +})