This here is basically an example
I showed you earlier in this module already.
This is a standard React App,
not using Next.js at all,
which uses a very traditional approach
of sending a request inside of useEffect
once this component is rendered,
setting some loading state
and then displaying some data down there.
Again, that's a very standard React's way.
And of course there are ways of changing that,
of handling errors.
Of using custom hoax and a lot of other things.
But this is the most basic form
of sending a request from inside React on the client side.
And in the end,
that's kind of what we now wanna build again
with Next.js here.
Now, for this I'll add a new page here,
a new route therefore.
And I'll name it last-sales.js.
Of course, this will just be a dummy page here.
This overall project is just a dummy project.
We're going to have a more realistic example
in the next course section,
when we applied as to our events project again.
But in this dummy file here, in this dummy page.
I want to show you how we could implement
client side data fetching with Next.js.
And of course it starts
with defining our page component here.
And of course we also want to export that component
so that it can be found.
Now in here, in that component,
we wanna return some JS Xcode.
Let's say some sales data
which should be rendered as a list,
but we wanna fetch that data
from inside this component function as well.
We don't wanna add get static props
or get server-side props here,
because that's exactly not our goal here.
We don't want to pre-fetch the data on the server
or during the build time.
Inside here, we can now write useEffect.
So use to useEffect hook,
which we import from React therefore.
And then in there, in this effect function
we can execute some code, which sends our HTTP request.
And for a useEffect
we also need to add this dependencies array,
listing all the dependencies of this useEffect function.
And in this case this function
won't have any dependencies
since I won't use any other component specific data here.
So, now in here, we can use the built-in fetch API
which is available in the browser.
And as a side note, which could also be used
in get static props or get service I props.
It is available there as well.
We don't need it there right now,
but you could use it there as well.
But here we use it on the client side instead of useEffect,
to send the request to some API,
to some web server.
Now to test this,
we need some dummy back-end,
we need some web server.
And I will use Firebase for that.
It sounds like it's just a database,
but actually Firebase is a service offered by Google,
which gives you an entire back-end
with a lot of different features.
But one of the features is a database with an attached API
which we can use as a dummy backend here.
So we're not going to build anything complex with Firebase.
We're just going to use it as a dummy back-end.
For this you need to go to the console
and for this you need a Google account
with which you should log in.
And once you did log in,
you can add a new Firebase project
and I'll just name it nextjs-course.
But you can of course
pick any name you want, click continue.
You can disable Google Analytics,
we don't need that.
And create that project.
Again Firebase is a service totally detached from Next.js
which is actually made up of a lot of different services
and tools and utilities,
which you can use to build powerful back-ends
for your application front-ends.
Here, I really just wanna use its built-in database
with a connected API.
And that will be the real time database
which I wanna use.
So, here I'll click on real-time database on the left.
And there, we then can click on create database.
Now you can leave the default here, click on next.
And on security rules
you wanna start in test mode actually,
which ensures that we do have access
to the database from outside.
Now this will create such a database for you.
The great thing is that it will be a database
into which we can look into here.
And we also get an API here to which we can send requests
which will then automatically be translated
into database operations by Firebase.
So, we send regular HTTP requests to this API here
and then automatically data gets written, deleted
whatever we wanna do here in Firebase.
Now, here I actually wanna prepare some data though.
So that we have some data we can fetch
with our Next.js code here.
Therefore we can click on the plus here,
when we hover over this database name.
And then add any key of your choice.
I'll go with sales here,
and then click on the plus here.
And now we basically created a sales node
a sales table kind off,
and we can now add a different pieces of information
that belong to a single sale.
For example, here, we could name this first sale
which you wanna add s1 and click on the plus again
and now add the data that belongs to that sale.
Like for example, the username, which could be Max,
click on add now.
And then click on the plus next to s1 again,
and also add a volume of let's say 100.
And now let's click on the plus next to sales again,
add a sale with a name of s2 and click on this plus.
And here add a username of manual,
and then click on the plus next to s2,
and add a volume of 50.
Click on add.
And now we added two sales entries to this dummy database.
Now I mentioned that it would be this URL
which we can use to send the request to,
to interact with that database.
And that is correct.
I'll copy that URL.
And now here in fetch,
we can use that URL at least as a starter.
And then here, we wanna send the request to the sales node
and fetch all the sales.
So, here I'll then add slash sales.
And now in Firebase world,
we also need to add dot json at the end.
This is not a Next.js requirement.
This is really just required
by this Firebase API we're using.
And this will send a request to this sales node
in this Firebase database.
Again, we just use it as a dummy back-end here.
Now, fetch this built-in browser API,
this function which is built into the browser,
then returns a promise.
So, here we can add a then block
to work with the response
which we actually get back here.
And on this response,
we can call dot json to read the data from that response.
That's how this fetch API works.
Again, nothing Next.js specific.
This is the standard browser fetch API
and how we can use it.
So now with that, we're taking the response
and extracting the response data.
This again, then returns a promise.
So we can chain another then call here
and this will then give us the actual data
which we parsed from the response.
And it's now in here in this function here,
where we can use that data which we received.
Now, we might want to update the state of this component
to output the data down there,
once we did get it.
And for this we can import to useState hook here.
And register a state in this component.
Let's say the data state or the sales state
with a setSales state updating function.
And we call useState to initialize this state.
And initially let's say that's undefined
because initially we have no sales.
And maybe we also want a loading state,
the isLoading state,
so that we can show some loading fallback
whilst we're waiting for that data to arrive.
So here I'll then also set up this state
and initially it's false.
And now in useEffect in this function,
we wanna set isLoading to true here at the beginning
to set this loading state to true,
because we are now fetching data.
And once we got the data here in this second then block,
we wanna setSales equal to our sales data.
And, balloon that in a second.
And we also want to set isLoading to false here again,
because we're not loading anymore.
Now regarding the sales data,
it is important to know
that the data we'll get back from Firebase
will not be an array,
but it will be an object where these Ids here,
s1 and s2 will be keys,
which then holds the detailed data as nested objects.
So, if we want an array, we need to transform this data.
So, here we can have our transformedSales
which is an array.
And we built that with a four in loop,
by looping through all the keys in data.
Because again, data will be an object
where our Ids s1 and s2 will be keys.
So then for transformedSales,
we push an object into this array.
And that object maybe has an Id property,
which has the key as a value,
because again, the keys are these Ids.
And then we have our username field
which is data for the given key.
Dynamically accessing it with the square brackets,
which is standard JavaScript dot username.
So now we're diving into that nested object here,
accessing the username.
And we wanna do the same for the volume.
So, I'll set a volume key here
and set this equal to data for the given key dot volume.
Now I'll reformat this and it looks like this.
So now this is how we transform our sales
from an object to an array.
And then I can set these transformedSales as my new sales.
And that would be a very standard reactive way
of sending such a request.
We can now use it and check if we are loading here.
And if we are, I return a paragraph where I say,
loading let's say,
or where we show some loading spinner off course.
And otherwise here in the unordered list,
we can also access our sales then, our sales state.
And map our sales
so that every sale is mapped into a list item
where the key is set to sale.id
and where we then output the sale username.
Then a dash maybe,
and then after that the sale volume
and maybe a dollar sign in front of it
but that's just cosmetics.
With all of that in place,
we now got this client-side code.
Now we can spin up our development server again
to preview this.
For this I'll go to local host last dash sales,
since that last a page name we added.
And here I get an error
cannot read property map of undefined.
That makes a lot of sense because initially
isLoading is false.
And our sales state
which we try to use down there is undefined.
Now in useEffect we change this loading state,
but the way React works
is such that useEffect only executes the effect function
after the whole component was evaluated
and rendered for the first time.
And for this first render cycle
sales therefore will be undefined
and state will be false.
So we'll reach that code
and we'll then try to call map
on something which is undefined.
So therefore I'll add another check
and check if not sales.
So if we have no sales yet,
in which case I return no data yet here as a paragraph.
Now with data, if we save this,
with this extra check added,
now if I reload you see loading
and then you see that data eventually.
And that is how we could fetch data on the client side.
Now, if we inspect the page source here,
then the interesting thing is that we see no data yet.
And that hopefully makes sense.
The pages still pre-rendered by Next.js.
Because I explained earlier in this module
that that would be the default page
which does not use get server side props,
effectively will be pre-rendered by Next.js.
The key thing here just is that the data used by this page
will not be prepared by Next.js
with get static props for example.
Hence, when Next.js pre renders this page,
it will not execute useEffect.
It will not wait for this.
It will not care about that.
It will just return
and pre-render the very basic first version
of what this component spits out.
And that has no data yet
for the reasons I explained a couple of seconds ago.
That is the initial state of this page.
And that is what gets pre-rendered therefore.
So we still have pre-rendering going on,
but without the data.
Because we're fetching the data on the client side now,
with this approach.