So at this point,
we've seen in detail
how we can manage caching
when sending requests to external APIs.
But of course, in the previous sections,
we also learned that often
you might not need to communicate
with external APIs.
You might not be using this fetch function
and therefore, in this and the next lectures,
I'll show you how you can still take advantage of caching
and control caching when using another data source
like a database to which you directly reach out
from inside your next application.
Therefore, to get started,
I'll comment out this code where I sent this fetch request
and instead, I will call getMessages here
in my MessagesPage
and getMessages is a function from the lib folder.
So this folder and this file in there.
And in there, I'm managing a simple SQLite database.
I got a function for inserting messages
and I got a function for getting data from the database.
And these are indeed synchronous functions right now
because this better-sqlite free package,
which I'm using for interacting with the database,
indeed does not need promises,
does not need asynchronous code,
and therefore there is no async here.
And hence, we actually also don't have to await this here.
We can even remove async here
if we want to on this component.
So with that, we'll then get our messages here,
which we can output and I can do the same
in my layout.
There, I also no longer wanna fetch my messages like this.
Instead, we can remove async here as well
and get the messages by calling getMessages,
which is that same function from the lib folder.
Now with that,
if I saved it and reload, I got no messages right now,
but that's why I have this addMessage function here.
And I now want to call this function again
from inside this server action in the NewMessages page
and pass the message that has been entered
by the user to addMessage.
And that should add a new message.
And therefore, with this re-added to the code,
if I go here and add a new message like test,
it shows up on that messages page.
If I add test two, that also shows up here.
And the fact
that these messages show up here proves
that there seems to be no caching going on here,
though that's not entirely true.
If you recall, once we start building this application
for production by npm run build,
we do get that page pre-rendering again
and we get that full route cache
unless you set one of these settings here
and force this page to be dynamic, for example.
But otherwise, we get this full route cache
and therefore, when building this for production,
we indeed have the problem that we see any messages,
any data that existed at build time,
but if we add a new message thereafter,
that indeed does now not show up.
So we do have some caching here,
we have that full route cache,
but we don't have that data cache.
We don't have the request deduplication
when using our own custom data source.
Now we'll fix that problem here
of the updated data not appearing
due to the full route cache later.
For now, I'll go back to my development server
and I'll focus on the request deduplication.
And on that full route cache first.
We can also stop that backend server here, by the way.
So my Next.js development server is running again,
and that indeed means
that with the development server,
we see all the updated data
because we don't have that full route cache here.
But it also means if we take a look at the logs here,
that we actually hit the database every time
I reload this page,
and we indeed always hit it twice
because I'm fetching the same messages
both from inside the page and the layout.
It's the same request which triggers
the same SQL command here,
the same query,
but we run this twice because we send it
in two different places.
We got no request deduplication going on here
because we're not using the fetch function
and out of the box,
Next.js only supports that for the next function.
But we can make this request deduplication work
for our own data fetching code
that uses our own data source
with help of another function
that can be imported from React.
So not from Next, but from React.
And from that React library,
we can import a cache function.
Now, this cache function is meant to be wrapped
around one of your functions
for which request deduplication should then occur.
And you can easily use that cache function
by wrapping it around getMessages, like this.
Now, this is now not valid code.
So what we should do here is we should create
a new constant call getMessages
and set that equal to that cached function,
and that's now valid again.
Now, if you do that
and you reload this page, everything works as before.
But what you'll notice is that now, if I clear that here
and rerun my development server,
if I reload this messages page,
there is just one request to the database.
Now we see that one request for every reload I perform,
but it's just one request per page reload instead of two,
because this cache function,
which is provided by React,
when wrapped around one of our functions,
indeed make sure that under the hood,
React cache is the data returned
by that function when it's called the first time
anywhere in our application,
inside of one single request cycle.
And then the response
by that function is reused in all the places
that also call that function
in that same single request cycle.
So if I reload the page
and therefore both the layout component
and the page component are executed in the end
during development,
I make two calls to the getMessages function.
But thanks to this cache function,
only one call is executed
and then the response or the result of the call
is stored and reused for the second call.
So we can therefore enable request deduplication
with our own data source
and our own functions with help of the cache function
provided by React.