[Docs]: for useSearchParams, functional updates should be explained in more detail
YakovL opened this issue · comments
Describe what's incorrect/missing in the documentation
Looking at https://reactrouter.com/en/main/hooks/use-search-params, one may think that to update one param while keeping the others, one can do:
const [searchParams, setSearchParams] = useSearchParams()
//...
const setPageNumber = (pageNumber: number) => setSearchParams(params => ({ ...params, page: String(pageNumber) }))
to update just the page
portion of the query. However, this doesn't work: it removes all the query params and sets just the the page
portion. (not sure if this is a bug or an intended behavior)
To work around this, one has to do:
const setPageNumber = (pageNumber: number) => setSearchParams(params => {
params.set('page', String(pageNumber))
return params
})
I think this is not trivial, and hence should be documented (unless it's a bug, I'm using 6.22.3).
URLSearchParams
is not a regular object, so you can't spread it like you normally would.
Instead, you need to convert the existing params into an object via Object.fromEntries()
const [searchParams, setSearchParams] = useSearchParams()
//...
const setPageNumber = (pageNumber: number) =>
setSearchParams(params => ({ ...Object.fromEntries(params), page: String(pageNumber) }))
https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams
IMHO the bigger undocumented caveat is that any mutation of searchParams
(the first array entry returned), e.g. searchParams.delete('page')
has the side effect of actually changing the URL.
Yeah, both are relevant: the Object.fromEntries
trick would be helpful there, and then an explanation of how to properly delete a param would be also useful. Is
setSearchParams(params => {
const queryParams = Object.fromEntries(params)
delete queryParams['page']
return queryParams
})
sufficient to avoid side-effects?