Search Params -Date parsing
We’re currently working through some filters that put a date range as two separate search Params. In our Zod validator we’re converting the date strings to Date objects exposed over useSearch. Is that a great practice or should we be doing that conversion in the select method of useSearch as a better practice.
I’m mostly asking due to a big we introduced where leveraging previous params caused the Date object to be passed in when it needed to be conveyed to an ISO8601 date format.
10 Replies
deep-jade•11mo ago
I would not create Date objects in useSearch's select, since it will interfere with structural sharing we are in the process of adding
cc @Chris Horobin
would also not use search validation for this
ratty-blushOP•11mo ago
Perfect. Just thought I’d ask before going to far down a path.
In the case of structural sharing in select, is it ok to just return a different data object or new properties? Opting for dateParsed rather than overriding the search definition?
deep-jade•10mo ago
now that we have released
structuralSharing
, please have a look at https://tanstack.com/router/latest/docs/framework/react/guide/render-optimizations#structural-sharing-with-fine-grained-selectorsTanStack | High Quality Open-Source Software for Web Developers
Headless, type-safe, powerful utilities for complex workflows like Data Management, Data Visualization, Charts, Tables, and UI Components.

exotic-emerald•6mo ago
Hi. I came across similar issue. I want to pass [startDate, endDate] in an array to trpc procedure.
I am doing this
In zod schema.
createdAt: fallback(z.date().array().max(2), [oldDate, new Date()])
.default([oldDate, new Date()]),
const search = Route.useSearch();
const data = [new Date(), new Date()];
navigate({
search: { createdAt: data },
replace: true,
});
I can see the url search params get changed but it doesnt rerender the component. search is not getting updated.
I tried with test:Date. Same issue
I tried [string, string]. It works fine.
Is there any correct way to do the dates in url or i should just use iso string in url.
@Manuel Schillerdeep-jade•6mo ago
not sure, can you please provide a complete minimal example?
exotic-emerald•6mo ago
import { createFileRoute } from "@tanstack/react-router";
import { fallback, zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
let oldDate = new Date();
// 1 month ago
oldDate = new Date(oldDate.getTime() - 30 * 24 * 60 * 60 * 1000);
const validatorSchema = z.object({
createdAt: fallback(z.date().array().max(2), [oldDate, new Date()]).default([
oldDate,
new Date(),
]),
sArr: fallback(z.string().array().max(2), ["test", "test2"]).default([
"test",
"test2",
]),
});
export const Route = createFileRoute("/test/")({
component: Home,
errorComponent: (error) => <div>{error.error.message}</div>,
validateSearch: zodValidator(validatorSchema),
});
function Home() {
const navigate = Route.useNavigate();
const search = Route.useSearch();
return (
<div className="p-2">
<pre>{JSON.stringify(search, null, 2)}</pre>
<button
onClick={() => {
navigate({
search: (prev) => ({
...prev,
createdAt: [new Date(), new Date()],
}),
});
}}
>
Date Test
</button>
<button
onClick={() => {
navigate({
search: (prev) => ({
...prev,
sArr: [
test ${Math.random().toFixed(2)},
test2 ${Math.random().toFixed(2)},
],
}),
});
}}
>
String Array Test
</button>
</div>
);
}
exotic-emerald•6mo ago
exotic-emerald•6mo ago
When i update the string array. It correctly reflects on dom element
const search = Route.useSearch();
but when i update date it only updates in search params
Hi any update on this?
deep-jade•6mo ago
so i played with this, seems the
Date
instance does not play well with replaceEqualDeep
we use internallydeep-jade•6mo ago
since we dont offer customization (yet?) like query does (see https://github.com/TanStack/query/discussions/3559) your best bet is just to use a string
GitHub
Special case
Date
instances in replaceEqualDeep
function · Tan...If my query returns a Date instance then it means that every time that query gets refetched it will over-write the existing Date instance in the cache with a new one even if both Date instances are...