I have an odd issue I am dealing with. I have this useEffect function which is supposed to run on my program’s start to check that they are logged in, and generate a dynamic element, named lists. Code is below:
// Initial Effect: Fetch access and lists data on component mount
useEffect(() => {
console.log('Running on launch!')
getAccess();
getLists();
}, []);
I am expecting this to run getLists() everytime the page is loaded. This is because our users can interact with the lists — they can add items to it and delete items (which updates our Postgres backend). I always want to dynamically pull the latest version of lists.
The function and route are shown below.
// Fetch list data from the server
const getLists = async () => {
const data = await fetch("/api/prospects/getLists/");
const json_data = await data.json();
console.log(json_data);
setLists([...json_data]);
};
"use server";
import * as db from "../../../../lib/db"
import { NextRequest, NextResponse } from 'next/server';
export async function GET(req: NextRequest) {
const list = await db.query(`
SELECT id, name FROM "List"
ORDER BY name ASC
`, []);
return NextResponse.json(list.rows);
}
However, let’s say I add an element to the list and then refresh my page. I can verify the useEffect function is being called as I see "Running on launch!" executed in my console. However, the console.log where we log the json_data will ALWAYS show the original state of the list table. If I start the program with 5 elements in list, and add a sixth, no matter how many times I refresh the page, it is showing me that my route is only returning the original 5 elements. Same issue with deletion. It never gets updated.
Importantly, I confirmed that my postgres table is indeed taking the changes in real time. So it isn’t an issue with adding or deletion.
How do I fix it so it dynamically always pulls the latest version of the List table on refresh?
It should also be important to note it works correctly in my development environment, but if I build it using npm run build on my local machine, or push it to github to my live version on vercel, then this issue happens.
I also confirmed that if I hit the API route directly in my browser: http://localhost:3000/api/prospects/getLists, that it doesn’t show the updated list either.
3
Answers
Next.js refreshes the API routes every time a request is made. You have to disable caching in you api route. You can do something like this.
Then console log to check it is still caching.
Otherwise, if you don’t like that approach, you can try dynamic updating with getServerSideProps or maybe re-fetch the data on the client side with intervals. All in all, this should work for this purpose.
It looks like you’re having a caching issue, especially given that the problem occurs only in the production environment. Here’s a solution to ensure that the
getLists
function always fetches the most recent data.Disable Caching for the API Route
To prevent caching of the API response, you can explicitly set the cache headers in your API route. Modify your GET handler to include the appropriate headers:
You need to disable caching if you are having a complete dynamic page where things change quite often. Or you might want to add a re validate time to the page.
So, basically the above code will re validate the cache in 60 seconds. You can set it as per your requirement.
The above line code should be in a page directly exported. You can have look in the below code for more context.