Provide and Consume State5:37 with Guil Hernandez
Now that context is set and the provider is in place, we'll provide state to the entire app. We'll set up Consumers that subscribe (or connect) to the
Provider component to make use of the context.
In the previous video, 0:00 we wrapped the children of app, in the Provider component. 0:01 The Provider usually lives at the top level of your app. 0:04 And it's what's going to provide the actual data 0:07 that needs to be shared throughout the component tree. 0:10 The provider component requires a value prop to share data. 0:13 The value can be anything, but it's usually the application state and 0:17 any actions or event handlers shared between components. 0:21 Let's first pass the value prop our player state, with this.state.players. 0:24 In React Dev tools, notice how Context.Provider now holds 0:29 the players array and state and its value prop. 0:34 So any component that's a descendant of the provider will have access to 0:39 the data given to the value prop. 0:43 And the way you access that data is with a consumer. 0:45 The Provider provides the context and a consumer consumes and 0:48 subscribes to that context. 0:53 A single provider can be connected to many consumers, 0:55 no matter how far down they are on the component tree. 0:58 So let's start by adding context to the Stats component. 1:01 In Stats.js, we'll import the consumer using a named 1:05 import with import consumer from ./context. 1:10 Then in the function's return statement, 1:17 we'll use the Consumer component by adding opening and closing Consumer tags. 1:19 To render anything inside the consumer, 1:26 you use a pattern in React called a Render Prop. 1:28 Render Prop refers to a method for 1:31 sharing code between React components using a prop whose value is a function. 1:33 A component is provided a prop which takes a function that returns a React element. 1:38 You can learn a whole lot more about Render Props in the resources listed in 1:43 the teacher notes. 1:46 This pattern is also called function as a child. 1:47 Because instead of passing a prop, you're also able to write a function inside 1:50 the opening and closing Consumer tags. 1:54 The function returns the part of the UI you want to render. 1:56 So we'll use a function that returns the stats UI inside the Consumer. 1:59 This function is required and needs to be placed inside a JSX expression. 2:04 So let's add a set of curly braces inside the Consumer tags, 2:09 then the function that will render something based on the context. 2:12 The function takes the current context value as a parameter, and returns JSX. 2:16 This parameter is commonly named value or context, I'll name it context. 2:22 The context parameter passed to the function will be equal to the value prop 2:28 of the provider. 2:32 In other words, the data we pass into the provider's value prop 2:34 is made available here via the context parameter. 2:38 So the consumer is now subscribed to any context changes. 2:42 Now we're able to access the player's data directly from within the stats component. 2:46 In the body of the function, I'll add the return keyword in a set of parentheses 2:51 to wrap the JSX, then move the entire stats table inside the return statement. 2:56 Next, we need to move the total players and total points variables inside 3:05 the consumer, just above the child function's return statement. 3:10 That way, we can access context. 3:14 Then, replace props.players.length with context.length and 3:20 props.players.reduce with context.reduce. 3:26 And since we're no longer passing the player state to the Stats 3:31 component as props, we can delete the props parameter. 3:36 As well as the entire propTypes object below the function and 3:40 the PropTypes import statement up top. 3:44 In Header.js, we can delete the players prop passed to the Stats component, 3:48 because it no longer needs it. 3:54 And remove the object and players variable in the Header function's parameters, 3:57 as well as the propTypes object below the function, and the PropTypes import. 4:02 Over in app.js, the player state no longer needs to make it's way through the Header. 4:09 So we can also remove the player's prop past to the Header component. 4:15 Our Header component now looks much cleaner and has less responsibilities. 4:20 It's just a stateless component that renders the Stats title and Stopwatch. 4:25 The Stats component displays all the scoreboard stats just like before. 4:30 But instead of props, 4:35 it's getting the player's data from the provider via the consumer. 4:36 So any time there's a change in the player's state, 4:41 the consumer get the data it needs to update the UI from the provider. 4:45 All right, now that you've learned how to use a consumer and access context 4:50 set by the provider, why don't you use a consumer inside the player list component. 4:54 The consumer here needs to access the player state just like we did with 5:00 the stats component. 5:04 And it should provide that data to the map function returning each player and state. 5:05 I'll show you my solution in the next video. 5:10 You may have noticed something you haven't seen yet in React. 5:13 The React.Fragment tags inside the return statement. 5:16 A React.Fragment lets you group a list of sibling elements or 5:19 components without having to add an unnecessary reaper element. 5:23 It doesn't render anything out to the DOM so 5:27 I'm just using it here to contain the list of player components. 5:29 You can read more about React.Fragment in the teachers notes. 5:33
You need to sign up for Treehouse in order to download course files.Sign up