The GuestList component is successfully rendering with data from the state, but there's no way to interact with it. More specifically, there's no way to change the application state yet. To do that, we'll create event handlers in App.js and hand them down to GuestList as props.
We've build our first subcomponent of the application, the GuestList component, and 0:00 it's successfully rendering itself with data from the state. 0:04 But, there's no way to interact with it, 0:08 more specifically there's no way to change the application state yet. 0:10 To do that, we'll create some event handlers in App.js and 0:14 hand them down to GuestList as props. 0:19 So first, let's extract the list item and 0:22 the GuestList component out to its own component. 0:25 Now I like to save a little time when I can, so in this case I'll just save this 0:29 GuestList component as a new file, then alter it from there to new component. 0:33 So I'll save it as Guest.js. 0:38 Then in this new file I'll select all the variables 0:44 named GuestList and delete the list at the end. 0:49 And Adam, I'm typing Ctrl+D to select and change them all at once. 0:53 So, this component will return list item so I'll delete the UL and map function. 0:58 And instead of guest.name and guest.isConfirmed, 1:13 we'll pass the data in onProps so I'll change guest to props. 1:18 Then I want to validate those two props, so, 1:27 I'll set propTypes for them down here in my propTypes. 1:29 I'll set name, name will be a string, 1:34 And isConfirmed will be a required Boolean. 1:41 Finally we don't need a key anymore since keeping track of different guests 1:54 is the responsibility of the parent component, guest list. 1:59 This component can be blissfully unaware of any other guest that may or 2:03 may not exist on this state. 2:07 So I'll delete the key and now I'll close this and 2:08 open up guest list again. 2:14 And first I'll import the new guest component at the top, 2:17 And I'll replace the list item returned by the map function with the guest component. 2:29 I'll keep the key, but I'll add a name prop, 2:43 and pass it guest.name and an isConfirmed prop, 2:48 which will get guest.isConfirmed. 2:54 I'll give this a save and nothing has changed, 3:00 which is just what we wanted to see. 3:03 So now we'll connect the confirmed boxes to effect the state of application. 3:05 First, let's review how events are handled and React. 3:10 Data always flows downward in a React app. 3:14 This means an ancestor state can be passed down to it's descendants through props. 3:17 But descendants can't past data back up. 3:22 Sometimes data needs to travel back to an ancestor though for 3:25 example a form field is a common example of a decadent that need to report it's 3:29 content up to the larger app. 3:33 To do that an ancestor must define a call back function and 3:35 pass it down to the decadent. 3:39 The function can accept data, like the text from an input and 3:41 add it to the ancestor state. 3:45 That function can then be bound to events on that child component, 3:47 sending data back to the ancestor every time the event occurs. 3:51 So, for example, when a text input element's on change event occurs, 3:55 meaning the user is typing into the field an ancestor's call back bound to 4:00 that event will fire passing the text up to the ancestor. 4:04 Let's set up a handler in App.js. 4:10 Below the state object I'll create a new method called toggleConfirmation. 4:13 Because confirmation can either be true or false. 4:21 We can just flip the value of the check box every time this handler runs, 4:25 so that means we won't need it to accept a value from the check box. 4:30 We can just take whatever value was stored and flip it to its opposite because there 4:34 are a number of guests, we'll need the index of the guest whose state to change. 4:39 I'll call it indexToChange. 4:44 And I'll also change the name of the function adding At at the end. 4:49 This is just a convention to help us remember this function takes the index of 4:55 the element toggle. 4:59 So in other words it will toggle the confirmation at specified index. 5:00 And now, it's just a matter of changing the state. 5:05 So I'll call this.setstate, 5:09 Passing in a new object that will become the state. 5:16 The property that we want to change is guests so 5:20 inside we'll add guests and it's going to be an array. 5:24 Now, we only want to change one member of the array though and leave the rest alone. 5:29 So we can use the map method to go through the existing guests array, 5:34 we'll say this.state.guests.map. 5:41 Passing it guest and index. 5:47 And we only want to make a change if the index matches. 5:52 So we'll type if (index === indexToChange 5:56 And we want to produce an object with the same name, but with the opposite value for 6:06 isConfirmed. 6:11 So in the return we'll add isConfirmed and 6:12 set it to !guest.isConfirmed. 6:16 Now we could just write the name property as well and 6:23 assign the current name value to it like this, guest.name, but 6:27 if we ever add more properties to this object for 6:31 any reason, we'd have to come, find this place again, and change it. 6:34 So we'll make our code more flexible, to use the object spread operator here. 6:39 So we'll replace the entire name property with ...guest. 6:45 You can learn more about the spread operator in the Teacher's Notes. 6:52 Basically, it just transfers the keys and values from one object to another. 6:55 Here the keys and 7:00 values from guest are placed in this new object we're constructing. 7:01 Because guest has an outdated value for 7:05 is confirmed though we'll need this second line to overwrite that key 7:08 with the new updated value which is the opposite of whatever it was. 7:13 This is a much more flexible way of creating a new object. 7:18 I recommend following this pattern for these kinds of changes to state in React. 7:22 Finally, if the index doesn't match, let's return the same object, 7:26 leaving it untouched so we'll write return guest. 7:32 Our handler is now complete. 7:37 The next step is to connect it to the form input so 7:39 checking it will fire the handler. 7:42 We'll do that in the next video. 7:44
You need to sign up for Treehouse in order to download course files.Sign up