Fetch props directly from the Database?!?! New Hooks in Next.js 9.3!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey how's it going it's Lee Halladay and today we're going to be looking at three different ways to fetch data in next j/s using the three new hooks that they introduced with 9.3 get server-side props get static paths and get static props and it all came about when I saw this interesting tweet from Adam Wathan next jazz 9.3 very exciting who needs graph QL when you can write SQL and what he shows is basically a way to directly grab data from your database and then provide that data to your component via its props and this brought me back to PHP days 10-15 years ago also I write a lot of Ruby on Rails so it's very similar to sort of server-side rendering concepts highly recommend checking out this full stack radio episode that Adam runs where he interviews Tim Nutkins who's the lead maintainer and developer on next yes they talked about all these things and specifically as I mentioned we're going to be looking at the different hooks that they introduced in this latest version but specifically we're going to be looking at three different ways you can grab data for your pages in next GS so let's pop over to this very basic next jazz application I have running it's already up and running with now dot now dev so it's running locally there and if I pull up my repository I'll give a little bit of a tour of what we're working with so next you ask all of your pages go in the pages folder I right now have company's page with a dynamic ID so a dynamic portion in the path and that's why I'm able to do jobs one or jobs too right now I'm just showing job for all of them but or companies one for example companies one etc so dynamic actions of the of the path so I've got a page for each company I've got a page for each job I've got a home page which is right now we won't be looking at this but it's displaying the jobs I have in my database I go there I can see we got rails developer at github these are fake jobs I made them up but they're all coming from local Postgres database that I set up two tables it's got a job's table with four random jobs I created and it's got a company's table with four random companies one thing to note not all the companies are featured and that will be important that we'll get to later okay so back to the code I have already set up this page so my job component job page which is returning right now this div job so we're going to be looking at one of the newest props that they introduced called get server-side props so in previous versions of next j/s they had get initial props and quite honestly I always found this a little bit confusing because it could run either on your server or on your client depending if it's the first request or if it's subsequent requests triggered from the client side so you always had to write isomorphic code all that means is basically any code you write needs to be prepared to run in any environment so it got tricky like when you're dealing with secrets you don't want to expose them to the client even something as simple as fetch you had to and use like a node fetch or an isomorphic fetch because you weren't sure what environment you were running in or cookies how do you grow up cookies it differs depending where you are so they introduced a new function that you can export and it will be an async function and it is called get server-side props just like that so get server-side props will always run on the server no matter what you don't have to worry about any keys or anything that you use in here or any libraries that you import it's all going to be tree shaking so that it doesn't blow your client code but the goal of this function as you saw in adam's demo is basically to return props that will be passed into your component here so let's get started at that what do we have available to us in here we have the params so what are params in our case if we go to jobs one the prams in our case will be this ID here and because our file name is named with brackets that means this part is dynamic so we're going to be receiving the ID as one of its params and the goal here will basically to be returning props that get passed into our job component so we do that by returning an object that has a props object cool so if we wanted to look at the params for example to see what we're receiving I can just refresh this page pop into the console and here you can see we're receiving the ID so we're going to use that to query directly to our database I've already set up a connection to NEX which is a query builder it basically allows you to execute SQL so I'll just show you what that looks like that's in SRC dB so I'm creating a next connection and exporting it here I've got this death package I've been playing around with when you deploy this code to a server this environment if you get traffic it's always spinning up new server list functions and it can overload your connections to like cheap hosted databases so I was trying to sort of kill them off as soon as the server list functions are killed but this is besides the point so I'm able to import this connection to the database and we'll just come in here and we'll query the job that we want so conce job equals a weight because it's an async so DB will select star from the jobs table where the ID matches the one that came in via the params and we want the first one because it's just finding one job right so just like that now I can I can look at the data make sure I got it right so console that log that job out come here here I can see that it found the job for company one rails developer so I can pass that job into this component and that will allow me to receive this here the job and I could come into this div and I could do something like put in h1 here and we'll put the job dot title into the h1 so there we go rails developer goto to react developer three payments rails developer so we have our jobs pages rendering the way it works is when you load the page it will basically run this code on the server and the result of that will be passed to your component which will be run on the client in the browser so why don't we just grab the the company as well so company is a weight DB select star from companies where the ID matches the job company ID and we want the first so now we can pass in the company as well which means we can receive it here in the component and we could put that it's a say rails developer at company name just like that there we go so payments rails developer at Shopify rails developer at github so one other thing you have available to you here is the node HTTP response object say the user requests a page that that doesn't exist or you want to redirect them elsewhere for example so we'll just say if it couldn't find a job with that ID we will redirect are sort of weird in this but you you basically write the HTTP status code along with the location you want to send the user to we end the response and then we can just return to get out of this function so that it doesn't keep trying to run this code down here so now say if I I only have like four or five jobs all seven it just redirects me back to the home page but if I go to one where it finds it hope one doesn't exist jobs one there we go rails developer at github so use this technique anytime you want to sort of without fear grab data server-side doesn't need to be from the database could be from another graph QL API or REST API it could be from the file system it could be from MongoDB could be from anywhere and you don't have to worry about it loading like next in the client next Jes takes care of all of that for you and this will execute every request on the server-side the next type of data fetching and two additional functions or hooks that next yes introduced are to build static pages so static pages are built at Build time so basically when you deploy your next code to say now are sorry now to the site Placerville is platform that they have it will build all these pages at Build time when you deploy and then whenever a user visits your site it will serve up cached versions of those pages so they'll be lightning quick and if two functions you want to work with in this case the first function is export and async function that is called gets static paths cool so what you do with this function is you basically return an array of all of the pages that should be generated so we're gonna generate a page for each one of the featured companies so these three here github Shopify and where I work at flip give so Twitter is another company in here it's not feature though so we won't build a page for it but I'll show you how you can sort of lazy load that page via fallback so as soon as someone visits Twitter it will be generated dynamically and it'll be cached from that point forward so what you want to do is again grab your connection to the database we are going to be fetching the jobs sorry the the companies from the database so const companies equals a weight DB dot select star from companies where featured is true and if you wanted you could limit it if you want it's up to you you could order them and grab the first 50 or whatever so what you want to do here is return to things well an object that has paths so this will be array of the pages to statically generate and whether or not to allow for fallback pages or not so if you're gonna create every page possible you can say fall back false but if you want it too lazy create something like Twitter you can do fallback true cool so I'm going to build the paths so what I'm going to do is map the companies so each company and for each company I will return props and in this case I'm only gonna be giving the ID so company ID so if you wanted to you could just select ID here to make it a little bit more efficient um and you could even come in here and you could say I want just the ID and then you could clean this up and just pass the ID and now the code is really nice and clean so what we want to do now that we have an array because we map them of objects with props we will pass the props in here so we can just do that and that part of it is done so where do these passes go you have to use this hand-in-hand with another function that they created so export async function get static props so this function will receive it will be called once for every path that this function returned so once per company and you have access to the props so we will come in here and we'll grab the props and sorry I'm a liar it's not props it's params my bad you receive params okay sorry if that confused you each path contains the params that are passed to get static props so what we can do with the params now we're receiving each company's ID is we can load the company from the database so Kant's company equals a weight DB dot select star from companies where ID is params ID and we'll grab the first one and then very much like get server-side props your job is to return the props that will be passed to the component when it renders so here we can return an object with props and we'll pass the company as props cool so because we've generated a path for each of our companies this gets static props has been called once per company so we could even see that by a console dot logging company now that said I don't think it actually runs that when you're developing locally it will only sort of generate these on-demand as needed but if you were to build this and deploy it this would be called once per company so scratch that now we have our company as a prop that we can use up here so company and we can say jobs at two this is an h1 jobs at company name like that so now ooh there we go if I go to companies one you why our parameter ID was not provided as a string okay I know what this is this means I think what we have to do is the database gives us this ID as a as an integer but I think all of these props have to be strings I believe so what we will do II was yeah so what we can just do is say ID is ID dot two string there we go so it has to be a string because normally those params come via the URL this part of the path and they all come as string so it wants them all the strings so now we've got jobs at github jobs our choppa Phi etc so when we deploy this it will create pages for the three featured jobs but then if you were to request Twitter which is ID for that's not like an ID for some reason can I read of undefined so let's see what we're receiving console dot log params you you some reason it's not like in that restart this maybe that's the issue for some reason no doesn't like that I did say fall back true which is weird um hmm I don't know with this ah I know I figured it out okay so when you're dealing with fallbacks you have to handle it a little bit as a special case because the first time the user requests it it has to go to the server generate this page and get a response back and then render it out so what you do in that situation all of this code was fine actually the issue was that we have to put a check in to see if it's still loading the fallback or if it already has got the data yet so what we can do is access the router via the use router function and then what we can do is check if the router is equal to is fallback so if that's true we can return loading job like that so basically this component will be called twice once in its loading State and a second time in its when it has data let's see if that works now Twitter works and you can see for a second it says loading job and then we've got jobs at Twitter cool figured it out oh boy so what I wanted to show was a third way we basically covered two ways now of grabbing data one which is server-side sort of on demand every request another one which is finding static paths at Build time and then building each of those pages statically with an optional fallback but I want to show how you could basically combine static pages with loading additional data client-side in the browser so I've installed this library SWR from the same folks at site and it is used for basically data fetching in a hook client side in react so what I'm going to do is create another component called jobs and I'm going to pass in the ID of the company that I'm trying to load jobs for so we'll come down here below and we'll create that functional component just I'm gonna put it in the same file maybe you'd have a components folder out here but just for demo purposes it's going to be right here so function jobs it will receive the ID of the company and then our Joel our our goal is to go to the backend and grab those but client side so what we are going to do is use SWR i've got a fully separate video on this so I'm not going to go into how it works I'll link to that video below so what we can do is we can say Const data and maybe loading is equal to use SWR and the way you SWR works is you have to pass in a key so in our case we're going to be giving the path that we want to request in the back end so I created a path to grab jobs for a specific company so this is a a JSON endpoint I'm not going to go into this code but it's basically fetching jobs from the database and we're returning them as JSON we can see that in action if we open up a new tab and we say API jobs for company one we get all the all the jobs for that company so that's what we're going to be fetching the data from pillows it is api jobs for a specific company which is the one being passed to this component and you need a fetcher function with with use SWR so it's this one that will receive this path and it will use fetch to go and grab that from the back end so what we can do here is let's just say if not data or loading let's just return null we won't render anything at all if we get to this point we know we have data so what we can do is we can return a ul where we map all of the jobs so data is actually the job so why don't we give it a proper name here jobs will map them so for each job we're going to create a list item with a key of its ID and in here we will just put the job title so job dot title like that cool so I don't think Twitter has any jobs but if we go to the first one here at github it's not liking it for summer troubleshoot internal server error all right what is happening cannot find module API jobs I have been having this issue with next yes and now so I'm just going to stop the server I'm just gonna clear out the the next folder and restart and hopefully it will just fix itself it's probably because I've been like deleting and resetting code as I've been building this and then demoing it now if I load the page there we go change nothing and somehow it works wicked so if I go to company 2 it loads this part statically and then client side it goes and it grabs the jobs for this company so what you can do is you can build static pages that have some content and then when the user visits them you can client side using muse SWR or react query go and fetch additional data and we can see here if we go to the network and we look at the jobs endpoint we can see that it's making that request and it's getting back the JSON data as a response cool so that's what I wanted to show today and you can see I can link into say Shopify loads of the static page and then that's there that's what I wanted to show today basically the three new hooks or functions that were introduced with next 9.3 so what we covered again were get server-side props run server-side you can do some pretty cool stuff like just going right to the database and returning props that get passed into your component we also looked at two functions here get static paths to basically return all of the pages so in this you can imagine reading a whole bunch of markdown files loading it from the database like I did making an API call to a wordpress site making an API call to another CMS it's totally up to you what you do with it you can build them all at Build time or you can just build a few of them if you have a thousand pages you might not want to pre build all of them so you build the important ones like the featured ones like I did and then you fall back for all the other ones which get cached and then get all the benefits of static builds after that so this function gets called once per path or per page given the params you can load whatever data you want and then return that that would be passed to your page your component we also showed how to handle the fallback that screwed me up for a few minutes but basically to show handle the loading state and then we created a little jobs component that will after page load client side using the use SWR hook and fetch go back to your server or wherever your loading data from could be graph QL could be whatever grab the data and then you can render that client side that will be fetched on every page load that's what we covered today I'll of next j/s and I love these new hooks functions that they've added I much prefer them over get initial props because I I built a website and I was loading cookies and it was it was always a battle like in my in the browser am I in the server this way you always know where you are and it's a lot more straightforward in my opinion hope you enjoyed the video take care bye
Info
Channel: Leigh Halliday
Views: 9,540
Rating: 4.9425287 out of 5
Keywords: nextjs, next.js, nextjs 9.3, getServerSideProps, getStaticPaths, getStaticProps, react, data fetching, react data fetching, useSWR, react hooks, react tutorial, nextjs tutorial, react SSR, react static pages, react server side, knex, postgres
Id: QABkof8ygzI
Channel Id: undefined
Length: 27min 33sec (1653 seconds)
Published: Sun Apr 19 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.