1 00:00:00,000 --> 00:00:04,959 We've build our first subcomponent of the application, the GuestList component, and 2 00:00:04,959 --> 00:00:08,541 it's successfully rendering itself with data from the state. 3 00:00:08,541 --> 00:00:10,922 But, there's no way to interact with it, 4 00:00:10,922 --> 00:00:14,971 more specifically there's no way to change the application state yet. 5 00:00:14,971 --> 00:00:19,829 To do that, we'll create some event handlers in App.js and 6 00:00:19,829 --> 00:00:22,889 hand them down to GuestList as props. 7 00:00:22,889 --> 00:00:25,844 So first, let's extract the list item and 8 00:00:25,844 --> 00:00:29,386 the GuestList component out to its own component. 9 00:00:29,386 --> 00:00:33,959 Now I like to save a little time when I can, so in this case I'll just save this 10 00:00:33,959 --> 00:00:38,693 GuestList component as a new file, then alter it from there to new component. 11 00:00:38,693 --> 00:00:41,530 So I'll save it as Guest.js. 12 00:00:44,527 --> 00:00:49,117 Then in this new file I'll select all the variables 13 00:00:49,117 --> 00:00:53,395 named GuestList and delete the list at the end. 14 00:00:53,395 --> 00:00:58,865 And Adam, I'm typing Ctrl+D to select and change them all at once. 15 00:00:58,865 --> 00:01:04,764 So, this component will return list item so I'll delete the UL and map function. 16 00:01:13,532 --> 00:01:18,001 And instead of guest.name and guest.isConfirmed, 17 00:01:18,001 --> 00:01:23,161 we'll pass the data in onProps so I'll change guest to props. 18 00:01:27,310 --> 00:01:29,748 Then I want to validate those two props, so, 19 00:01:29,748 --> 00:01:32,777 I'll set propTypes for them down here in my propTypes. 20 00:01:34,452 --> 00:01:38,335 I'll set name, name will be a string, 21 00:01:41,844 --> 00:01:45,535 And isConfirmed will be a required Boolean. 22 00:01:54,900 --> 00:01:59,384 Finally we don't need a key anymore since keeping track of different guests 23 00:01:59,384 --> 00:02:03,037 is the responsibility of the parent component, guest list. 24 00:02:03,037 --> 00:02:07,117 This component can be blissfully unaware of any other guest that may or 25 00:02:07,117 --> 00:02:08,786 may not exist on this state. 26 00:02:08,786 --> 00:02:14,683 So I'll delete the key and now I'll close this and 27 00:02:14,683 --> 00:02:17,782 open up guest list again. 28 00:02:17,782 --> 00:02:21,531 And first I'll import the new guest component at the top, 29 00:02:29,595 --> 00:02:36,580 And I'll replace the list item returned by the map function with the guest component. 30 00:02:43,897 --> 00:02:48,822 I'll keep the key, but I'll add a name prop, 31 00:02:48,822 --> 00:02:54,126 and pass it guest.name and an isConfirmed prop, 32 00:02:54,126 --> 00:02:58,181 which will get guest.isConfirmed. 33 00:03:00,410 --> 00:03:03,498 I'll give this a save and nothing has changed, 34 00:03:03,498 --> 00:03:05,823 which is just what we wanted to see. 35 00:03:05,823 --> 00:03:10,662 So now we'll connect the confirmed boxes to effect the state of application. 36 00:03:10,662 --> 00:03:14,778 First, let's review how events are handled and React. 37 00:03:14,778 --> 00:03:17,935 Data always flows downward in a React app. 38 00:03:17,935 --> 00:03:22,778 This means an ancestor state can be passed down to it's descendants through props. 39 00:03:22,778 --> 00:03:25,519 But descendants can't past data back up. 40 00:03:25,519 --> 00:03:29,215 Sometimes data needs to travel back to an ancestor though for 41 00:03:29,215 --> 00:03:33,924 example a form field is a common example of a decadent that need to report it's 42 00:03:33,924 --> 00:03:35,744 content up to the larger app. 43 00:03:35,744 --> 00:03:39,597 To do that an ancestor must define a call back function and 44 00:03:39,597 --> 00:03:41,615 pass it down to the decadent. 45 00:03:41,615 --> 00:03:45,323 The function can accept data, like the text from an input and 46 00:03:45,323 --> 00:03:47,150 add it to the ancestor state. 47 00:03:47,150 --> 00:03:51,584 That function can then be bound to events on that child component, 48 00:03:51,584 --> 00:03:55,794 sending data back to the ancestor every time the event occurs. 49 00:03:55,794 --> 00:04:00,336 So, for example, when a text input element's on change event occurs, 50 00:04:00,336 --> 00:04:04,952 meaning the user is typing into the field an ancestor's call back bound to 51 00:04:04,952 --> 00:04:08,536 that event will fire passing the text up to the ancestor. 52 00:04:10,243 --> 00:04:13,827 Let's set up a handler in App.js. 53 00:04:13,827 --> 00:04:18,979 Below the state object I'll create a new method called toggleConfirmation. 54 00:04:21,891 --> 00:04:25,806 Because confirmation can either be true or false. 55 00:04:25,806 --> 00:04:30,400 We can just flip the value of the check box every time this handler runs, 56 00:04:30,400 --> 00:04:34,703 so that means we won't need it to accept a value from the check box. 57 00:04:34,703 --> 00:04:39,682 We can just take whatever value was stored and flip it to its opposite because there 58 00:04:39,682 --> 00:04:44,602 are a number of guests, we'll need the index of the guest whose state to change. 59 00:04:44,602 --> 00:04:46,981 I'll call it indexToChange. 60 00:04:49,605 --> 00:04:55,205 And I'll also change the name of the function adding At at the end. 61 00:04:55,205 --> 00:04:59,350 This is just a convention to help us remember this function takes the index of 62 00:04:59,350 --> 00:05:00,532 the element toggle. 63 00:05:00,532 --> 00:05:05,832 So in other words it will toggle the confirmation at specified index. 64 00:05:05,832 --> 00:05:09,992 And now, it's just a matter of changing the state. 65 00:05:09,992 --> 00:05:12,915 So I'll call this.setstate, 66 00:05:16,157 --> 00:05:20,061 Passing in a new object that will become the state. 67 00:05:20,061 --> 00:05:24,165 The property that we want to change is guests so 68 00:05:24,165 --> 00:05:29,122 inside we'll add guests and it's going to be an array. 69 00:05:29,122 --> 00:05:34,933 Now, we only want to change one member of the array though and leave the rest alone. 70 00:05:34,933 --> 00:05:41,218 So we can use the map method to go through the existing guests array, 71 00:05:41,218 --> 00:05:45,088 we'll say this.state.guests.map. 72 00:05:47,082 --> 00:05:49,205 Passing it guest and index. 73 00:05:52,160 --> 00:05:56,618 And we only want to make a change if the index matches. 74 00:05:56,618 --> 00:06:02,784 So we'll type if (index === indexToChange 75 00:06:06,741 --> 00:06:11,504 And we want to produce an object with the same name, but with the opposite value for 76 00:06:11,504 --> 00:06:12,411 isConfirmed. 77 00:06:12,411 --> 00:06:16,951 So in the return we'll add isConfirmed and 78 00:06:16,951 --> 00:06:20,618 set it to !guest.isConfirmed. 79 00:06:23,914 --> 00:06:27,340 Now we could just write the name property as well and 80 00:06:27,340 --> 00:06:31,722 assign the current name value to it like this, guest.name, but 81 00:06:31,722 --> 00:06:34,909 if we ever add more properties to this object for 82 00:06:34,909 --> 00:06:39,790 any reason, we'd have to come, find this place again, and change it. 83 00:06:39,790 --> 00:06:45,408 So we'll make our code more flexible, to use the object spread operator here. 84 00:06:45,408 --> 00:06:50,372 So we'll replace the entire name property with ...guest. 85 00:06:52,409 --> 00:06:55,652 You can learn more about the spread operator in the Teacher's Notes. 86 00:06:55,652 --> 00:07:00,600 Basically, it just transfers the keys and values from one object to another. 87 00:07:00,600 --> 00:07:01,632 Here the keys and 88 00:07:01,632 --> 00:07:05,986 values from guest are placed in this new object we're constructing. 89 00:07:05,986 --> 00:07:08,731 Because guest has an outdated value for 90 00:07:08,731 --> 00:07:13,639 is confirmed though we'll need this second line to overwrite that key 91 00:07:13,639 --> 00:07:18,396 with the new updated value which is the opposite of whatever it was. 92 00:07:18,396 --> 00:07:22,576 This is a much more flexible way of creating a new object. 93 00:07:22,576 --> 00:07:26,905 I recommend following this pattern for these kinds of changes to state in React. 94 00:07:26,905 --> 00:07:32,883 Finally, if the index doesn't match, let's return the same object, 95 00:07:32,883 --> 00:07:37,203 leaving it untouched so we'll write return guest. 96 00:07:37,203 --> 00:07:39,581 Our handler is now complete. 97 00:07:39,581 --> 00:07:42,189 The next step is to connect it to the form input so 98 00:07:42,189 --> 00:07:44,157 checking it will fire the handler. 99 00:07:44,157 --> 00:07:46,429 We'll do that in the next video.