Table of contents
Next.js 13 app directory is great for building full-stack web applications. However, the caching system is not good "yet". Let me show you the exact problem.
Problem
For example, you want to have a form in the /add
route to store some data in the database. Then, you want to redirect to the /list
route where all the data stored in the database is shown. So the problem is when we get redirected to /list
, Next.js is not re-fetching the data, and showing old data that doesn't have the new data created in the previous route.
We can simply test it by calling Math.random()
function. Here's an example of the demo.
page.tsx
import Link from 'next/link'
export default function Home() {
return (
<div>
<Link href="/about">Go to About</Link>
</div>
)
}
about/page.tsx
import Link from 'next/link'
export default function About() {
return (
<div>
<div>{Math.random()}</div>
<Link href="/">Go to Home</Link>
</div>
)
}
So now when we open the home page and click on "Go to About", it should show a random number.
This is fine, but when we click on "Go to Home" and click on "Go to About" again, it shows the same number. Because Next.js hard caching it, it's not re-fetching the route and showing the old cache. This is a bug in Next.js and has no official fixes.
Solution
As per Next.js docs, we can use router.refresh()
to make a new request to the server, re-fetch data requests, and re-render Server Components.
router.refresh()
: Refresh the current route. Making a new request to the server, re-fetching data requests, and re-rendering Server Components. The client will merge the updated React Server Component payload without losing unaffected client-side React (e.g.useState
) or browser state (e.g. scroll position).
So let's create a client component called force-refresh.tsx
and in the useEffect
function we can refresh the route. Now in the /about
route, you can simply import the component and it should work fine.
'use client'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'
export function ForceRefresh() {
const router = useRouter()
useEffect(() => {
router.refresh()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return null
}
What this will do is that whenever the page is visited, it will make a new request to the server, and re-fetch the data.
Conclusion
I hope Next.js will fix this bug as soon as possible. This bug has overwhelmed many developers including me.