Closed okanji closed 2 months ago
Maybe this is a different approach I could use? Any help would be appreciated.
I am not sure if this helps but usually i call router.refresh()
after router.push()
. But it is not 100% always works in dev environment (next dev
)
Okay router.refresh() works! Is this the intended/ best way way to do things?
I also have this issue. I call revalidate(..) and then redirect(...) inside of a server action, which worked in localhost on version 13.4.13 but ceased working on localhost when I updated to version 13.5.3, even in a local production build
HOWEVER, this same code ran in my production deployment on Vercel still works - despite the build being on version 13.5.3 as well
To answer the router.refresh() question - no, it's been an extremely hacky solution since the App router got released. Due to App router's forced caching - which seems to be biting us here yet again, bug or otherwise - people have been struggling to provide the user with the latest data, this gets recommended sometimes but it is way off the "intended" or optimal solution
I see, hopefully we get a more solid solution in the near future!
Hi, in my opinion revalidation works perfectly fine both for Server Actions and when handling form submissions manually.
When handling form submissions manually as @okanji's example you can use startTransition
or useTransition
to ensure that revalidation and navigation is happening in one elemental step regarding rendering in React. This will ensure that the new data is available for the ui when the navigation happens. Depending on your caching configuration it might be possible that your route handler/api route has to call revalidatePath
or revalidateTag
to clear any other cache than the Router Cache.
So, the Router Cache is cleared by router.refresh
, the other cache layers have to be revalidated via the Server-side functions revalidatePath
or revalidateTag
as that can conceptually not happen on the client:
"use client";
import React, { useState, startTransition } from "react";
import { useRouter } from "next/navigation";
function SimpleForm() {
const router = useRouter();
const [formData, setFormData] = useState({
text: "",
});
const [loading, setLoading] = useState(false);
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value,
});
};
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
await fetch("api/create-post", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ text: formData.text }),
});
setLoading(false);
startTransition(()=>{
router.refresh();
router.push("/server-page");
})
};
return (
<div>
When using Server Actions as described by @D34THNOTE revalidatePath
or revalidateTag
should be used over revalidate
:
'use server'
import { redirect } from 'next/navigation'
import { revalidateTag } from 'next/cache'
export default async function submit() {
const id = await addPost()
revalidateTag('posts') // Update cached posts
redirect(`/post/${id}`) // Navigate to new route
}
Here are some resources that will explain stuff in detail:
I think the documentation is quite good and comprehensive and from 13.5.x
onwards the app router works really nice.
I believe this should be resolved on the latest version. Please try it out and let me know, and open a new issue if you are still seeing something. Thank you!
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.
Link to the code that reproduces this issue
https://github.com/okanji/revalidate-issue
Unable to revalidate a server rendered page that fetches db data via prisma when I re direct to it and the url is the same (i.e it is not dynamic and does not have any search params).
I need to manually re fresh the page to trigger the server component to re render and fetch the updated posts.
To Reproduce
See the sandbox: https://codesandbox.io/p/github/okanji/revalidate-issue/main?workspaceId=7c867f2b-0006-4b92-93b6-ae684cf1b42c
Current vs. Expected behavior
Current
I am using the following route segment config options in my server component.
This is in my client page where I navigate to the server page that shows all the posts. The relevant part is the
router.push
:Expected
I expect that when I programmatically navigate to this page using
router.push("/server-page");
from my client rendered page, the server page should re render and re fetch the data from the data base and show this new data (with my new post).This is not the case. I manually need to refresh the page for it to update.
Verify canary release
Provide environment information
Which area(s) are affected? (Select all that apply)
App Router, Data fetching (gS(S)P, getInitialProps), Routing (next/router, next/navigation, next/link)
Additional context
No response