Introduction to Next.js and React

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this tutorial will be an introduction to react and nextjs it's Hands-On interactive and hopefully fun as well too so we're going to build a real app I'm going to walk you through building this from start to finish explain some of the concepts along the way and at the end you'll have a real URL that you can share with your friends now this is designed for beginners who are new to react or nextjs but if you've used react or maybe nextjs before hopefully you'll still pick up some new tips along the way too all right let's get started so first let's install nodejs now if you go to nodejs.org you can download the latest version and you'll know that you have it successfully set up if you run node DV in your terminal or command line and you can see the latest version that we're on here so ensure you get nodejs installed you'll also want to ensure that you have git installed now I believe all new Macs have get included but if you run g-v you'll be able to see what version of git you're on if not go go to get and install this version as well too now I would also recommend that you create a GitHub account this is where you'll be able to store your code it's kind of like Google drive but for your codes you can see the versions of it and then also a versell account where we will deploy our code and we'll get our URL from now in this tutorial I'm going to be using VSS code as my text editor or IDE and Google Chrome as my browser you can use whichever tools you prefer but this is what I'm going to be using so I've got my editor up on my left and I've got my browser up on my right and we can use this as the playground where we'll be building our application today so first things first I want to actually walk you through creating a new project from scratch using the command line and then eventually we'll start from the quick start but I think it's helpful to understand exactly what specific steps you need to build an xgs and react app from scratch U before we take the easy route so first in the command line on the left in my terminal what I'm going to do is I'm going to make a new directory we can just call this next react course and then we can change our directory into our next react course here now inside of here I'm going to create a brand new project defined by a package Json so mpm has this command called mpm and knit I'm going just going to Auto Select all of the defaults for here and let me open up this project okay so we have this project open in VSS code and we can see the new package Json file that we've created now most of the stuff in here is usually for actually publishing packages to mpm so when you want to bundle up some code and publish it so that someone else can use it for this application we can actually get rid of all of this and we can get rid of all of this and really all we're going to need here is the scripts but first we need to install some dependencies now this gets into package managers node by default includes the package manager mpm that was how we created this package Json file here but there's a bunch of different package managers there's mpm there's yarn pmpm bun it doesn't really matter which one you use I'm going to use pmpm because that's what I use most of the time all of them are great um so I actually have an alias on my command line instead of writing pmpm every single time I just write PN because I'm lazy so you can also do that in your uh bash or whatever terminal file you're using um so I'm going to install next react and react Dom those are all the dependencies that you need to create your first nextjs react application and that adds in a new key into our package Json for all those different dependencies so this is the the most boiler plate the smallest amount of dependencies you need to get started and then we're going to make a new command in here called Dev is how we can start our local Dev server and the command is next Dev so this is the the smallest amount of configuration needed to actually start up a local Dev server for my nextjs application so now on the right we have our package Json that we've walked through we have a lock file which tells your package manager how to specifically resolve the versions of packages you can pretty much ignore this this is just going to be autogenerated but you usually check it in to your git provider of choice so that you have this version which means that if somebody pulls down your repository which is where you store your code they can always install the exact version of the packages that you're using and then all of the node modules that were included which are all of the packages are included here on your local file system as well too so let's create our first route inside of our nextjs application just the smallest most minimal route and then we'll get into talking about what react is doing so I'm going to make a new folder we're going to call it app I'm going to make a new file we'll call it layout. JS and I'm going to make another file that's called page.js now don't worry I'm going to explain these conventions a little bit more later but for now I'm going to just complete these so we're going to do export uh default function root layout and that just scaff with me some stuff here but we can do uh HTML and then we're going to do uh body and then we can do the children and this is going to be English okay that looks fine export default function page and and we'll do return we'll do an H1 we'll do yep H1 and we can say hello world yep that looks good okay I can close these okay so now let's run our local Deb server and on the right here I can open up Local Host 3000 and we see Hello World so this is the most minimal example of getting started here and another thing I'm going to do inside of our package Json is I'm going to add this D- turbo flag to make our Dev server Faster by the time you watch this video This Might already be the default but I'm just going to flip it on here so we can get even faster when we're loading up our application to start as well as making changes so let me walk through what's happened here we have a page that actually is being shown on the page or in our browser this is the most minimal example and if I go inside of here and I add some more exclamation marks I hit save on the right you see that it's instantly updated in our browser this is what we call fast refresh or hot module reloading and that makes it really fast for you to iterate locally make changes add things to your page and then just you know hit save and see it reflected over here in your browser so really fast iteration time now if you've seen nextjs anywhere else or you've used it before in the past you might be wondering what that app folder is so that was something that was introduced in nextjs 13 it was stabilized in nextjs 13.4 we're now on 14 so this is now kind of the standard way but if you still see other examples that are using the old Pages directory that's totally fine too that's still supported and works so there's actually two different routing systems in nextjs so I could for example say you know Pages slab. JS and here I could say export default function about um and we're going to go here and return about so if I go to our browser and I go to slab here we see our new page for about so you can use both of these routers it's okay if you have them in the same application totally fine for the rest of this tutorial I'll only be using the app router or app directory but I just wanted to quickly mention that in case you're coming in with some pre-existing knowledge okay so we have a local Dev server running now we can make changes see them updated in the browser we have our sandbox for editing our react components and making changes and we have our first react component shown on the screen let's actually take a little bit of a step backwards here and talk about some of the fundamental concepts of react now the reason I went in this route is because I personally learn best by building and I think it's the most helpful for you all coding along that you can actually have your editor open make these changes see them update in the browser versus me talking about it in the abstract a little bit here so if you haven't heard of react it's a library for making user interfaces you get a write components and react takes care of the rest basically and it's really fun to work with and I'm going to show you some practical examples so the first concept I want to talk about here is jsx and you might be noticing looking at this component it looks kind of like JavaScript it looks pretty similar but then there's also this HTML in here as well too and jsx is the magic that allows us to to combine HTML and JavaScript and have the ability to write conditional statements and check if this I want to display this UI otherwise display this UI or to substitute in variables in places for example maybe we wanted to say um my name is Lee so I'm going to put this function here let name equals Lee and then rather than this hardcoded string here this hardcoded value I can use these braces here and I can say you know what actually instead of that value let's substitute in Lee so I hit save and I see that Dynamic value rendered on the right now trivial example but this is so powerful when you start to think about grabbing data from remote locations or having some computational logic in here to check for something or to use any JavaScript expressions and then put that logic actually into the HTML so it's allowing you to very easily template your UI the second thing I I want to talk about is composability this is one of my favorite Parts about react so maybe actually this header component here that displays my name we want to model this as its own function its own component so I'm going to say um function we're going to call this um header and inside of here what I could do actually is just remove this so name equals Lee Return H1 name Lee awesome now here maybe I want to have some header component maybe this is a section and I'll say this is my amazing site so I've got a paragraph tag I've got a section tag and then I'm composing this header component I'm using this inside of the page component so the page is a parent the header is a child here so if I hit save on the right now I see the section the header and then the paragraph So this is pretty powerful again simple example but this concept can take you very very far with react and you can you know make things a little bit fancier this than this as well too so maybe for example I wanted to pass some information to my component maybe I didn't want this name to be justly hardcoded inside of there I wanted to say you know what I want the name to be Bob and this value is called called a prop short for properties so I can forward more information to the header component so let me remove this now how does it get access to this name well here inside the arguments you have the props object and on that object you can use a JavaScript uh feature here to destructure that object and I want to pull off the name key so I could as well if I really wanted to write props and this is the whole object and then do props name like this to access the key of name but a really nice functionality there is that you can just destructure that and pull name off here so now if I hit save I see Bob on the right because I passed in this Dynamic value I could change it back to Lee and this is how you can kind of forward data or information between components so that's really helpful but passing his props isn't always the best design it really depends on the type of data again the composability here is one of the great Parts about react so what would that look like well right now this is a selfcontained component so it has an opening tag and then it closes at the end but what if we wanted to pass some children to this component so the parent here I want to say the children of this component maybe we want this to be um maybe we want the H1 here that's going to say Lee we can remove this and we also want to have um maybe we also want to have some other information here we could if we wanted to this is all the child of this header now if I go up to header on the props there's also a prop called children so now maybe inside of here I wanted to have like a uh I could use the literal header HTML component that works um I have a header component I have an H1 that is the children and then I finish that out here now I don't want duplicate H1s so I could do I could remove it from here I guess if I wanted to sure it still explains the concept uh I could change this here just to so we can see it updated on the right and this is great I can kind of Stack my components on top of each other I can compose components together and you can do some really fancy stuff with this but the fundamental thing here is that you get to group these bits of logic into reusable pieces and while right now this header component is all designed or it's all living in the same file this is a little bit of a personal preference but I kind of prefer to keep things in the same file for as long as I can until maybe they're used in a bunch of different places but it's nice to keep the code that changes together in the same file but just to to show an example what if instead I make a new file here we'll call this header. JS and I could actually pull this component out go over to header. JS and right now there's no exports so with the JavaScript module system I want to either export the default function from this file or a named export from this file so if I did export function header this would be a named export or if I did export default function it would be the default export um I'll do a named export here again kind of a personal preference it doesn't matter too much so now when I'm importing what the editor is showing me here is actually a default export so there's no braces around here but I have a named export so I would wrap this with header and then actually the file path here is just to do slash so it's in the same directory slhe header and I hit save and now I can change this again put even more exclamation marks and we see that it's updated on the right so you can kind of refact factor out bits and move them around as you want and this component could even come from some external dependency as well too for example if I actually stop my local development server and I install a new dependency react tweet so I can embed tweet embeds or X EDS or whatever they're calling it nowadays uh and I restart my Deb server maybe inside of here rather than this paragraph I want to do a tweet um and the tweet is going to take in some ID and I'll just paste in some ID and then we need to import this tweet we'll see if I can get vs code to give me a suggestion here it does not that's okay uh import tweet from react tweet okay that looks fine let's reload our page over here okay so I get a re use install and just import components that can do some pretty cool stuff this could be a tweet this could be something visual from my CMS this could be a markdown Library it could really be anything uh the cool thing about this component actually is it not only did it show the visual bits but it also knew how to go grab the data and determine what to display on the screen just given an ID we'll talk a little bit more about how that's some new functionality that's in and react but it's a really powerful concept you get to encapsulate this logic put it in a component and then share it with anyone to use all right now most people don't actually start their nextjs or react applications this way they instead start with a command that helps scaffold out all of the files for them so while this was interesting and it helped you understand the foundational pieces the MVP of what you needed to actually make your application let's use the common default which is the tool called create next app so in the command line like we've done before we can do npx which is essentially like running a an a script for you it's calling some package installation that's going to scaffold out and run a command for you and you can do create actually let me um go back a directory here so we can do MPX create next app at latest so we're going to install latest version and we'll call this uh next react course um create next app now this is going to give you an interactive set of prompts that you can use to pick what options you want now the reason I mentioned most people start from this is also because most people nowadays are starting from typescript this is again kind of personal preference but I'm going to start with typescript um we're not going to use eslint we can use Tailwind I think we'll go ahead and install it but I'll talk about this a little bit later when we get to styling options and how we want to style our application um Source directory is just a optional way of bucketing your code and then we're using this app router here as well too don't need to customize any of that okay now you're going to notice it installed the dependencies we already talked about it also installed some other dependencies for us for typescript and for the styling setup so let me jump over to that directory okay new directory I've cleared out my browser window here let's take a look at what create next app includes by default and and to start I'm just going to walk through the entire directory structure and talk about what files are included and then we can show kind of what we're getting for default here so first things first I'm going to go into the package Json uh I'm going to also add that turbo flag again that might be the default um again you can get rid of some of this stuff if you want private true it's like I'm not going to publish this package to mpm we've got our scripts I'll talk a little bit more about some of these later um we don't have es lint set up so we can remove that okay those dependencies look good I'm going to run our Dev server and if I go back over to here I go to Local Host 3000 I will see our create next App application so this includes a little bit more than just a hello world it gives you a nice design here to get started by default with some links out to some helpful things but we don't really need to jump into that right now let's talk about the file structure we'll go bottom up here so we'll start with the tsig uh. Json this file automatically created by nextjs you shouldn't need to touch it's going to automatically set up all of the right defaults for you for your nextjs application to use typescript um so that you don't really need to touch the Tailwind config the postcss config again these are going to be defaults that are scaffolded out because of the option that we selected for Tailwind styling in the future you might not even need these they might just work with without even needing to be there depending on what time you watch this video um we can ignore those for now the read me included just gives you some more information about the application the package Json we already talked about the next config file you can pass additional options to configure nextjs maybe it's something around where you want to allow image optimization from or maybe it's specific directories you want to customize you can do a lot of things here but the default you don't need to configure anything this file is included for typescript but you don't need to do anything by default we include a get ignore file by default that has some good um initial things included for you some files that we're pretty sure you probably don't want to commit these to get they want to stay on your local machine like autogenerated files we have a public directory this public directory is things that we want to be publicly accessible on our nextjs server so if I go to next. SVG for example I'm able to access this file that's kind of hosted on our server route so we've got some svgs in there we already talked about node modules next is the compiled version of our application so when I'm working locally uh it's generating all of these internal files that nextjs can serve up you can basically ignore this file this is kind of considered like the internals while you're working locally um but if you needed to clear your cache for example you can delete your file uh and then we have this app directory or app router um and we're using again a layout and page file from the previous setup that we had too but rather thanjs or jsx you have TS or TSX now the JS or jsx thing file extension uh it's really personal preference it doesn't actually change that much um but in this one we're using typescript so we've got type um. TSX here we also have a favicon so this is automatically served up by our browser um all you have to do is include it in the folder and will just automatically work when it's a child of the app we've got some Global CSS that we're including here it's got the Tailwind set up um and then we have our root layout and our page now this is a good time to talk about these special files and what they mean to nextjs I kind of glossed over it a little bit earlier so the layout especially this root layout is going to wrap our entire application so when we talk through the those fundamentals around the composition of react components this component wraps all of the other components and that's why it has the top level tag the HTML tag the body tag and then it takes in the children as a prop if we go back to those fundamentals and returns it here with whatever we pass below which is going to be the page right so a layout wraps a page um we're also doing some other stuff in here by default we're using this built-in font functionality from nextjs that allows you to install fonts from Google fonts or from your local machine to style your application and do it in a way that doesn't affect performance um we also have some metadata so this will automatically set the values inside of the head of your HTML document so title tags and you know other meta tags for descriptions or OG images you can configure that all through here and there's also types as well too if you want to go see all the different fields that are available but basically every field that you need to configure your metadata is in there there so this is the root layout and then inside of the page you're going to be like whoa what is this uh this is Tailwind so it is CSS Styles inlined into your HTML so kind of like how you can put your HTML into your JavaScript with jsx uh Tailwind is kind of doing that as well for your styling um but fundamentally this is pretty much the same thing as what we were looking at before you have a default comp component that's going to render some HTML or some markup on the screen and we're also using an image component here to you know optimize images um for the sake of not uh overwhelming everyone with tail one styles to get started what we can do is let's actually just clear this out because we're not going to need that and we can go back to you know something like a section um yeah nextjs plus this and we can remove the image as well too um now you're like like whoa what is this interesting repeating pattern over here pretty sure there's something in our in our background here there's a linear gradient um so we can just get rid of that stuff as well too uh it's also worth noting if you start here small small thing Tailwind includes a CSS reset which removes all the default browser Styles so if you're wondering why my H1 looks different here versus what a different before that's that's what's happening there um you don't have to use Tailwind by the way um we can use just normal CSS files if we would prefer I could write all my you know write all my Styles in here if I wanted to but this will allow us to iterate a little bit faster here during the tutorial so I talked about the layout file this special file convention here that explicitly has the name layout well page is similar in the sense that you need to explicitly call this file page when we get into actually showing multiple routes here you'll understand why there will be multiple page files but I just want to quickly call out that those are special file names but now that we have our we have our playground we've talked through kind of all the base steps let's actually get into building our application together today we're going to build a quiz application so you'll be able to create quizzes and a quiz will have different answers they'll have a question and some answers and you'll be able to see which one is the right answer pretty simple example but it'll allow us to show different routes inside of nextjs uh both grabbing data as well as mutating or adding data we're going to work with a postrest database as well too uh and hopefully learn some things along the way so let's get started first I want to talk about routing in between different pages we're going to have a homepage that lists all the quizzes in our application but then we're also going to have individual Pages for each quiz as well too so onside our index route here maybe we want to change this to uh all quizzes for example but then below it we're going to need to have a list of quizzes so this could be yeah exactly like that uh an unordered list of quizzes quiz one two three it's going to have uh links to those specific quizzes so we can leave this for now but we need to understand how to link specifically to those pages so let's go to our app we're going to make a new folder we're going to call this quiz and what you're going to start to see is that nextjs has a file system based router you could kind of already tell this by the layout in the pages files being how nextjs was able to understand how to go to this index route but this works for really any route in your application so if I make a new folder under quiz we need to be able to understand the dynamic parts of the route too and we can use brackets here square brackets to denote variables that can be substituted in our route so slash quiz slash some ID one 2 or three now inside of here this goes back to what I talked about the special files so page. TSX this is how next CHS is going to be able to route to specifically SL quiz1 or Quest SL quiz2 versus the index route so we can export default function quiz page uh and then inside of here maybe we want to return something like this sure we have a section we have quiz one this is our quiz page now if we go back here we had this list of links and I want you to notice pay attention in the browser because when we navigate to this other page we're going to to a full browser load so if I click on quiz one we see the browser Spin and we navigate over to quiz one this is just a a standard browser navigation between Pages we can go quiz one quiz two awesome now quiz one is literally hardcoded in that page for now but we're going to change that out but I wanted to first show how we can make these transitions between Pages a little bit faster and we can do that using a built-in component from nextjs called the link component so inside of our unordered list instead of defining an a tag we can use the link component and we're going to import that from next link so go to quiz one quiz one and we don't actually even need to use the a tag the link component will generate the a tag for us so we can get rid of that awesome and then we'll replace this and quiz two Quiz 3 cool now notice in the browser when I go from the index route to the quiz one route was really fast I didn't have to to do the full browser transition or the full page load because of this link component so it's able to prefetch it's able to understand what I'm going to route to and then make it feel like it's part of a a single page application or feel like it's part of a unified application kind of like a mobile app feels right where it's really fast to navigate between Pages nextjs takes care of that for you now if you're still linking to external links like I need to go out to the versell website you would still use the a tag there there's no point and um you're not going to preload the external link but for navigating internally you would want to use this internal link all right now let's change that hardcoded quiz one to a dynamic value so inside of this Dynamic route this Dynamic page how do we access that ID value or that ID parameter so in the props again just a react component in the props for this page nextjs includes a prop for you and that prop is called params and those are the parameters of the route segment or the dynamic route so the prams and it's going to complain because I need some typescript types here has an ID that is a string so and I'm missing a closing brace there so rather than quiz one here I can use my jsx to include some Dynamic values here and now I'm getting some typescript help because that's all set up so it knows that hey ID is a value that's available it's a key on this object and we can use quiz whatever here so now when I go to quiz two I see quiz two when I go to quiz three I see quiz three those are kind of the basics of navigating between routes really fast and also reading the dynamic values from the routes based on how they're defined in your file system now I don't think we actually have a need for a nested layout here but I want to quickly show how this works as well too so that you have the right me model of layouts and Pages we talked about the root layout that wraps our entire application but this same model of composing components of a parent and a child of a layout and a page can also work as you go further down the application tree so if you think about the root layout at the top of the tree and you have different branches as you go down when you get into the the quiz routes and this quiz page well what if I want to have multiple Pages underneath quiz slash something maybe I want qu quiz slash1 but maybe I also want the quiz SL results or some other route inside of here well the nice thing is you can have nested layouts inside of here too so I can make a new file inside of this ID folder or you know maybe I actually want it right here underneath the quiz route we're going to call this layout. TSX it's going to be the same concept as our root layout so a component that takes in some children and renders it so we could do export default function nested layout that's going to have the props that are children and then we could [Music] return this is giving me autocomplete for the root layout but we'd want some tag here and maybe instead of body we want um we want some nav for example and maybe inside of the nav we want this is my navigation again this could really be whatever you want here and let's throw some typescript types on here so now this is my nested layout for everything under the quiz route so if I go to quiz /1 I see this is my navigation from quiz1 and you can take this concept basically as far down you want to go so you can Nest many different layouts as well too I don't think we have a need for a nested layout here but I just wanted to quickly mention that those Concepts stack on top of each other all right so going back to our index route we have a list of quizzes hardcoded uh we can navigate between routes we can go to different quizzes here we kind of understand the fundamentals of going between Pages layouts Pages let's talk about how we actually change this from being hardcoded to fetching real data now in this tutorial I'm going to use postrest as our database you could use my SQL you could use any database that you want uh but we're going to use postgress here so I'm going to quit my Dev server I'm going to install the postgress package this postgress package you could use other post packages as you want this one's going to give me the ability to to just write some SQL queries really easily um and then I'm also going to create aemv dolal file I think the touch command only works on Mac by the way so I think it's different on Windows but you could also use your Editor to do that so I'm going to make an env. looc file and then inside of here I'm going to have a database dot or database URL um it's giving me autocomplete for postgress or for my SQL but the postgress one looks pretty Sim similar to that it's like this and there's going to be something here so I'm going to go off camera here for a second I'm going to go grab the postgress url url for my application you could use any service you want I'm going to use verel for this but um grab your database URL and then come back here okay so grab my database URL put it in my EMV dolo file I've installed my postgress package um now I can restart my Dev server and we can go to our route here and we can start fetching some data so I'm going to import postgress from postgress and I want to make some query now right now we have this hardcoded list so let's actually take this let's cut this and let's compose in here a uh quizes quizzes component and then we're going to make a new component we're going to call this quizzes uh sure um we'll see what the auto complete gives us here this was the code we had before which was manually writing out unordered list list item link the hrf and then the text here let's see what the AI gave us here we have an unordered list we have jsx to use a dynamic value here um and we're to run an expression and the expression is to take the quiz's variable map over that array for each quiz we want to make a list item that has a link inside of it that link has a dynamic HF it's using a JavaScript um tag template literal string here so the special back ticks allow us to inject Dynamic values into the string rather than concatenating them onto the end and then we access quiz. name and it's a child of the link this all looks correct and right um but we have again still this hard-coded list of quizzes now one of the really cool things about nextjs and the latest react features is that you can actually Mark components as asynchronous and fetch data directly now if you've maybe dabbled with react a little bit um prior to some of the latest features in nextjs in react you might have needed to use client side effects to fetch data or other kind of nextjs specific apis but what we're showing here is just standard react and it's called the react server component so I can mark this component as asynchronous and I actually think I need to yeah set up a connection here to postgress we're going to do process. em. database URL this value uh will be automatically read from my em. Lo file or whatever my deployment platform is um and passed along to the postest function it's complaining because this value could be not available but I know it is if you want to have better error checking you can do that here I'm using some typescript Foo there uh now inside of here I want to say okay go get all of the quizzes from my quizzes table select star from quizzes return those quizzes and then map over them so that all looks good okay my thing is running here I reload the page [Music] and nope nothing here I think I know why too so I've already set up a postest database here that has some quizzes in it and I'll be able to include a link to the command that I used to just scaffold out some data in this database um the ID on that quiz is actually quore ID so I'm going to select Dot ID here I can use command D to select multiple inside of VSS code and I can do quore ID and then also instead of quiz. name it is quiz. tile now if I wanted to make this better since this isn't giving me any help from typescript is saying hey there was this row that was returned back I could actually Define a type here so I could say a type of quiz has a quiz ID it has a title I think there's there's also some other stuff on here as well too and then I could say you know what quizzes is actually an array of quiz or quizzes um now I get some helpful information here about what property I have available so if for example before when I had name it would have blown up and said actually by the way Le it is title um so I save and I reload and I see all of the quizzes here I have programming quiz one two and three my quiz awesome and again I can navigate between here I can go to quiz one two three so I'm now fetching Dynamic data from my database this is just standard postgress here so you know similar if you're using my SQL as well too um if I I would recommend if you're new to databases if you're new towards the more backend side of applications um use AI tools large language models chat gbt use these tools to help beer your or your pair programmer to learn how these things work for example you can say please describe this database schema tell me how it works help me query help me insert placeholder data into this database it'll help guide you along as you're learning databases as well too that's a little bit outside the scope here where we have a database we're able to fetch some data from it and pull this values dynamically now another interesting part here is that this component is now an asynchronous component fetches data dynamically one of the cool things about the react model 2 is we have control over how we reveal or show content on the page as well as how we have a fallback when loading a synchronous Theta so if we wanted to for example we could actually instead wrap this component if I can type uh with suspense yes have fallback okay and this has some fallback uh react component it could be a loading skeleton it could be a loading spinner and then the tri of that is our actual quizzes component so if I hit save here I see it was loading and then we showed our value so you can really have fine green control over how you um reveal or show loading States in your application using react suspense and server components um just wanted to quickly mention that as well too some helpful guidance here is that you want to place your data fetching close to where you're actually rendering the UI for that data that you return back so we fetched our quizzes it makes sense to put this in a quizzes component actually renders out these values now depending on when you're watching this video um in a future version there might be a flag turned on that's called partial pre-rendering what that's going to do is it's going to allow you to have the rest of this page you could have a bunch of other things on here right that part can be essentially pulled out and made separate from the dynamic parts of your pages where you're actually fetching data so that part will automatically be taken care of by nextjs and make the the rest of the shell of your application very fast to load and then you get control over this specific quizzes component defined by your react suspense boundaries that I was showing uh just a minute ago on how you actually want that content to load in so writing your code today using suspense and thinking about putting your data fetching close to your components using suspense and thinking about how you want to reveal and load content will help prepare you for a future version of nextjs um or maybe the the default by the time you're watching this another thing to mention here too as well is that again depending on the time that you're watching this right now we're making this Dynamic data fetch through the postgress package here and there's a built-in caching system into nextjs such that let's say I have multiple places where I want to query for these quizzes I can ensure that we're only making one call there um if you're using the fetch API this automatically works today and there's future improvements coming here that make it even easier to do this when you're using um something like this like the post glass client here or just any uh database omm or any other value so definitely check out the documentation to learn more about options for caching for non fetch as well depending on the time you're watching this but this at least gets you prepared for the future as well to to thinking about how these pieces will fit together now this page looks pretty boring so let's add a little bit of styles here and talk about Tailwind CSS and inline Styles so for example on the H1 I can provide a prop to H1 or an attribute to this HTML element called class name and you're probably thinking if you've used HTML before why is it class name instead of class there are some specifics to react like this where the the attribute names are a little bit different and the react Land versus the HTML land there aren't very many but class name is one of those so class name for example maybe we want uh font 2 Excel um text blue text blue 700 U this is the or is it text to XL I might forgot text to XL text to XL font semi bold yeah so one of the nice things about ta1 CSS is you get this really fast iteration Loop when you're kind of editing your inline Styles here your collocated styles with your code and then you get to just hit save and see it update on the right um this isn't the only way that you can do things by the way you could for example do uh inline Styles so you can pass a style object here and you could do something like that for example just remove this for a second here um why is this complaining oh I think I messed that up yeah I did cool um so font size this isn't my favorite one because you have to do uh a different casing here than the normal CSS elements but sure uh font size large font weight align Center some margin awesome so you can do this is if you want as well too you can also do um traditional class names so my hero title whatever the problem with this is that these names have to be unique so you know I could go into my Global CSS file and I could say my hero title whatever you can do that of course but it makes it a little bit difficult as your Styles scale in your application so what I would typically recommend if you don't want to do Tailwind um is something called CSS modules so you get to scope the styles that you want to load to specific Pages or components so I would do uh a new file we'll call this um oops we'll call this um styles do or home. module. css so this is going to be CSS module and they'll have the class in here we'll call it hero and we'll do font size uh to rem or pixels or whatever value you want to use Here and Now inside of here I want to do styles. hero and the Styles is going to give me um let's see if it nope okay I'll go uh import uh styles from slash uh home. module. CSS so I'm able to get access to whatever these styles are here cool hit save okay so same same but different it's another way of doing it just slightly different this is kind of all um syntactical preference so whichever way you or your team prefers writing things a lot of people really like CSS modules because that same component module that you think about with style or with react you get to apply to your Styles as well too so only include the styles for this CSS module in this page for example example um for the rest of this tutorial I'll just go ahead and use uh Tailwind just for the sake of it's already installed here but you can really do any of these that you want or other popular styling Solutions as well too so we'll remove the blue we'll keep it to XEL semi bold awesome okay so we have a list of quizzes we're displaying it on our index route let's actually go to the quiz pages and start displaying more information about the qu quiz as well too so maybe to make this a little bit more clear we'll just do uh underline so it's clear that those are links as well too and these go over to the individual quizzes and I can go to this quiz page okay so we're fetching a quiz or we we're displaying a quiz based on the ID but we need to actually dynamically fetch this quiz based on that value as well too so let's go back to here and I could abstract this out and do like a database file if I wanted to but for the sake of good old copy paste we can just include this for here and then let's say I want to do a new async function uh quiz my editor is learning a little bit it takes in some ID that's a string we make a call here select star from quizzes where quiz ID equals whatever this ID is okay sure we um maybe we want this to be a section H1 is quiz zero title and that might not be right but we're going to see uh we have our quiz page takes in the ID okay so now we need to take this and you know we could have a bunch of other things on here we could have some paragraph This is the page for a quiz sure what we're instead we're going to do is we're going to have look like I almost yeah uh quiz we'll have this nested quiz component again because in a future version of nextjs there might be some optimizations here on by default that make most of this page static by default and that means that you might want to have more of your page that's uh not doing the data fetching so I'm intentionally putting the data fetching close to the code here um since we already have the top level section we'll do a div there okay so we forward the ID as a prop prams the ID that's a string goes into here we fetch some data and we return it back okay so I saved and over here on the right we now see that the title of the quiz programming quiz one is being fetched from our database if I go back quiz two quiz three these are all being dynamically pulled from the postrest database here so this is a start but the actual database is is uh We've added a little bit more information here so the way the schema works is actually let me just pull that up so I pasted the schema for the database into the read me here and we can talk through how the relations work here so we have a list of quizzes they have an ID a title and a description what the question is that we're going to ask and then just when we created it just for best practice then we also have a table of the answers so there are many answers for one quiz linked by the ID and one of the answers is going to be the correct answer now this could be there's many ways you could Define the schema here you could go way more complex you could add in user authentication and have quizzes for different users this is just intentionally meant to be a pretty simple example um there's a lot of ways you could do this but we'll roll with this for now and just to help speed things up a little bit here I've actually just copy pasted in a larger query here and we're going to talk through what some of those bits are so to get not only information about the quiz but also join it with the answers we're going to do a couple things let me start here first given the ID of the quiz we're going to join a query from two different tables together so we're going to get the answers we're going to call the quizzes values we're going to shorten it to just Q so we want the quiz ID quiz title quiz description um the question that we're asking and then we also want some information about the answers shorten to a so answer ID answer text and whether it's correct and we're looking through all the quizzes and we're finding the one based on that specific ID so let's change this here instead of quiz this is answers and this is quiz title um we'll do a paragraph here yep answers at zero quiz description now um sure we could do the quiz question here as well too maybe we want to style that a little bit differently we want to iterate over the answers so that looks fine we have an unordered list answers. map answer list item key is the answer ID yes uh actually yeah let's see actually let's just simplify this we can get rid of the input um and instead of the label we'll do a paragraph so the answer text okay yeah all that looks good okay programming quiz one all right reload the page so now we've fetched information about the quiz um we could make this class name um text to excel maybe we want um maybe on the question we want text Excel we want margin y to before we want text grade 700 here okay just some like small tweaks right programming quiz one a quiz about programming Concepts what is a variable well we have a container for storing data we have a programming language or we have a mathematical operation now we need a way to check which one is the correct answer so let's do not on the questions themselves but down here below we're going to want some way to have an action some action that checks okay let's check the answer and a good mental model here to think is I have an action I probably want to start with a form which is a little different maybe than if you've worked with nexs react a little bit in the past slightly updated mental model here so I'm going to start with a form HTML element but then again if you've worked with just normal HTML then this is actually the same mental model you had I'm going to start with a form here a submit button that says um or actually I don't even need a submit button um it it's implied um but we want this to say like show answer or reveal answer something like this okay so this button is going to reveal the answer and I want to show something unique here that you might not have thought of which is what about if I want to send a link to somebody and I want them to go directly to see the completed quiz now you could use some JavaScript right to can to reveal or hide which answer is correct on the page but I want to challenge your mental model to think server first and think URL first for how we could show this answer and to do that what we're going to do is we're going to have an action a server action that actually updates the URL so on a form we can use the action prop this is just normal HTML but instead of a URL we're actually going to have a function this is a reac reaction um and this should be an asynchronous function inside of here to mark this as a server action you can do this in line or we could pull this out into a separate file we want to say use server so this magic string or this magic directive is telling nextjs telling its compiler it's telling it how to understand this code should be pulled out and essentially turned into an API for me so I don't need to manually create some API endpoint on my server I get to kind of write my backend code or I get to write my API code directly either inline here as this kind of uh action Handler or I could have it in a separate file as well too so inside of use server we have this action for the form we're going to redirect um for quiz slams. ID and instead of Slash answer we could do show equals true so we're going to use a query pram we could have a separate page for this as well too but let's use a query progam and I will import redirect from next navigation okay so we did this how do we actually get that URL search parameter well the props for the page not only is there pams there is also search pams so inside of here we have not only pams we have search pams which is show optional the question mark the string so we have quiz ID of this we have form this okay that all looks good so let me save get some reformatting going on here and um what's going to happen here I could probably style this a little bit better class name let's do background gray 200 um margin X2 margin Y3 uh I was in my head I was thinking padding when I wrote that out and then maybe maybe we still do margin to okay and maybe we do rounded and actually I don't know that I like that maybe we just want padding too sure okay we probably don't even need margin doesn't matter uh we have background gray we have some padding okay we have a button to show an answer and you know what this is it's not going to be complete unless I add a hover Style on here too we want to make background gray 400 we're getting wild with the tail and CSS now oh but that's not good enough that's not good enough we need to transition um transition all which means that animate those o now we're talking and that's too dark now I'm just going to nitpick this oh okay there we go now we're finally ready okay so when we click the button uh server action redirect to the quiz and show True um okay so we have quiz one show True now nothing happened but really what happened is the next server said oh actually there's a new value in the search prams do you want to do something with it and we definitely do so what we could do here is pass the it's not working search Rams cool uh what we could do here is pass the search prams up to this component and search pams and this is going to be search params cool that's got the show that all looks right okay now inside of here maybe uh maybe inside this paragraph We want to do something different if it is correct so if search prams doow is true and we could um we could cast this to a Boolean somewhere else uh and the answer is correct show a check mark that seems fine okay let's click show Answer look at that so it redirects back to the same route it has a search foram and it now shows us what the correct answer is by putting the check marks by it without having to add any client side JavaScript to do this or if you've used react before any react state before or any other logic this is all just serers side code your server is templating out your UI if you've been using PHP or rails or other server side languages before this probably feels very familiar if you're kind of newer to the um the JavaScript react ecosystem and you might have seen State before this might feel a little bit different but it's really powerful how far you can get with this model by lifting State up to the server and thinking about your url as a function of as well too because now I just got the added benefit of being able to send my friends this link where they can automatically see the selected answer so the the quiz here the question has already been completed for example and we could make this button like toggle if we wanted to and change or remove that but the same idea holds true okay so let's quickly recap we have our homepage has our list of quizzes we have Pages for the individual quizzes where we can click to show an answer it will redirect back to that page and display a check mark by the right one that all looks great um what else here well maybe actually if I go back to our index route maybe we want to have a form to add in a new quiz and I want to talk about this because I want to also talk about the last bit here of this kind of data life cycle we've fetched data we've we've handled the data but now I actually want to mutate or add a new data into our database and then reflect that in the UI or revalidate the data as well too so on our index route here let's say for example down below here we wanted to have a new quizzes form so I'm going to start by moving this out into a separate component actually so we're going to do quiz form. TSX export default function quiz form um that all looks good we'll return something here it's probably going to spit out a bunch of stuff uh we actually don't want that right now um let's do uh just something simple here like a form and uh wow okay yeah sure we'll we'll accept uh we'll accept some of this stuff because there's some some parts here that are decent um we have a title description question so we have three labels inputs for title description question and then we have answers inside of a form we'll keep that for now we'll go in here quiz form um tab to complete there and it autoc completed quiz form okay so import quiz form it's uh styled beautifully right now if I do say so myself um let's let's start breaking this out into making this look a little bit better now the the way that Tailwind usually recommends to do things is that you start by duplicating Styles until there's a while you're kind of iterating and then once there's a a more consistent pattern then you abstract it out into a component so rather than you know for example I want these inputs to look a bit better I want them to have background Bray 100 rounded uh P yeah padding two um rather than saying okay I want to do this one by or move this out to a component actually what they recommend doing is doing this first uh and then moving it out to a component you can kind of do this however you want um the one way of working like this is then if you command D you can select multiple and say actually I kind of wanted let's say let's say back background gray 50 border border gray 100 and maybe padding one actually border grade two okay so that's one way to do it you could also move it out to component definitely up to you class name let's Flex this uh let's do uh let's do a row Flex row or sorry column yes okay that looks fine um let's do some margin on the top more margin okay cool we have a title description question answer looking okay it's at least some elements here now this is uh where I actually do want to break this out into a reusable component uh and it's going to be for the answer so let me pull this one out we'll do function answer turn do this and the answer is going to take in some ID this is going to be some number sure um for now for this kind of basic one here we're just going to um we're just going to AR code this so we're going to have three answers basically and these are going to be dynamic so we have answer ID there's a name which this name is going to be important in a little bit here this is how we're able to denote specifically this element in the form name of answer slid awesome uh we probably also want a checkbox in here to determine which one is the correct answer um so we could do input type checkbox name um correct ID that all looks fine so we've got our function answer now I can go back to here after here I want answer one two three nice and actually I could do the old uh I could put the styling on the one above it or I could do uh an HR here or a paragraph the the spacer div right HR spacer I don't know putting some spacing in between here margin y four cool there's many again there's many different ways that you could do that um and I actually also might want um maybe inside of here I want an H3 uh create quiz class name text Excel uh font semibold so I can do that as well too um so we're starting to cook we're cooking here right we've got a we've got a form going it looks okay we've got some answers and then also let's do um a button here to actually submit the form we can actually just crib the button that we created here whoops sure so we got got this button that all looks fine create uh create quiz and maybe on our form we want to do like Max with uh extra small okay that looks fine I actually just staring at this now I actually I think I I feel like that's too too dark I think I actually want 50 again here as well too I mean it doesn't really matter I probably could have zoomed this in earlier as well too but um Okay so we've got our button on to create our quiz we've got some fields on our quiz we've got multiple answers this is seeming okay let's actually now figure out how we take this form and we handle the submission so to do that I'm going to go up to the form and just like the form in the other one we're going to have an action and this action is going to call a function we're going to call it create quiz and our button we can just be explicit here that this is a type submit button this button is going to submit the form to create the quiz so we have an async function create quiz and this takes in form data and well this go like this okay so we have a form it calls an action that's going to call This Server action to create a quiz so we have use server uh it passes in the entirety of the form data so inside of here it's going to know that we have all these elements inside our HTML form that have names and we can reference items by names to get the values now you know we can make this more Dynamic we could have a variable number of answers there's lots of things that we could do here but let's just roll with this for now so the the general idea here is that you can basically do um you know con or let whichever you prefer um let's say title and do form data. and get back the value of the title so title description question and then I'm actually going to just do some some good old fashion copy pasta here to save us a minute and then I'll walk through what we're looking at here you're like whoa he just copy pasted the whole tutorial uh we have three answers so three different IDs one two three and I map over these and given the ID I'm going to make an array or an object here of of things an array of objects one is it's getting the values of form data. answerid so this and then if it's correct so if we've checked it to be correct form data. git check slid which this can be check and if that equals on which is the value from the form it's either on or off from the input checkbox uh we can do that then uh the reason why I wanted to copy paste this is just to get this SQL query down perfect um you know this is chat gbt assisted of this SQL query to get it exactly perfect no shame no shame in my uh llm game so we're doing two things here we're inserting a new quiz into our quizzes table with the title description the text when we create it so we used the tag template literal here to include the values from our form the title description question and then we hit the current timestamp we return the quiz ID then we go to the answers table we put the quiz ID the answer text and whether it's correct so then again this is hardcoded you could do it dynamically but I have three answers so we do um whatever the answer text was and then whether it was correct or not so true or false now this is complaining because we don't have SQL right now again we could abstract this out I'm just going to keep going the lazy route for now uh and copy paste over postgress SQL that all looks good to me [Music] and ah okay so the issue was with form data and it not knowing you know there's no type on here what is title exactly what is description what is question so added some typings here for as strings so that this SQL function here knows that these values are strings this is a good time to interject and say that the reason I'm using this SQL tag template literal postrest package is just because it's easy in your production system or in something more serious you might use something that gives you some of these benefits by default whether it's an OM an orms can give you type safety around how you query data back from your database you define your schema it can help you run dat base migrations as well too super recommend that for more complex things um but at least for the simple example here you know this this works pretty well we can also add um some validation onto our server actions to actually expect and check the form of our form data the form of our form data to look at the values that we get back and make sure they match the type of data that we expect uh again for the simple example it's fine um and just before we actually run the SQL command what we can do here is do do Ye Old console log and I'll just comment this out I'll hit save and let's actually say my new quiz test what is a quiz and we'll say that the first one is the right answer create quiz okay so here's the shape of the data that we've got back title my new quiz description answers this all looks right so the data we've got back looks correctly here it seems like we should now be able to rather than just console log it out actually insert this data into our database now I want to do this the wrong way first I want you to see what happens so I'm going to hit create quiz and you're not going to see anything happen but that doesn't mean that it didn't actually work work so if I reload the page I see my new quiz so it did actually work it did insert into the database but remember that other component this component up here that was selecting all the data from the quizzes well it didn't know that there was a data mutation that happened that the data changed and it needed to go fetch new data now the cool thing about nextjs and this whole model is that we actually give you the Primitives for how to model this relationship whether it's at the route level or you can even get more specific at a specific tag of your data so in this example we can do something um at the route level so revalidate path and we're going to say we're going to revalidate the index path here and if I do control space I can get this to pop up say Okay revalidate path from next cache and again if I wanted to get even more granular I could add tags to specific data fetches and only invalidate those cach tags but we're going to say you know what invalidate this whole path here okay back over here on the right uh another new quiz um this is my quiz what is the meaning of life deep deep question uh well we have uh I don't know man uh we have coding and we have 42 the answer is 42 so now we're going to Create a quiz and we didn't have to do anything in the data Refresh on the page without putting the browser into a loading state so in one network roundtrip nextjs was able to go to the server do the data mutation and actually return back the new UI just for this portion of the page it's pretty mind-blowing but the whole thing is kind of integrated together both how you fetch your data how you mutate your data how the data is cached it's all part of one system and if I wanted to for example clear out this form on submission I could also do that as well too uh but I can click into another new quiz here okay what is the meaning of life I don't know man show answer 42 okay so I'm feeling like this is a good time to start to try to wrap things up and actually get our site online and get a URL that we can share out to the world so what I'm going to do is I'm going to stop our Dev server and I mentioned at the start you can create a versell account now versell is going to make it really easy to deploy your next Us application or really any frontend application so I've already made an account there I've already connected it with my GitHub account but I've installed the versell CLI so whether whatever package manager you want mpmm whichever one you want to use I've installed the version of verell on the CLI and what I'm going to do here first is I'm going to actually make a new project so I'm going to link this to a new project um we're going to set up a new new project I'm going to put it on my account it's not a project we can call it sure yep that's all great the reason why I'm doing this first and keep the default settings here is that I want to add an environment variable so for example if I go verell EMB d-el it's going to tell me a little bit more about what I can do here so you can oops you can remove environment variables you can add variables you can concatenate them in from files um so let's go ahead and do this let's say verel EMV add databaseurl that looks right to me okay what's the value of database URL well let's paste this in and we're going to say this is for production preview and development hit enter awesome added that environment variable now if I want to do verell d-r we should have all the information we need to actually deploy deploy our application to production so if I click on this URL it'll open it in my browser on the right here it's going to authenticate with my ell account that's going to say hey your deployment is building now this is a good time to talk about what is actually happening during this build so the default settings for nextjs is it's going to run next build and the next build command is what optimizes your application for production it does the compilation it does the minification it does the bundling all of these things that you can dig into more if you want to go past the introduction level but they help make your site as fast as possible and there parts that have been optimized for you such that you don't have to think about them or necessarily configure all the tools unless you really want to so now on the right here we see that our deployment finished uh it talked to our database and it fetched back the information about the quizzes we even see the new quiz that we just added here locally um you could have different databases for local and prod of course if you'd want and we've got our unique URL for this deployment now the cool thing is I can actually go to versell I can add and buy custom domains so maybe I want to launch my new quiz startup um I can add analytics I can do a whole bunch of things but it's really that easy just to get your first site online whether it's nextjs or any other Frameworks using brassell and integrating it into the rest of all the changes you'll make in the future as well too all right so we've covered a lot here we've done an introduction into react in nextjs we've talked about some of the fundamentals of what make up react components and how to build nextjs applications we've built out a little quiz app and we've actually got it online as well too this is just the start of your coding programming Journey with Nexus and react uh I also want to mention some other resources where you can dig in and learn more we have lots of content on versell but also the react docs and the react tutorial is very very good good so please check out react. devlearn and then we also have a more in-depth tutorial on the nextjs site as well too both more on the foundations of how we move from JavaScript to react to nextjs and also building an even more in-depth application than what I just showed today kind of a dashboard Style app as a stepbystep course uh on this dashboard as well too so both of these resources should be helpful in you continuing your next jsn react Journey if you liked this type of longer form course or tutorial please let me know I would love to do more content like this if you have questions or you want to see other things created in the future leave a comment down below but that is all for now thank you very much for watching and stay tuned for the next one peace
Info
Channel: Lee Robinson
Views: 46,860
Rating: undefined out of 5
Keywords:
Id: h2BcitZPMn4
Channel Id: undefined
Length: 81min 37sec (4897 seconds)
Published: Mon Dec 04 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.