-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
prefetchQuery
in useHook()
for client components
#3
Comments
Yea I can add this today |
Can you show me an example of how you want to use this? I have some forms with initialValue and I simply don't render them if there isn't data available or isPending is true. You are trying to prefetch the session? What do you mean by add prefetchQuery in the useHook()? I want to make sure I cover this adequately for this use case |
I was thinking of a new hook like |
I'll try my best to explain. Let's say you have the following component where you are using the When you visit the relevant component next time, you'll see the form fields are being populated. export function UpdateUserEmailSettingsForm() {
const { user, isPending, refetch } = useSession();
const form = useForm<UpdateUserEmailSettingsFormValues>({
resolver: zodResolver(updateUserEmailSettingsSchema),
defaultValues: {
currentEmail: user?.email ?? "",
newEmail: "",
},
});
async function onSubmit(data: UpdateUserEmailSettingsFormValues) {
console.log(data)
}
if (isPending || !user)
return (
<div className="flex h-[50vh] items-center justify-center">
<Loader2 className="h-6 w-6 animate-spin" />
</div>
);
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-3">
<h3 className="mb-4 text-lg font-medium">Update Email Address</h3>
<div className="space-y-4 rounded-lg border p-4">
<FormField
control={form.control}
name="currentEmail"
render={({ field }) => (
<FormItem>
<FormLabel>Current Email</FormLabel>
<FormControl>
<Input placeholder="Current Email" {...field} />
</FormControl>
<FormDescription>Your current email address.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="newEmail"
render={({ field }) => (
<FormItem>
<FormLabel>New Email</FormLabel>
<FormControl>
<Input placeholder="Your New Email" {...field} />
</FormControl>
<FormDescription>
Enter the new email address you wish to use.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button
type="submit"
size={"sm"}
variant={"outline"}
disabled={
isPending ||
form.formState.isSubmitting ||
!form.formState.isValid ||
!form.formState.isDirty
}
>
{isPending || form.formState.isSubmitting ? (
<Loader2 className="animate-spin" />
) : (
"Update Email"
)}
</Button>
</div>
</form>
</Form>
);
} How can we solve this? There are a few ways:
Prefetching the user is only available from server side at this point from your package. But client side prefetching isn't an option yet. If I server side prefetching here and use client side prefetching in other components, they won't be sync when the data is mutated from the client side. So, I'd need to
const form = useForm<UpdateUserEmailSettingsFormValues>({
resolver: zodResolver(updateUserEmailSettingsSchema),
defaultValues: {
currentEmail: "",
newEmail: "",
},
});
useEffect(() => {
if (user) {
form.reset({
currentEmail: user.email ?? "",
newEmail: "",
});
}
}, [user, form]); Using the typical
Like the client side
Your proposal |
What I'm noticing from the Tanstack example linked is that the prefetching is for link hovers, etc. It doesn't actually prefetch on mount. I also don't think you want to prefetch on mount, since that would delay your rendering. I think adding prefetch on client side is still useful, but I don't think that is what you want for this form. Let's say you refresh the page on your form, the prefetch would either block the UI, and I don't think it's possible to prefetch client side (await in client component not supported) What I would do is instead move your form to a separate component called |
Aha, thanks for digging into this. Prefetching on the client side will still be helpful though in your package. As well as an option to refetch the server side prefetch that you are offering already. For now, I will use the suggestions you've shared or will stick to |
The "refetch" on server side prefetches should happen any time that that page SSR's, and since it uses headers it should be dynamic and refetching every render as is? The server side prefetch simply hydrates the new session into the useSession hook, and you can refetch it just fine there? |
Also if you want the user to be available on initial render, that's when you would do the SSR prefetch, the useSession hook will be populated on render, which would be behind a Suspense boundary |
Didn't work for me though when I used |
This is for rendering an email change? Or an authentication? This might be an issue with Next.js App Router cache |
I'm gonna spend today working on forms and testing everything with updating email & avatar image, and making sure it works well with either SSR, client side or hybrid, including clearing cookie cache when one of these is updated. I'll share my findings when I'm done. It might be needed to call router.refresh() even still (for SSR) or revalidatePath, this could be a Next.js issue where it caches the page in the App Router client side |
Great, I was testing it on the name and image for the user profile. Looking forward to the finding and the change you make on this 🙏 |
I've included examples on how to use updateUser mutate function. I'm gonna close this issue for now. Feel free to open another issue if anything else comes up. |
Can we please get
prefetchQuery
in theuseHook()
hook for the client components? TanStack doc shows an example here. This is a must need to fill up the default values when creating a form using React Hook FormuseForm()
hookdefaultValues: {}
. Otherwise, we need the typicaluseEffect()
to set the values.The text was updated successfully, but these errors were encountered: