react hook form filters

Hello doing filters using react-hook-form but having problems to run my update function, i would like to be able to push to url after some field changes, currently my update function does not run unless i make button for it, also any ideas/tips welcome: More info and code on comments!
1 Reply
rocawear
rocawear6mo ago
Page:
export const filtersSchema = z.object({
example: z.string().nullable(),
example2: z.string().nullable(),
})

const ExamplePage: NextPage = () => {
const { control, values, update } = useFilters({
schema: filtersSchema,
defaultValues: {
example: null,
example2: null,
},
})

return (
<PageContainer>
<form onSubmit={update}>
<Select
title="title"
placeholder="placeholder"
control={control}
label="example"
options={[
{ label: "option 1", value: "option 1" },
{ label: "option 2", value: "option 2" },
{ label: "option 3", value: "option 3" },
]}
/>
<Select
title="title"
placeholder="placeholder"
control={control}
label="example2"
options={[
{ label: "option 1", value: "option 1" },
{ label: "option 2", value: "option 2" },
{ label: "option 3", value: "option 3" },
]}
/>
<Button type="submit">submit</Button>
</form>
{JSON.stringify(values, null, 2)}
</PageContainer>
)
}
export const filtersSchema = z.object({
example: z.string().nullable(),
example2: z.string().nullable(),
})

const ExamplePage: NextPage = () => {
const { control, values, update } = useFilters({
schema: filtersSchema,
defaultValues: {
example: null,
example2: null,
},
})

return (
<PageContainer>
<form onSubmit={update}>
<Select
title="title"
placeholder="placeholder"
control={control}
label="example"
options={[
{ label: "option 1", value: "option 1" },
{ label: "option 2", value: "option 2" },
{ label: "option 3", value: "option 3" },
]}
/>
<Select
title="title"
placeholder="placeholder"
control={control}
label="example2"
options={[
{ label: "option 1", value: "option 1" },
{ label: "option 2", value: "option 2" },
{ label: "option 3", value: "option 3" },
]}
/>
<Button type="submit">submit</Button>
</form>
{JSON.stringify(values, null, 2)}
</PageContainer>
)
}
Hook:
type UseFiltersProps<Schema extends z.ZodTypeAny> = {
schema: Schema
defaultValues: DefaultValues<z.infer<Schema>>
}

export const useFilters = <Schema extends z.ZodTypeAny>({ schema, defaultValues }: UseFiltersProps<Schema>) => {
const { control, handleSubmit } = useForm<z.infer<Schema>>({
resolver: zodResolver(schema),
defaultValues,
})

const router = useRouter()
const values = useWatch({ control })

const update = (values: z.infer<Schema>) => {
const v = pickBy(values, (value) => value !== null)
router.push({ query: v }, undefined, { shallow: true })
}

return {
control,
values,
update: handleSubmit(update),
}
}
type UseFiltersProps<Schema extends z.ZodTypeAny> = {
schema: Schema
defaultValues: DefaultValues<z.infer<Schema>>
}

export const useFilters = <Schema extends z.ZodTypeAny>({ schema, defaultValues }: UseFiltersProps<Schema>) => {
const { control, handleSubmit } = useForm<z.infer<Schema>>({
resolver: zodResolver(schema),
defaultValues,
})

const router = useRouter()
const values = useWatch({ control })

const update = (values: z.infer<Schema>) => {
const v = pickBy(values, (value) => value !== null)
router.push({ query: v }, undefined, { shallow: true })
}

return {
control,
values,
update: handleSubmit(update),
}
}
Not sure how to trigger page push after value changes, also now if I submit with button it will reset my form