1 00:00:00,390 --> 00:00:04,120 It may seem like we did a lot of code refactoring earlier to little benefit. 2 00:00:04,120 --> 00:00:07,550 After all, our scoreboard still functions the same. 3 00:00:07,550 --> 00:00:12,230 The problem with our old structure is that the score data was kept locally 4 00:00:12,230 --> 00:00:14,100 in the counter component state. 5 00:00:14,100 --> 00:00:17,590 So what if we needed to pass the total score of all players to the header, 6 00:00:17,590 --> 00:00:18,620 for example? 7 00:00:18,620 --> 00:00:21,857 There was no way to use the score data anywhere else in the app, 8 00:00:21,857 --> 00:00:24,297 because it was trapped inside of the counter. 9 00:00:24,297 --> 00:00:28,231 So now that our score state's been lifted up to the top of the application, 10 00:00:28,231 --> 00:00:30,172 we can pass it down to any component. 11 00:00:30,172 --> 00:00:35,128 In this video, we'll build a statistics component that displays the total number 12 00:00:35,128 --> 00:00:39,253 of players on the scoreboard, as well as the total number of points. 13 00:00:39,253 --> 00:00:43,804 We'll use the player state to determine the number of players in the state and 14 00:00:43,804 --> 00:00:47,179 the player dot score state to calculate the total score. 15 00:00:47,179 --> 00:00:52,583 First we'll create a component named stats in the component folder. 16 00:00:52,583 --> 00:00:56,516 Create a new file named Stats.js. 17 00:00:56,516 --> 00:01:00,795 This is going to be a stateless functional component, so 18 00:01:00,795 --> 00:01:06,676 let's import React at the top of the file with import React from 'react';, 19 00:01:06,676 --> 00:01:11,953 and write an error function named Stats that takes a props parameter. 20 00:01:14,280 --> 00:01:18,145 We'll display the stats using a good old HTML table. 21 00:01:18,145 --> 00:01:23,530 So let's add the return keyword and parentheses to wrap our JSX. 22 00:01:23,530 --> 00:01:27,405 And let's not forget to export our stats component 23 00:01:27,405 --> 00:01:31,379 at the bottom of the file with export default Stats. 24 00:01:32,780 --> 00:01:35,970 To create the table that will display our stats, 25 00:01:35,970 --> 00:01:39,250 I'll quickly paste an HTML snippet of a table element. 26 00:01:39,250 --> 00:01:42,800 You can copy this exact code from the teacher's notes with this video. 27 00:01:42,800 --> 00:01:46,140 The table element has a class of stats. 28 00:01:46,140 --> 00:01:49,780 The first row displays the total number of players, and 29 00:01:49,780 --> 00:01:52,020 the second row, the total points. 30 00:01:52,020 --> 00:01:55,072 Both are hard coded as 0 for now. 31 00:01:55,072 --> 00:02:02,699 So now let's import our new stats component into the header component, 32 00:02:02,699 --> 00:02:09,215 and header.js we'll add import stats from './Stats'. 33 00:02:09,215 --> 00:02:14,791 And we'll display the stats component on the left side of the title by 34 00:02:14,791 --> 00:02:21,732 including the Stats tag as the first child of the header element, just above the h1. 35 00:02:21,732 --> 00:02:26,176 And since the total players number is now inside the stats component, 36 00:02:26,176 --> 00:02:30,781 lets delete the span element we were using to display the total players. 37 00:02:34,369 --> 00:02:38,056 Next, we need to get the data from the player state down 38 00:02:38,056 --> 00:02:42,963 into the Stats component to calculate the total score and player count. 39 00:02:42,963 --> 00:02:45,236 You already know how to do that with props. 40 00:02:45,236 --> 00:02:50,136 The header contains the Stats component so first it would need to 41 00:02:50,136 --> 00:02:54,683 be passed the player state in order to pass it down to Stats. 42 00:02:54,683 --> 00:03:00,273 So in the app component, let's change the total players 43 00:03:00,273 --> 00:03:05,631 prop being passed to the header component to players, 44 00:03:05,631 --> 00:03:14,265 then we'll pass the entire player state to the component with this.state.players. 45 00:03:14,265 --> 00:03:19,911 Now we need to pass the players to the stats component in Header.js. 46 00:03:19,911 --> 00:03:25,215 I'll give the stats tag the same prop name, players. 47 00:03:25,215 --> 00:03:30,358 And pass it to players and state with props.players. 48 00:03:30,358 --> 00:03:35,506 All right, our player data now flows from the app component, 49 00:03:35,506 --> 00:03:40,268 through the header, and down into the stats component. 50 00:03:40,268 --> 00:03:42,686 So now in the stats component, 51 00:03:42,686 --> 00:03:46,784 we can calculate the stats using plain JavaScript. 52 00:03:46,784 --> 00:03:51,676 We already know how to get the total number of players in state with the length 53 00:03:51,676 --> 00:03:52,446 property. 54 00:03:52,446 --> 00:03:57,576 So above the return statement I'll create a variable 55 00:03:57,576 --> 00:04:03,505 named totalPlayers and assign it props.players.length. 56 00:04:03,505 --> 00:04:10,982 Inside the table we can include the totalPlayers variable in a JSX expression. 57 00:04:13,751 --> 00:04:19,460 Over in the browser, we see that it's rendering the number 4, perfect. 58 00:04:19,460 --> 00:04:24,160 Finally, calculating the total points is a little more complex, to get the total 59 00:04:24,160 --> 00:04:29,090 number of points we'll need to iterate over each player and state. 60 00:04:29,090 --> 00:04:33,860 We'll get each player's score and total up the scores to produce our value. 61 00:04:33,860 --> 00:04:36,618 The best way to do this is with the Reduce method. 62 00:04:36,618 --> 00:04:41,159 Reduce is useful when you want to end up with a value than an array like a number. 63 00:04:41,159 --> 00:04:47,263 So let's create a new variable named totalPoints. 64 00:04:47,263 --> 00:04:52,372 We'll use the Reduce method on the players array that's passed in through props. 65 00:04:52,372 --> 00:04:59,824 So we'll assign the variable props.players.reduce. 66 00:04:59,824 --> 00:05:04,031 The reduce method takes a callback function that gets executed on 67 00:05:04,031 --> 00:05:06,270 each element in the array. 68 00:05:06,270 --> 00:05:10,109 So let's pass reduce an arrow function. 69 00:05:10,109 --> 00:05:12,860 And the callback takes two parameters. 70 00:05:12,860 --> 00:05:16,539 An accumulator, that adds up the return values, and 71 00:05:16,539 --> 00:05:19,823 the current item being processed in the array. 72 00:05:19,823 --> 00:05:27,439 For the accumulator, I want a total score and the current item will be a player. 73 00:05:27,439 --> 00:05:32,704 We can set the initial value of the accumulator as the second 74 00:05:32,704 --> 00:05:38,824 argument to the reduced method, so I'll initialize total to be 0. 75 00:05:38,824 --> 00:05:44,554 For each player being processed we'll add their score to the total accumulator. 76 00:05:44,554 --> 00:05:52,911 So inside the call back let's return total + player.score. 77 00:05:55,956 --> 00:06:00,197 The value of total get passed to each iteration 78 00:06:00,197 --> 00:06:03,901 to produce the final cumulative value. 79 00:06:03,901 --> 00:06:06,885 Now that we've calculated the Total Points, 80 00:06:06,885 --> 00:06:11,872 let's include the totalPoints variable in the table with a jsx expression. 81 00:06:14,121 --> 00:06:15,791 All right, let test our code. 82 00:06:15,791 --> 00:06:18,887 If I increase or decrease a players score, 83 00:06:18,887 --> 00:06:23,961 the stats table automatically updates with the latest data, great. 84 00:06:27,629 --> 00:06:31,225 You can learn more about the reduce method by watching the Treehouse videos posted 85 00:06:31,225 --> 00:06:33,060 in the teacher's notes with this video.