-
-
Notifications
You must be signed in to change notification settings - Fork 213
Description
Context
What's your version of nuqs?
"nuqs": "^2.4.3"
What framework are you using?
✅ React SPA (no router)
✅ React Router
Which version of your framework are you using?
"react": "19.0.0"
"react-dom": "19.0.0"
"react-router": "7.1.5"
Description
When using parseAsDateTime on a singular field, null works fine — calling setState(null) bypasses the serializer, so no errors occur (as in the docs examples).
However, when wrapping parseAsDateTime in parseAsArrayOf (e.g., for date ranges), the serializer fails if any array element is null or undefined. This happens because the serializer calls .toISOString() on a nullish value.
Example:
parseAsArrayOf(parseAsDateTime)
// Intended to handle: [Date, undefined]
Instead, it throws because undefined (or null) is passed to .toISOString().
Relevant parser code (parseAsIsoDateTime):
export const parseAsIsoDateTime: ParserBuilder<Date> = createParser({
parse: v => {
const date = new Date(v)
if (Number.isNaN(date.valueOf())) {
return null
}
return date
},
serialize: (v: Date) => v.toISOString(),
eq: compareDates
})
Why it fails:
In array contexts, each element is run through serialize without checking for null/undefined. Standalone parseAsDateTime works fine because null never hits the serializer.
Suggested fix:
serialize: (v: Date | null | undefined) => (v === null || v === undefined ? '' : v.toISOString()),
This ensures that nullish values inside arrays are handled consistently.
Note:
This issue is likely not limited to parseAsDateTime. Other built-in parsers without nullish checks in serialize may behave the same when used inside parseAsArrayOf.
Reproduction
Steps to reproduce:
Create a state with useQueryStates using parseAsArrayOf(parseAsDateTime).
Set the value to [new Date(), undefined] or [new Date(), null].
Observe that .toISOString() is called on the nullish value, causing an error.
Minimal example:
const [dateRange, setDateRange] = useQueryStates({
range: parseAsArrayOf(parseAsDateTime)
});
// This will throw
setDateRange({ range: [new Date(), undefined] });