Page does not refresh data even though it uses no-store cache in Next JS 13.4

I use Next JS 13.4 and using app route. I am fetching the API use option cache no-store like this.

export const getBooks = () => new Promise(async (resolve, reject) => {
  const response = await fetch(process.env.API_BASE_URL + `/books`, { cache: 'no-store' });

  const data = await response.json();

  if (response.status >= 400) {
    reject(data);
  }

  resolve(data);
});

I use the data books at / URL. I update the data at the /books/[id]/edit URL and when success updating, I navigate the page to / with router.replace("https://stackoverflow.com/").

// '/books/[id]/edit'

const editBookMutation = useMutation({
    apiFn: (data) => updateBook(book.id, data),
    onSuccess: () => {
      router.replace("https://stackoverflow.com/");
    },
    onError: (error) => {
      toast.error(error.message);
    }
});

But after navigating to / URL, book data does not match the data that should be (The book data still matches the old data). I want to after navigating to / URL, API refetch again to gain fresh data from API.

To ensure that your data is refetched after navigating to the / URL in Next.js when using router.replace("https://stackoverflow.com/"), you can utilize the following approach:

  1. Use a state variable to trigger a re-render when the data should be refetched.
  2. After navigating back to /, update this state variable to trigger a re-render of the component that fetches the data.

Here’s an example of how you can implement this:

import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import { getBooks } from './yourApiFile'; // Import your API fetching function

function YourComponent() {
  const [refreshData, setRefreshData] = useState(false);
  const router = useRouter();

  useEffect(() => {
    if (refreshData) {
      // Fetch the data again when refreshData state changes
      getBooks()
        .then((data) => {
          // Handle the fetched data
          // Update your component's state with the new data
          // For example, you might have a state variable like "books" that you can update
          // setBooks(data);
        })
        .catch((error) => {
          // Handle errors
        })
        .finally(() => {
          // Reset the refreshData state after fetching
          setRefreshData(false);
        });
    }
  }, [refreshData]);

  const editBookHandler = () => {
    // Your edit book logic here

    // After successful edit, set refreshData to true to trigger a re-fetch
    setRefreshData(true);

    // Navigate back to "https://stackoverflow.com/"
    router.replace("https://stackoverflow.com/");
  };

  return (
    // Your component JSX here
  );
}

refreshData is a state variable that you can toggle to trigger a re-fetch of the data in your component. After successfully editing a book, you set refreshData to true, which will trigger the useEffect to refetch the data, ensuring that you get fresh data from the API when you navigate back to /.

Leave a Comment