ProNextJS
    Professional Next.js Course
    Loading price
    30-Day Money-Back Guarantee
    lesson

    File Caching Behavior

    Jack HerringtonJack Herrington

    Implementing a Dynamic File Counter

    In this example, we have a dynamic file counter that is not yet implemented. Our goal is to implement it by using the original version from our stock-15-caching and copying that to the file versions. We'll be working with file-counter-cache and file_counter_dynamic, and we will convert them one by one.

    The count comes from a local file called count.json, which is a JSON file that contains the count.

    To refresh the page automatically when the button is clicked, we will use revalidate_path. Since we don't want to cache anything on this page.

    What's happening in the code?

    In our Counter function, we read the count.json file and put the count inside. We then create a server function called increment using "use server". Inside this function, we get the initial count, add one to it, and write it out. We expire the path, and we only do this because we want the page to automatically re-render.

    export default function FileCounterDynamic() {
      async function increment() {
        "use server";
    
        const count = JSON.parse(fs.readFileSync("count.json", "utf8"));
        count.count += 1;
        fs.writeFileSync("count.json", JSON.stringify(count, null, 2));
    
        expirePath("/file-counter-dynamic");
      }
    

    For the UI, we simply have the counter and the increment button.

    The dynamic file counter works as expected when we hit the increment button. However, it didn't auto-detect that we have dynamic data in there. To fix this, simply wrap the dynamic data in a Suspense component and import Suspense from React.

    Using Cache

    Now let's take a look at the cached version of the dynamic file counter. We're currently using an unstable cache to cache the file access, but we want to improve that.

    import { unstable_cacheTag as cacheTag, expireTag } from "next/cache";
    ...
    
    const getCount = async () => {
        "use cache";
        cacheTag("counter");
    
        const count = JSON.parse(fs.readFileSync("count.json", "utf8"));
        return count.count;
    };
    

    So we can reload the page a million times, and that counts always going to remain the same until we hit that increment button, and then it's going to go up to the next value, and then again, that's going to be cached until the end of time.

    All right, next up, we're going to take a look at how to handle caching when it comes to fetches. Generally speaking, you've got an XJS system connecting with a microservice set on the backend, and you're doing a lot of fetches. So how to cache those fetches is very important. We'll walk through all of those scenarios in the next video.

    Transcript

    All right. So back in our example, we got this dynamic file counter. Let's go and implement on that because currently, it's not found. So let's go and implement that by taking the original version from our stock 15 caching and then copying that to the file versions. So this file counter cached and file counter dynamic, and copying those into the app directory, and one by one, we will convert them.

    Okay. So our goal is to never cache the count. Well, where does the count come from? Well, the count comes from a local file called count.json, JSON file that has a count in it. Now, let's go back here and let's see.

    So we're going to use RevalidatePath. We're only going to use RevalidatePath because we're not actually going to cache anything on this page. We just want to automatically refresh the page when you hit the button. So we're going to use expire path, and we'll change out expire path. Now, what's this actually doing?

    Well, so over in our counter RSC, we're reading that count.json file and then putting in the count. Then we create a server function called increment. We do that by saying use server. Then inside of that function, we get the initial count, we add one to it, and then we write it out. Then we expire the path, and we're only expiring the path because we want the page automatically re-render.

    Then for UI, we just have the counter and then the increment button. Let's hit save and let's see what we get. So we go to File, Counter, Dynamic and we'll hit increment and there you go, looks good. Now, it didn't seem to auto-detect that we have dynamic data in there. Again if it does in the future just wrap that in a suspense, bring in suspense from React, and you'll be good to go.

    Alright let's take a look at our cached version of this. So currently, we're using unstable cache to cache this file access. So yay, we can get rid of that. So now in this one, we're going to cache that count and we're going to invalidate by tag. So what do we need to do?

    Well, we need to say that we are going to specify that we are specifying that cache by a tag, and then we're going to expire that tag. So let's go and change revalidate tag to expire tag. Now, the tag itself is called counter. So all we need to do in here is set that to be get count. Say that we want to use a cache, and that cache tag is counter.

    Let's hit Save. Now go to File, Counter, Cached with Tag. And There we go. So we can hit this a million times and that counts always going to remain the same until we hit that increment button and then it's going to go up to the next value and then again that's going to be cached until the end of time. All right.

    Next up, we're going to take a look at how to handle caching when it comes to fetches. I think this is what everybody's been waiting for. Generally speaking you've got an XJS system connecting with a microservice set on the back end and you're doing a lot of fetches so how to cache those fetches is very important. Let's walk through all of those scenarios in the next video.