1 00:00:02,240 --> 00:00:03,640 To output our own goals, 2 00:00:03,680 --> 00:00:08,120 I'll add a new component in the components folder and to keep it manageable, 3 00:00:08,150 --> 00:00:11,420 I'll actually create a new subfolder for every component, 4 00:00:11,420 --> 00:00:17,630 this is not a must do but I personally like doing this because then I can quickly find all my components. 5 00:00:17,630 --> 00:00:20,950 Of course you now need to adjust your import here in app.js, 6 00:00:21,110 --> 00:00:23,990 my IDE did it automatically, in case that did not happen, 7 00:00:23,990 --> 00:00:28,670 make sure you adjust your goal list import to reflect that new folder 8 00:00:28,700 --> 00:00:35,750 I added and then I will add a new goals component here in the components folder as well, in there 9 00:00:35,750 --> 00:00:39,180 add a new goal.js file and a new goal.css 10 00:00:39,270 --> 00:00:40,430 file 11 00:00:40,430 --> 00:00:45,830 if we want to apply some styling. Now in the NewGoal.js file, we first of all need to import React 12 00:00:45,830 --> 00:00:46,700 from React, 13 00:00:46,700 --> 00:00:47,930 you always need to do that 14 00:00:47,960 --> 00:00:54,770 otherwise you can't use jsx in that file because keep in mind, jsx is translated to React create 15 00:00:54,800 --> 00:01:00,070 element and then here, I have my new goal component here. 16 00:01:00,110 --> 00:01:02,750 We could accept props but as long as we don't need them, 17 00:01:02,750 --> 00:01:04,310 we don't have to 18 00:01:04,310 --> 00:01:09,690 and then I export new goal. Now in app.js, 19 00:01:09,760 --> 00:01:13,850 I want to render new goal, so I will import new goal, 20 00:01:13,900 --> 00:01:19,620 again the name here is up to you but it should start with a capital starting character and I import 21 00:01:19,620 --> 00:01:26,860 this from components, new goal, new goal and then here we can render this above our goal list let's say 22 00:01:27,100 --> 00:01:28,290 like that. 23 00:01:28,390 --> 00:01:34,930 Now this wouldn't work because new goal is not yet a valid React component because it's a function right 24 00:01:34,930 --> 00:01:40,290 now but it's not a function that works as a React component because it's not doing one crucial thing, 25 00:01:40,540 --> 00:01:48,550 it's not returning jsx, so let's return some jsx here and there to keep things simple, I'll add a form 26 00:01:49,180 --> 00:01:57,270 and in that form, I'll add an input field, type text, self closing element. In regular HTML, 27 00:01:57,270 --> 00:02:03,810 this doesn't have to be self closing, in jsx this does have to be self closing and then a button which 28 00:02:03,810 --> 00:02:04,530 is of type 29 00:02:04,620 --> 00:02:13,090 submit where I say add goal. A very simple form and if we now save that, you should see it here. 30 00:02:13,100 --> 00:02:17,360 Now let's add some styling to make this look a bit prettier, 31 00:02:17,360 --> 00:02:25,130 for that I'll add a class to the form, new-goal and I'll import the NewGoal.css file into the 32 00:02:25,130 --> 00:02:27,470 NewGoal.js file 33 00:02:27,470 --> 00:02:36,440 and then here on the new goal class which is added on the form, I'll add a margin of 2rem in all directions 34 00:02:36,920 --> 00:02:38,420 and text align 35 00:02:41,340 --> 00:02:44,960 center so that this looks a bit nicer 36 00:02:46,620 --> 00:02:50,130 and now we could also style the input and the button but I don't want to spend too much time on that, 37 00:02:50,220 --> 00:02:53,730 so I will leave it the way it is. Now right now when you click the button by the way, 38 00:02:53,730 --> 00:02:59,340 this page will reload because right now the default browser functionality will kick in, which is that 39 00:02:59,340 --> 00:03:04,320 when a button of type submit is clicked in a form, a request is sent to the server that served this 40 00:03:04,320 --> 00:03:04,880 page. 41 00:03:04,980 --> 00:03:10,380 Now that's not the behavior we want here though because here, I don't want to send a request to any server 42 00:03:10,410 --> 00:03:13,230 because we're not doing anything on the server side, 43 00:03:13,230 --> 00:03:18,570 instead I want a handle that click with Javascript and that is the first thing I'll do here. 44 00:03:18,570 --> 00:03:23,110 Let's see how we can handle events because thus far, we haven't done that. 45 00:03:23,280 --> 00:03:28,050 I want to handle the submit event of this form here and React makes that simple, 46 00:03:28,140 --> 00:03:35,180 we can add event listeners to any element, not just to the form but to any element, by adding on, lowercase 47 00:03:35,220 --> 00:03:37,010 on and then the name of the event. 48 00:03:37,020 --> 00:03:42,300 Now not every event is supported on every element but here you've got the default HTML elements 49 00:03:42,300 --> 00:03:42,990 available, 50 00:03:42,990 --> 00:03:50,000 so for example on a form element, you have the submit event, on submit. On a button, you also have on click 51 00:03:50,070 --> 00:03:56,380 but since it's a button in a form, it's better to handle this on the form itself. Now what do you pass 52 00:03:56,440 --> 00:04:00,190 as a value to on submit though? As a value, 53 00:04:00,190 --> 00:04:06,070 you have to pass a function that should be triggered when this event happens, 54 00:04:06,100 --> 00:04:08,740 so a pointer to a function. 55 00:04:08,740 --> 00:04:13,510 You could do this here with curly braces and then an anonymous inline function 56 00:04:13,510 --> 00:04:14,950 but I don't like that too much, 57 00:04:14,950 --> 00:04:20,800 instead I will create a new function here and in Javascript, you can create functions in functions. 58 00:04:20,800 --> 00:04:26,100 So inside of the new goal function which it still is in the end, I can create a new function, 59 00:04:26,380 --> 00:04:30,800 I will create my add goal handler. 60 00:04:30,890 --> 00:04:32,060 Now the naming is up to you 61 00:04:32,070 --> 00:04:38,320 but I like this naming of having handler at the end of my function name 62 00:04:38,400 --> 00:04:43,150 if it is a function that is triggered upon some event. 63 00:04:43,270 --> 00:04:44,460 So this is a function, 64 00:04:44,460 --> 00:04:49,960 in this case I'll again use an arrow function which is not a must do but I will use only arrow functions 65 00:04:49,960 --> 00:04:52,210 here and on submit 66 00:04:52,220 --> 00:04:54,710 now can point at add goal handler. 67 00:04:54,940 --> 00:04:57,730 Don't execute it here, so don't add parentheses, 68 00:04:57,790 --> 00:05:04,330 instead you just want to point at the function so that the browser and React in a common effort can 69 00:05:04,330 --> 00:05:08,950 execute this function for you when this submit event occurs. 70 00:05:08,950 --> 00:05:16,390 Now this function will get an event object, an event parameter passed in automatically by React and 71 00:05:16,400 --> 00:05:23,440 there for example we can call prevent default, which prevents the browser default of sending a request 72 00:05:23,440 --> 00:05:28,630 to some backend, which it shouldn't do here because we're not handling this on the server side here. 73 00:05:28,930 --> 00:05:35,740 Our server only serves that single index.html file, it does not have any logic to handle any submissions. 74 00:05:35,740 --> 00:05:42,400 Instead I want to handle it here in Javascript on the frontend, in my React application and for the 75 00:05:42,400 --> 00:05:49,900 moment, I'll ignore what the user entered here and I will simply instead create a dummy goal and I want 76 00:05:49,900 --> 00:05:58,230 to pass that dummy goal to app.js and add it to my course goals here so that it then is rendered here. 77 00:05:58,270 --> 00:06:07,970 Now step-by-step, we can create a new dummy goal of course in that add goal handler by adding a new goal 78 00:06:07,970 --> 00:06:11,210 constant here which is a Javascript object, 79 00:06:11,240 --> 00:06:15,590 the ID here could be a random number with math random, 80 00:06:15,590 --> 00:06:21,350 this of course is not really a unique ID but it's good enough and I'll convert it to a string, 81 00:06:21,350 --> 00:06:27,020 it's good enough for our demo application here I mean and then the text here later will be the text 82 00:06:27,020 --> 00:06:30,270 the user entered here, for now just some dummy text, 83 00:06:30,290 --> 00:06:32,510 my new goal. 84 00:06:32,560 --> 00:06:38,950 So now we have the new goal here and of course we can console log that to see that everything up to 85 00:06:38,950 --> 00:06:40,450 this point works. 86 00:06:40,450 --> 00:06:43,890 So if we save that, we see our form here 87 00:06:44,030 --> 00:06:49,300 and if I click on add goal, the page will not reload but instead we see this dummy goal here and I can 88 00:06:49,300 --> 00:06:55,490 create of course multiple goals but at the moment, they're not added to this list. To add them to the 89 00:06:55,490 --> 00:06:55,910 list, 90 00:06:55,910 --> 00:07:01,470 we now need to get that goal out of the new goal component to the app component. 91 00:07:01,520 --> 00:07:08,500 Now before, we learned we can pass data around the props but that was from app to goal list, 92 00:07:08,540 --> 00:07:12,780 so to a lower level component, a component which is included in app, 93 00:07:13,010 --> 00:07:19,460 now it's the other direction, we want to pass data from new goal to the parent component, so to the component 94 00:07:19,460 --> 00:07:21,550 which includes the new goal component. 95 00:07:21,560 --> 00:07:22,710 How does this work?