Ensure useParams return array for catch-all routes (#52494)

## What?

Ensures `useParams` matches `params` passed to the page, also matches the docs.

Fixes #50856
Fixes NEXT-1419
This commit is contained in:
Tim Neutkens 2023-07-10 14:04:44 +02:00 committed by GitHub
parent cf08f60077
commit 73e2979cb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 2 deletions

View file

@ -127,7 +127,7 @@ export function useRouter(): import('../../shared/lib/app-router-context').AppRo
}
interface Params {
[key: string]: string
[key: string]: string | string[]
}
// this function performs a depth-first search of the tree to find the selected
@ -144,7 +144,13 @@ function getSelectedParams(
const segmentValue = isDynamicParameter ? segment[1] : segment
if (!segmentValue || segmentValue.startsWith('__PAGE__')) continue
if (isDynamicParameter) {
// Ensure catchAll and optional catchall are turned into an array
const isCatchAll =
isDynamicParameter && (segment[2] === 'c' || segment[2] === 'oc')
if (isCatchAll) {
params[segment[0]] = segment[1].split('/')
} else if (isDynamicParameter) {
params[segment[0]] = segment[1]
}

View file

@ -0,0 +1,13 @@
'use client'
import { useParams } from 'next/navigation'
export default function Page() {
const params = useParams()
if (params === null) {
return null
}
return (
<div>
<div id="params">{JSON.stringify(params.path)}</div>
</div>
)
}

View file

@ -16,6 +16,11 @@ createNextDescribe(
expect($('#param-id2').text()).toBe('b')
})
it('should work for catch all params', async () => {
const $ = await next.render$('/a/b/c/d/e/f/g')
expect($('#params').text()).toBe('["a","b","c","d","e","f","g"]')
})
it('should work for single dynamic param client navigating', async () => {
const browser = await next.browser('/')
expect(