1 00:00:02,130 --> 00:00:08,390 So before we conclude all of that here and you can always dive into the github repository to learn more, 2 00:00:08,460 --> 00:00:12,300 let me show you one super important feature of nextJS, 3 00:00:12,420 --> 00:00:17,270 let's go back to the index.js file in the pages folder, so our main page here 4 00:00:17,310 --> 00:00:23,170 and let's turn this from a functional into a class based component by naming this class IndexPage 5 00:00:23,170 --> 00:00:27,320 maybe, exporting this as a default, 6 00:00:27,370 --> 00:00:34,930 let's them therefore also export component from react because we still as always need to extend component 7 00:00:34,930 --> 00:00:35,560 here 8 00:00:36,790 --> 00:00:40,160 and there we have a render method, so this is all just the same 9 00:00:40,180 --> 00:00:46,120 where we return some jsx and the jsx of course is the jsx I returned before. Let's get rid of 10 00:00:46,120 --> 00:00:50,830 that stuff down there, quickly reformat and we're good to go, 11 00:00:51,010 --> 00:00:53,790 everything should still work as before. 12 00:00:53,890 --> 00:00:58,180 Now we're using a class based component and that's one thing I wanted to show you, 13 00:00:58,270 --> 00:01:01,830 I also want to show you a special lifecycle hook you can use though 14 00:01:01,960 --> 00:01:10,610 and unlike the react lifecycle hooks, that lifecycle hook would even be available in functional components. 15 00:01:10,660 --> 00:01:11,810 I'll show you how to use it there 16 00:01:11,820 --> 00:01:14,390 too but let's start in the class based one. 17 00:01:14,410 --> 00:01:23,680 It's called getInitialProps and it will receive an argument which describes the context of your application, 18 00:01:23,680 --> 00:01:27,490 let's simply log context to see what's inside of that 19 00:01:27,520 --> 00:01:29,030 when this gets called. 20 00:01:29,170 --> 00:01:35,470 Now to see what's inside of that, we need to change it because it's not a normal lifecycle method 21 00:01:35,470 --> 00:01:41,530 like the other ones, instead it's a static method which means it can be called without the component being 22 00:01:41,530 --> 00:01:48,220 instantiated yet and it's an asynchronous method which means it doesn't resolve, it doesn't return something 23 00:01:48,250 --> 00:01:49,310 instantly. 24 00:01:49,660 --> 00:01:54,500 Now let's save this and wait for a compilation and let's reload the page then, 25 00:01:54,550 --> 00:01:58,040 now we see that it should resolve to an object. 26 00:01:58,150 --> 00:02:01,940 So let's fine tune it and let's make sure we actually return an object, 27 00:02:01,960 --> 00:02:03,360 it can be empty though. 28 00:02:04,270 --> 00:02:10,720 And now with that, let's reload the page and we don't see anything here, we don't even see a console log. 29 00:02:11,620 --> 00:02:18,790 We can see something in a console though, in the console here where we ran npm run dev because this 30 00:02:18,790 --> 00:02:26,560 code actually is executed on the server first, it will only be executed on the child if you navigated 31 00:02:26,560 --> 00:02:27,810 there within the app 32 00:02:27,820 --> 00:02:33,700 so by clicking a link for example. If you navigated there by typing the URL and hitting enter or refresh, 33 00:02:34,060 --> 00:02:35,690 it executes on the server, 34 00:02:35,770 --> 00:02:38,580 that's the special thing about this lifecycle method. 35 00:02:38,950 --> 00:02:45,750 It executes either on the server or the client and you can use it to initialize your app before it loads, 36 00:02:45,790 --> 00:02:54,090 so on the server for example in getInitialProps, you could fetch data from a database and then pre- 37 00:02:54,090 --> 00:03:00,730 populate the props this page component will receive with props of your choice. 38 00:03:00,760 --> 00:03:07,300 For example here we could hard code the app name prop which is a super app which of course here isn't 39 00:03:07,300 --> 00:03:13,990 fetched from some database but you could easily do that since it's an async method, you can use await 40 00:03:14,060 --> 00:03:20,500 keyword in here to await for a promised resolve and you would typically have a promise or something 41 00:03:20,500 --> 00:03:23,060 like get if you are reaching out to a web server, 42 00:03:23,110 --> 00:03:25,270 for example with axios. 43 00:03:25,450 --> 00:03:31,720 Now if you don't want to use async here, what you can also do is you can still use normal static method 44 00:03:31,720 --> 00:03:35,340 like this in case you don't know that async await syntax 45 00:03:35,340 --> 00:03:41,170 and then what you would do here is you would create a promise or use a package like axios which does something 46 00:03:41,170 --> 00:03:48,810 that turns a promise, here I'll create one manually with the new promise keyword and there, if you create 47 00:03:48,810 --> 00:03:55,720 it manually on your own, you would always pass a function which receives resolve and reject, two functions 48 00:03:55,720 --> 00:03:56,870 that can execute. 49 00:03:57,010 --> 00:04:03,130 If that's all new to you, I recommend refreshing the promise knowledge in general as this is an important 50 00:04:03,130 --> 00:04:05,370 javascript feature. 51 00:04:06,260 --> 00:04:13,330 In a promise, you typically execute async code and again often times, you don't write promises on your 52 00:04:13,330 --> 00:04:18,850 own but you use some package which wraps some async action like reaching out to a server in a promise, 53 00:04:18,950 --> 00:04:23,200 axios which we used in this course does that for example. 54 00:04:23,200 --> 00:04:30,850 So here in that async action like setTimeout to fake, the reaching out to a server, you would then call 55 00:04:30,850 --> 00:04:38,330 resolve and return your data like the name of the app, Super App. And then what you can do 56 00:04:38,580 --> 00:04:40,010 or let's name it app name here 57 00:04:40,010 --> 00:04:49,330 too. What you can do is you can listen to that promise with the then keyword and pass a function to then 58 00:04:49,420 --> 00:04:53,120 which will be executed as soon as the promise resolved. 59 00:04:53,380 --> 00:04:56,530 Now this then part is what we leave out here, 60 00:04:56,530 --> 00:05:03,850 instead here we simply return the entire promise in our getInitialProps method and nextJS will 61 00:05:03,850 --> 00:05:10,210 take care about listening to its result and then pre-populate our props once the result is there 62 00:05:10,480 --> 00:05:14,600 and only render the page once the result is there. 63 00:05:14,620 --> 00:05:23,650 So now here in our page, we could say the main page auth and then render this props app name and we 64 00:05:23,650 --> 00:05:31,860 know that this will be populated because we pre-populate the props here in our getInitialProps function. 65 00:05:31,930 --> 00:05:36,830 If we now save this file here and we reload this page, 66 00:05:36,950 --> 00:05:41,150 you'll see it takes a bit longer to load because it needs to wait for this second 67 00:05:41,150 --> 00:05:49,700 here, we specified that on setTimeout but then it actually displays Super App here because it did pre-populate 68 00:05:49,700 --> 00:05:52,300 our props. So getInitialProps, 69 00:05:52,340 --> 00:05:59,660 super important working together with promises, either promises written by you or returned by third party 70 00:05:59,660 --> 00:06:00,770 packages, 71 00:06:00,770 --> 00:06:04,940 it'll wait for them to resolve and pre-populate your props. 72 00:06:04,940 --> 00:06:07,480 Now let's dive into that context we get here, 73 00:06:07,640 --> 00:06:13,850 we print it here with console log and we can inspect it here on the server since we loaded the page by 74 00:06:13,850 --> 00:06:15,600 simply refreshing it. 75 00:06:15,670 --> 00:06:20,910 Now it's quite hard to read that here because we see all the nested properties and so on too, 76 00:06:21,080 --> 00:06:25,900 so let's get rid of that and instead have a look at the official docs of nextJS. 77 00:06:25,910 --> 00:06:32,960 There if we go to the getInitialProps part which is about fetching data and the component 78 00:06:32,970 --> 00:06:34,340 lifecycle, 79 00:06:34,340 --> 00:06:42,170 we see that the context has the path name of the page we loaded so what's after the slash, any query params 80 00:06:42,160 --> 00:06:49,010 we might have and important on the server only though, the request and response object. 81 00:06:49,010 --> 00:06:53,450 So basically the same you would get in an expressJS environment, 82 00:06:53,840 --> 00:06:58,700 this allows you to really get all the information all the requests that reach the page. 83 00:06:58,700 --> 00:07:04,430 You might not need that but there are also some use cases where this can be really helpful as it allows 84 00:07:04,430 --> 00:07:08,440 you to analyze what exactly the user requested and so on. 85 00:07:08,720 --> 00:07:12,070 So here we're not taking advantage of the incoming context data, 86 00:07:12,200 --> 00:07:18,620 we could do so though, of course we're nonetheless using this to initialize our props which is an important 87 00:07:18,620 --> 00:07:20,780 function of this method, 88 00:07:20,780 --> 00:07:25,020 it's probably the reason why it's called getInitialProps. 89 00:07:25,040 --> 00:07:28,700 Now how do we use this in a functional component? 90 00:07:28,890 --> 00:07:29,910 This is possible, 91 00:07:29,930 --> 00:07:37,480 you can see how it works on the official documentation too, you simply create your constant and then add 92 00:07:37,520 --> 00:07:46,160 this as it is a static method to that constant after you created it. A function which a functional component 93 00:07:46,160 --> 00:07:54,320 of course is in the end allows you to add something to it inside of that function, a function which this 94 00:07:54,320 --> 00:08:00,770 constant here in the end is and which our constant here also is is just a javascript object so we can 95 00:08:00,770 --> 00:08:03,570 add static methods to it. 96 00:08:03,740 --> 00:08:10,860 So I can just say authIndexPage.getInitialProps and therefore I define this method and nextJS 97 00:08:10,870 --> 00:08:12,790 will only call it if it is defined 98 00:08:12,800 --> 00:08:18,290 otherwise it will just skip it and then we define it just as we did in the other file. 99 00:08:18,290 --> 00:08:26,150 So there, I can also set up my promise here and then return it and set getInitialProps equal to an 100 00:08:26,150 --> 00:08:32,570 arrow function where I would receive context passed in automatically by nextJS and then create 101 00:08:32,570 --> 00:08:34,670 my promise and return it. 102 00:08:34,780 --> 00:08:42,680 And here we can say app names Super App Auth to really see that something's different and here, we could output 103 00:08:42,680 --> 00:08:46,120 is in our jsx code of course 104 00:08:46,120 --> 00:08:50,290 too, app name. If we now save this, 105 00:08:50,300 --> 00:08:57,950 we see that if we reload our main page not /auth, it of course still works but if it go to auth, it 106 00:08:57,950 --> 00:09:05,180 takes a second because it needed to resolve that and then it just fails because I forgot to pass props 107 00:09:05,180 --> 00:09:06,950 into that functional component. 108 00:09:07,070 --> 00:09:08,670 We have to do that of course, 109 00:09:08,810 --> 00:09:10,280 so let's try this again, 110 00:09:10,280 --> 00:09:15,380 let's go back to the main page first and then let's click on auth and wait that second 111 00:09:15,470 --> 00:09:18,920 and then we go there and also see that populated. 112 00:09:18,920 --> 00:09:20,850 So getInitialProps, 113 00:09:20,870 --> 00:09:27,020 super useful lifecycle which works in both functional and class based components and which allows you 114 00:09:27,200 --> 00:09:31,450 to initialize your props before the page is actually loaded.