1 00:00:06,540 --> 00:00:08,910 - In this lesson, we're going to take a detailed look 2 00:00:08,910 --> 00:00:12,330 at how to test React applications using Jest. 3 00:00:12,330 --> 00:00:14,940 We're going to look at two different testing libraries 4 00:00:14,940 --> 00:00:17,010 and there's a library called Enzyme. 5 00:00:17,010 --> 00:00:19,890 Enzyme allows you to look inside a component 6 00:00:19,890 --> 00:00:22,440 and check its internal details. 7 00:00:22,440 --> 00:00:25,155 So for example, you can look at the properties, 8 00:00:25,155 --> 00:00:27,150 or the parameters, if you like, 9 00:00:27,150 --> 00:00:29,070 that were passed into a component, 10 00:00:29,070 --> 00:00:34,070 the state the data that it maintains across rendering, 11 00:00:34,605 --> 00:00:36,840 like a counter, 12 00:00:36,840 --> 00:00:38,760 something called effect hooks, 13 00:00:38,760 --> 00:00:41,970 an effect hook is a react mechanism. 14 00:00:41,970 --> 00:00:46,290 It's kind of like a way of invoking another function 15 00:00:46,290 --> 00:00:48,660 after every time the component's rendered. 16 00:00:48,660 --> 00:00:50,550 So every time the component's rendered, 17 00:00:50,550 --> 00:00:52,680 you can say call this other function 18 00:00:52,680 --> 00:00:54,410 to do some additional work, 19 00:00:54,410 --> 00:00:56,700 maybe to update data in local storage 20 00:00:56,700 --> 00:00:57,990 or something like that. 21 00:00:57,990 --> 00:01:00,510 So anyway, with Enzyme, you have full access 22 00:01:00,510 --> 00:01:03,300 to the internal details of the component, 23 00:01:03,300 --> 00:01:05,640 and you can do white box testing. 24 00:01:05,640 --> 00:01:08,340 There's another library called React Testing Library, 25 00:01:08,340 --> 00:01:10,860 which looks at the component from the outside. 26 00:01:10,860 --> 00:01:14,580 So, it tests the component's overall effect. 27 00:01:14,580 --> 00:01:17,670 What does it look like to the user's perspective? 28 00:01:17,670 --> 00:01:20,970 So this is more like black box testing from the outside. 29 00:01:20,970 --> 00:01:22,800 So both of these have a role to play. 30 00:01:22,800 --> 00:01:25,110 This is a bit more like unit testing, 31 00:01:25,110 --> 00:01:28,020 and this is a bit more like kind of user acceptance testing. 32 00:01:28,020 --> 00:01:31,503 Does it look right from what the user is going to perceive? 33 00:01:32,700 --> 00:01:34,950 So React Testing Library doesn't have access 34 00:01:34,950 --> 00:01:36,750 to the internals of the component, 35 00:01:36,750 --> 00:01:38,310 but it can see what it looks like 36 00:01:38,310 --> 00:01:41,010 after it's been rendered from the user's perspective. 37 00:01:41,010 --> 00:01:42,930 Both of these different testing libraries 38 00:01:42,930 --> 00:01:46,920 have an important role to play when you test and react. 39 00:01:46,920 --> 00:01:49,410 So what we're going to do, for the sake of consistency, 40 00:01:49,410 --> 00:01:51,570 we have quite a lot to cover in this lesson, 41 00:01:51,570 --> 00:01:52,590 so what I've done is I've written 42 00:01:52,590 --> 00:01:54,690 a single sample application, 43 00:01:54,690 --> 00:01:56,100 and it's gonna be the same application 44 00:01:56,100 --> 00:01:59,340 that we use throughout the lesson for consistency. 45 00:01:59,340 --> 00:02:01,830 So before we look at how to test it, 46 00:02:01,830 --> 00:02:03,540 I thought it'd be a good idea to actually explain 47 00:02:03,540 --> 00:02:06,210 what the application does so you can understand it, 48 00:02:06,210 --> 00:02:08,820 and then we'll have a look at testing it later. 49 00:02:08,820 --> 00:02:11,040 So if you go into the demo folder, 50 00:02:11,040 --> 00:02:12,390 so we are in lesson 10 now, 51 00:02:12,390 --> 00:02:16,920 if you go into sample application in there, 52 00:02:16,920 --> 00:02:18,990 I've got a demo app tool. 53 00:02:18,990 --> 00:02:23,010 I generated this using the Create React App tool. 54 00:02:23,010 --> 00:02:26,380 And this demo application is a reasonably interesting 55 00:02:27,240 --> 00:02:29,583 React application with several components, 56 00:02:31,931 --> 00:02:34,500 and a use of interface that is sufficient for us 57 00:02:34,500 --> 00:02:39,420 to understand what's involved in a realistic scenario. 58 00:02:39,420 --> 00:02:44,420 So I've opened that project in the code editor. 59 00:02:44,670 --> 00:02:47,910 Okay, so I'm gonna give you a quick overview 60 00:02:47,910 --> 00:02:52,260 of what the code looks like in the next few minutes. 61 00:02:52,260 --> 00:02:54,180 Before we do that, I thought it'd be a good idea 62 00:02:54,180 --> 00:02:56,490 to actually see what the application looks like 63 00:02:56,490 --> 00:02:58,170 from the user's point of view. 64 00:02:58,170 --> 00:03:00,570 So, open up a command window, 65 00:03:00,570 --> 00:03:02,280 and go into the demo app folder, 66 00:03:02,280 --> 00:03:04,350 sample application demo app, 67 00:03:04,350 --> 00:03:07,950 and then run NPM install, or yarn install, 68 00:03:07,950 --> 00:03:09,900 to install the packages, 69 00:03:09,900 --> 00:03:13,410 and then do an NPM start to start the application. 70 00:03:13,410 --> 00:03:16,140 Okay, and it'll compile the application 71 00:03:16,140 --> 00:03:18,750 from TypeScript into JavaScript. 72 00:03:18,750 --> 00:03:22,860 Babel will convert all of the JSX into pure Java, 73 00:03:22,860 --> 00:03:25,470 and then it'll open up a web browser. 74 00:03:25,470 --> 00:03:27,210 Sorry, it'll open up a web server 75 00:03:27,210 --> 00:03:29,370 and display it in a web page. 76 00:03:29,370 --> 00:03:30,600 So when you do that, 77 00:03:30,600 --> 00:03:33,000 eventually, it'll take about five minutes to do all of that. 78 00:03:33,000 --> 00:03:34,470 I've done it already. 79 00:03:34,470 --> 00:03:35,730 This is what it's gonna look like 80 00:03:35,730 --> 00:03:37,350 when you run the application. 81 00:03:37,350 --> 00:03:38,430 So here we go, 82 00:03:38,430 --> 00:03:41,760 it's rich enough for us to have something tangible 83 00:03:41,760 --> 00:03:43,280 to get our teeth into. 84 00:03:43,280 --> 00:03:45,870 What I've got is some simple data, 85 00:03:45,870 --> 00:03:47,340 as I'll show you in a moment. 86 00:03:47,340 --> 00:03:49,470 I've defined a class called product, 87 00:03:49,470 --> 00:03:53,100 and each product has a description and a price, 88 00:03:53,100 --> 00:03:54,900 and the number of units in stock, 89 00:03:54,900 --> 00:03:56,670 imagine it was like an online retailer. 90 00:03:56,670 --> 00:03:58,950 This shop sells skis. 91 00:03:58,950 --> 00:04:02,340 A pair of skis cost 1000 pounds, it's quite expensive, 92 00:04:02,340 --> 00:04:05,657 and there are five skis in stock, or five pairs of skis. 93 00:04:05,657 --> 00:04:08,342 The shop also sells ski boots, 94 00:04:08,342 --> 00:04:11,040 they come in at 250 pounds a pair, 95 00:04:11,040 --> 00:04:12,660 and there were four pairs in stock, 96 00:04:12,660 --> 00:04:14,940 and ski goggles is the third item. 97 00:04:14,940 --> 00:04:18,720 So my shop doesn't sell many items, but it's getting there. 98 00:04:18,720 --> 00:04:21,600 And then at the bottom, it calculates the total value 99 00:04:21,600 --> 00:04:25,080 of the shop's stock. 100 00:04:25,080 --> 00:04:28,680 So if carbon skis cost 1000 pound each, 101 00:04:28,680 --> 00:04:31,203 and there were five of them, that's 5,000 pound. 102 00:04:32,490 --> 00:04:34,200 That's another 1000 pound, 103 00:04:34,200 --> 00:04:35,910 so that's 6,000 pound. 104 00:04:35,910 --> 00:04:37,170 That's another 1000 pound, 105 00:04:37,170 --> 00:04:39,300 7,000 pound is the total value, 106 00:04:39,300 --> 00:04:41,250 which is calculated based on 107 00:04:41,250 --> 00:04:43,560 multiplying the price by the stock, 108 00:04:43,560 --> 00:04:45,060 and then just adding them all up. 109 00:04:45,060 --> 00:04:46,361 Okay? So that makes sense? 110 00:04:46,361 --> 00:04:48,480 So let's start looking at the code 111 00:04:48,480 --> 00:04:50,190 to see how it's implemented. 112 00:04:50,190 --> 00:04:51,720 Once we understand the code, 113 00:04:51,720 --> 00:04:55,530 then we can see how to test it in the rest of the lesson. 114 00:04:55,530 --> 00:04:58,782 So first of all, all of this code is in the source folder. 115 00:04:58,782 --> 00:05:03,690 So in the source folder I have a class called product, 116 00:05:03,690 --> 00:05:06,900 okay, product item, there we go. 117 00:05:06,900 --> 00:05:09,510 It's a regular TypeScript class. 118 00:05:09,510 --> 00:05:11,280 It has a constructor. 119 00:05:11,280 --> 00:05:14,578 You pass in the description, like goggles, 120 00:05:14,578 --> 00:05:17,550 the unit price, and how many in stock. 121 00:05:17,550 --> 00:05:20,460 And if you haven't seen this syntax before in TypeScript, 122 00:05:20,460 --> 00:05:22,470 when you have a constructor, 123 00:05:22,470 --> 00:05:25,620 and you annotate the parameters with public, 124 00:05:25,620 --> 00:05:29,070 then these parameters actually become fields in the class. 125 00:05:29,070 --> 00:05:30,720 It's a shorthand syntax, 126 00:05:30,720 --> 00:05:34,380 for declaring fields and for copying parameters into them. 127 00:05:34,380 --> 00:05:37,018 So a product will have a description field, 128 00:05:37,018 --> 00:05:39,990 which is public, initialized by that parameter, 129 00:05:39,990 --> 00:05:43,380 and a price data number and an in stock data number. 130 00:05:43,380 --> 00:05:45,420 Those values are actually stored implicitly, 131 00:05:45,420 --> 00:05:48,060 and copies those values into the object. 132 00:05:48,060 --> 00:05:50,070 Okay, so that's my product item class. 133 00:05:50,070 --> 00:05:50,903 All it does, 134 00:05:50,903 --> 00:05:52,710 it has nothing to do with user interface, 135 00:05:52,710 --> 00:05:56,070 it just stores the data for a product item. 136 00:05:56,070 --> 00:05:59,220 Okay, a simple class to hold product data. 137 00:05:59,220 --> 00:06:02,790 Nothing to do with React, just a simple data class. 138 00:06:02,790 --> 00:06:05,610 Right, so in a React application, 139 00:06:05,610 --> 00:06:08,670 you've normally got a top level component called app, 140 00:06:08,670 --> 00:06:10,980 the root component that gets things going. 141 00:06:10,980 --> 00:06:12,630 So let's have a look at that. 142 00:06:12,630 --> 00:06:16,950 First of all, from the very top we have the index TSX file, 143 00:06:16,950 --> 00:06:19,950 which renders the application component. 144 00:06:19,950 --> 00:06:23,760 The application component is defined in app TSX. 145 00:06:23,760 --> 00:06:25,920 Let's have a look at that. 146 00:06:25,920 --> 00:06:29,250 So what I've done here is I've set up some sample data. 147 00:06:29,250 --> 00:06:31,800 I've set up an array of product item. 148 00:06:31,800 --> 00:06:35,130 I've created three product items as we just saw. 149 00:06:35,130 --> 00:06:39,270 And then what I do is in order to render the application, 150 00:06:39,270 --> 00:06:40,920 typically the application component 151 00:06:40,920 --> 00:06:42,420 doesn't actually do much, 152 00:06:42,420 --> 00:06:46,230 it just kicks off some other component to do the rendering. 153 00:06:46,230 --> 00:06:49,363 So just like in a Java application, or C++, or C#, 154 00:06:50,850 --> 00:06:52,380 the main function doesn't do much, 155 00:06:52,380 --> 00:06:55,140 it just kicks off some other function to do the work, 156 00:06:55,140 --> 00:06:56,400 and that's what I've done here. 157 00:06:56,400 --> 00:06:57,990 All the application component does, 158 00:06:57,990 --> 00:07:01,710 is to render another component called product list. 159 00:07:01,710 --> 00:07:04,650 And the product list component receives a property 160 00:07:04,650 --> 00:07:05,880 called products, 161 00:07:05,880 --> 00:07:09,240 and that will be the array of products I've just seen. 162 00:07:09,240 --> 00:07:10,770 So that array of products 163 00:07:10,770 --> 00:07:12,900 will be passed in as a property 164 00:07:12,900 --> 00:07:14,430 into the product list component. 165 00:07:14,430 --> 00:07:16,500 Basically, the application component says 166 00:07:16,500 --> 00:07:18,630 render that list of products. 167 00:07:18,630 --> 00:07:22,380 This component knows how to render a product list. 168 00:07:22,380 --> 00:07:23,880 So the product list component, 169 00:07:23,880 --> 00:07:25,710 it receives a list of products, 170 00:07:25,710 --> 00:07:28,770 and it displays them in that list that we saw. 171 00:07:28,770 --> 00:07:30,150 Remember what we were looking at? 172 00:07:30,150 --> 00:07:31,890 Basically the product list component 173 00:07:31,890 --> 00:07:35,280 is going to display this list of products. 174 00:07:35,280 --> 00:07:37,860 So let's have a look at the product list component next, 175 00:07:37,860 --> 00:07:39,603 and it is here. 176 00:07:40,830 --> 00:07:43,140 So the product list component, 177 00:07:43,140 --> 00:07:46,770 so TypeScripts and backs starts to get a bit ugly. 178 00:07:46,770 --> 00:07:49,070 So I'll just run through what's going on here. 179 00:07:49,950 --> 00:07:52,110 Ultimately, if you remember, 180 00:07:52,110 --> 00:07:54,813 components just receive a single object. 181 00:07:55,710 --> 00:07:58,980 Okay, but typically you'll want to gain access 182 00:07:58,980 --> 00:08:01,740 to one of the properties inside the object, 183 00:08:01,740 --> 00:08:03,240 or maybe multiple properties. 184 00:08:03,240 --> 00:08:05,237 So you could say if that object had a property 185 00:08:05,237 --> 00:08:08,490 called A, B, and C and you want to access them, 186 00:08:08,490 --> 00:08:10,830 you can use destructuring to say something like this, 187 00:08:10,830 --> 00:08:14,010 A, comma, B, comma, C, 188 00:08:14,010 --> 00:08:18,090 okay, take the incoming object and extract those properties. 189 00:08:18,090 --> 00:08:19,950 The reason that type script is complaining, 190 00:08:19,950 --> 00:08:23,070 is because it needs to know what type are those properties? 191 00:08:23,070 --> 00:08:24,968 So you have to say, oh, I can't believe it, 192 00:08:24,968 --> 00:08:27,510 I've gotta tell you the types of each property? 193 00:08:27,510 --> 00:08:29,943 Okay, well A is a number, 194 00:08:31,080 --> 00:08:32,763 and B is a string, 195 00:08:33,720 --> 00:08:35,820 and C is a number. 196 00:08:35,820 --> 00:08:38,520 So we have that kind of syntax in type script. 197 00:08:38,520 --> 00:08:42,120 An object gets destructured, extract those properties, 198 00:08:42,120 --> 00:08:45,480 TypeScript needs to know what those property types are. 199 00:08:45,480 --> 00:08:47,160 This is a hypothetical example, 200 00:08:47,160 --> 00:08:49,050 but that explains the syntax. 201 00:08:49,050 --> 00:08:52,072 So if I revert to what we had originally, 202 00:08:52,072 --> 00:08:54,420 the object that was passed in 203 00:08:54,420 --> 00:08:56,550 had a property called products, 204 00:08:56,550 --> 00:08:59,670 and that products property was an array of product item. 205 00:08:59,670 --> 00:09:02,340 Remember from my application component, 206 00:09:02,340 --> 00:09:04,560 I passed in a products property, 207 00:09:04,560 --> 00:09:06,993 it was an array of products. 208 00:09:08,700 --> 00:09:10,653 Okay, so the products, 209 00:09:12,420 --> 00:09:16,110 variable, is an array of product item. 210 00:09:16,110 --> 00:09:19,200 It's an array, if the length of the array is zero, 211 00:09:19,200 --> 00:09:20,490 then it displays this. 212 00:09:20,490 --> 00:09:22,770 It'll just say, instead of displaying a list, 213 00:09:22,770 --> 00:09:24,930 it'll just say no products in stock. 214 00:09:24,930 --> 00:09:26,730 Well, we have three products, 215 00:09:26,730 --> 00:09:29,160 so it displays a heading. 216 00:09:29,160 --> 00:09:32,550 Remember when you're in JSX or TSX, you have 217 00:09:32,550 --> 00:09:36,990 to enclose JavaScript inside curly brackets to evaluate it. 218 00:09:36,990 --> 00:09:39,900 So there are three products in stock. 219 00:09:39,900 --> 00:09:42,510 There are three products in stock, each product, 220 00:09:42,510 --> 00:09:45,450 how do you want to display each product? 221 00:09:45,450 --> 00:09:48,270 Well, I'm gonna defer that to another component. 222 00:09:48,270 --> 00:09:49,860 I'm gonna actually do this. 223 00:09:49,860 --> 00:09:52,803 I'm gonna say for each, loop through that array, 224 00:09:53,820 --> 00:09:55,350 okay, so each time round this, 225 00:09:55,350 --> 00:09:58,170 the map function is gonna call this Lambda. 226 00:09:58,170 --> 00:10:00,720 This Lambda will be involved with the first product, 227 00:10:00,720 --> 00:10:03,450 then the second product, then the third product. 228 00:10:03,450 --> 00:10:06,420 Okay, so P, will be a product item. 229 00:10:06,420 --> 00:10:10,320 And what we do, is we convert it into a product component. 230 00:10:10,320 --> 00:10:12,630 This is really common in React. 231 00:10:12,630 --> 00:10:14,680 You have an object, or you have an array, 232 00:10:15,630 --> 00:10:19,110 and you iterate through the array to get each object, 233 00:10:19,110 --> 00:10:21,900 and then you convert it into something that can be displayed 234 00:10:21,900 --> 00:10:25,140 for each product, render it like this. 235 00:10:25,140 --> 00:10:27,570 Okay, each product will be rendered 236 00:10:27,570 --> 00:10:29,493 by the product component. 237 00:10:30,750 --> 00:10:32,580 Whenever you have a list of things, 238 00:10:32,580 --> 00:10:34,920 React wants there to be like a key, 239 00:10:34,920 --> 00:10:38,460 just to certain element zero, element one, element two, 240 00:10:38,460 --> 00:10:40,560 so that's just a react mechanism. 241 00:10:40,560 --> 00:10:42,840 And then here the spread operator, 242 00:10:42,840 --> 00:10:45,060 if you remember what the spread operator does, 243 00:10:45,060 --> 00:10:49,260 it basically unpacks the object into its constituent parts. 244 00:10:49,260 --> 00:10:54,260 So if the product item had a property called description, 245 00:10:56,790 --> 00:11:00,180 then it'll be, this, will basically say, 246 00:11:00,180 --> 00:11:04,320 okay then, let's pass in a description property, 247 00:11:04,320 --> 00:11:06,903 which will be the product's description. 248 00:11:08,430 --> 00:11:10,653 Okay, and it does it for the next property, 249 00:11:11,760 --> 00:11:13,260 so the next property was- 250 00:11:13,260 --> 00:11:15,903 what was the next property in my product item? 251 00:11:16,830 --> 00:11:18,300 Price. 252 00:11:18,300 --> 00:11:21,720 Okay, so it'll then say let's pass in a price property, 253 00:11:21,720 --> 00:11:24,213 which is the value of the product's price. 254 00:11:25,290 --> 00:11:26,700 Because we are in TypeScript, 255 00:11:26,700 --> 00:11:29,280 it knows that each element in the array is a product item, 256 00:11:29,280 --> 00:11:31,320 so we get Intellisense, cool isn't it? 257 00:11:31,320 --> 00:11:33,210 One of the reasons for using TypeScript. 258 00:11:33,210 --> 00:11:37,290 And so on for the units in stock, 259 00:11:37,290 --> 00:11:40,050 units in stock is going to be equal 260 00:11:40,050 --> 00:11:43,563 to the value of the product's unit in stock. 261 00:11:45,930 --> 00:11:48,630 Okay, so at this point I might be tempted 262 00:11:48,630 --> 00:11:51,720 to kind of split it onto separate lines, 263 00:11:51,720 --> 00:11:54,180 because it's quite difficult. 264 00:11:54,180 --> 00:11:56,670 In fact, I think I'll indent that a bit more as well. 265 00:11:56,670 --> 00:11:58,560 You want your code to be readable, 266 00:11:58,560 --> 00:12:00,480 because you're gonna have to maintain this, 267 00:12:00,480 --> 00:12:02,583 for years going forward, potentially. 268 00:12:03,930 --> 00:12:04,763 Okay, so there we go. 269 00:12:04,763 --> 00:12:06,690 I might put that there as well. 270 00:12:06,690 --> 00:12:11,460 So basically for each product, render the product component, 271 00:12:11,460 --> 00:12:12,900 and pass in a property called 272 00:12:12,900 --> 00:12:15,933 description, price, and in stock. 273 00:12:17,707 --> 00:12:21,070 That was equivalent to just doing 274 00:12:22,140 --> 00:12:23,973 dot, dot, dot, P. 275 00:12:25,909 --> 00:12:28,560 Okay, that is equivalent to doing that. 276 00:12:28,560 --> 00:12:31,260 It'll basically automatically expand each of its properties 277 00:12:31,260 --> 00:12:33,963 into a separate parameter, like that. 278 00:12:37,586 --> 00:12:38,700 Okay, so I can just shorten it 279 00:12:38,700 --> 00:12:40,050 back to what we had before then, 280 00:12:40,050 --> 00:12:43,710 in that case, that might be easier on the eye- 281 00:12:43,710 --> 00:12:44,543 like that. 282 00:12:44,543 --> 00:12:46,410 So what does the product component do? 283 00:12:46,410 --> 00:12:50,220 Well, the product component renders one product, 284 00:12:50,220 --> 00:12:52,380 and it renders it like this, 285 00:12:52,380 --> 00:12:55,140 all it knows about is how to render one product. 286 00:12:55,140 --> 00:12:56,970 So let's have a look at the product component, 287 00:12:56,970 --> 00:12:58,200 we're almost done here now. 288 00:12:58,200 --> 00:13:00,540 The product component, it receives, 289 00:13:00,540 --> 00:13:04,260 basically it receives an object that has a price property, 290 00:13:04,260 --> 00:13:07,020 a description property, and an in stock property. 291 00:13:07,020 --> 00:13:09,900 In other words, it receives a product item object, 292 00:13:09,900 --> 00:13:13,719 and it says, okay display it with a heading, 293 00:13:13,719 --> 00:13:18,719 and a price, and an in stock, and it has a CSS class. 294 00:13:18,930 --> 00:13:21,870 Remember if you wanna set a CSS class in React, 295 00:13:21,870 --> 00:13:24,120 you can't say class, 296 00:13:24,120 --> 00:13:27,060 because that's a keyword in JavaScript. 297 00:13:27,060 --> 00:13:29,520 In Reactive you've gotta say class name. 298 00:13:29,520 --> 00:13:30,600 So there's a class, 299 00:13:30,600 --> 00:13:33,870 a CSS class, somewhere called product item. 300 00:13:33,870 --> 00:13:35,310 What I would normally do at this point, 301 00:13:35,310 --> 00:13:39,000 I'd say, well where is that CSS class defined? 302 00:13:39,000 --> 00:13:43,350 Is there some kind of CSS import here? 303 00:13:43,350 --> 00:13:44,250 No. 304 00:13:44,250 --> 00:13:48,150 So, it's not as if product has its own CSS file, 305 00:13:48,150 --> 00:13:50,520 so it must come in somewhere else. 306 00:13:50,520 --> 00:13:54,660 So maybe there's an index dot CSS that defines the class, 307 00:13:54,660 --> 00:13:55,920 and there it is. 308 00:13:55,920 --> 00:14:00,920 Okay, so it displays each product item in a blue background, 309 00:14:00,960 --> 00:14:03,993 in a white font, in a nice large font size. 310 00:14:05,940 --> 00:14:09,480 Okay, so that was one product being displayed. 311 00:14:09,480 --> 00:14:11,640 If I go back to product list, 312 00:14:11,640 --> 00:14:15,000 it will iterate through all my products 313 00:14:15,000 --> 00:14:16,830 and display each product. 314 00:14:16,830 --> 00:14:21,120 And then at the bottom, it displays the total value. 315 00:14:21,120 --> 00:14:23,430 So I've actually put that into a separate component. 316 00:14:23,430 --> 00:14:24,720 You do this a lot in React. 317 00:14:24,720 --> 00:14:28,380 Whenever you've got a bit of HTML that's cohesive, 318 00:14:28,380 --> 00:14:31,020 consider putting that into a separate component 319 00:14:31,020 --> 00:14:32,550 to encapsulate it. 320 00:14:32,550 --> 00:14:35,352 So I have another component called total value, 321 00:14:35,352 --> 00:14:37,080 because it's quite complicated, 322 00:14:37,080 --> 00:14:40,942 you have to calculate the total value of all the products. 323 00:14:40,942 --> 00:14:43,350 That's not a trivial thing. 324 00:14:43,350 --> 00:14:45,420 So I've put it into a separate component. 325 00:14:45,420 --> 00:14:47,940 So I rendered the component here. 326 00:14:47,940 --> 00:14:50,130 If you think about it, to calculate the total value, 327 00:14:50,130 --> 00:14:52,230 you've gotta give it all the products, 328 00:14:52,230 --> 00:14:54,510 so it can multiply and add. 329 00:14:54,510 --> 00:14:58,350 So I pass in the product list into total value, 330 00:14:58,350 --> 00:14:59,910 and here it is. 331 00:14:59,910 --> 00:15:04,910 It receives an object of products, a product item array, 332 00:15:06,450 --> 00:15:08,613 which contains an array of product item. 333 00:15:11,893 --> 00:15:12,726 For each product item, 334 00:15:12,726 --> 00:15:15,960 what I wanna do is to calculate the line cost, if you like. 335 00:15:15,960 --> 00:15:18,330 I wanna multiply, for each product, 336 00:15:18,330 --> 00:15:21,120 the price by the number in stock. 337 00:15:21,120 --> 00:15:22,720 And that would give me the value 338 00:15:23,700 --> 00:15:26,790 of all of my skis that that I own. 339 00:15:26,790 --> 00:15:28,260 Okay, so that's what I do. 340 00:15:28,260 --> 00:15:29,613 I say for each product, 341 00:15:30,510 --> 00:15:33,960 take the product, multiply its price and its stock. 342 00:15:33,960 --> 00:15:37,620 Okay, and then, so that'll give me the line cost, 343 00:15:37,620 --> 00:15:40,230 and then what I do is I basically add them all together. 344 00:15:40,230 --> 00:15:44,460 There's a very handy function in JavaScript called reduce. 345 00:15:44,460 --> 00:15:46,950 And what you do is you give it two parameters, 346 00:15:46,950 --> 00:15:48,450 and it's like an accumulator. 347 00:15:48,450 --> 00:15:49,440 It takes two parameters 348 00:15:49,440 --> 00:15:51,780 and it reduces them into a single result. 349 00:15:51,780 --> 00:15:53,583 So what happens is it takes in, 350 00:15:55,080 --> 00:15:58,653 T, is the current total so far, 351 00:15:59,550 --> 00:16:04,080 and C, is the next value, if you like. 352 00:16:04,080 --> 00:16:06,990 So first time this function's gonna be called three times, 353 00:16:06,990 --> 00:16:09,540 once for the first product, then the next product, 354 00:16:09,540 --> 00:16:10,710 then the next product. 355 00:16:10,710 --> 00:16:12,707 First time it calls this function, 356 00:16:12,707 --> 00:16:15,000 it'll pass in zero, 357 00:16:15,000 --> 00:16:18,150 as the initial value for the total to bootstrap it. 358 00:16:18,150 --> 00:16:20,010 And then it'll pass in 359 00:16:20,010 --> 00:16:23,970 the price multiplied by the stock for the first product, 360 00:16:23,970 --> 00:16:25,350 the cost of the first product. 361 00:16:25,350 --> 00:16:28,620 It adds them together, and that running total 362 00:16:28,620 --> 00:16:31,170 then gets passed in to the next invocation. 363 00:16:31,170 --> 00:16:32,910 So every time you call this function, 364 00:16:32,910 --> 00:16:34,560 it'll calculate the next total, 365 00:16:34,560 --> 00:16:36,870 and pass it in to the next function call 366 00:16:36,870 --> 00:16:38,220 to accumulate the values. 367 00:16:38,220 --> 00:16:41,100 Eventually it'll give you back the total value, 368 00:16:41,100 --> 00:16:44,580 which I display with the CSS class of orange, 369 00:16:44,580 --> 00:16:46,983 I display the total value on the webpage.