1.10 TeslaStats Component
Now we are going to build the TeslaStats component. Create the src/components/TeslaStats directory, create a TeslaStats.js file in it, and enter the following code:
import React from 'react';import PropTypes from 'react';import './TeslaStats.css';const TeslaStats = (props) => {const listItems = props.carstats.map((stat) => (<li key={stat.model}><div className={'tesla-stats-icon tesla-stats-icon--${stat.model.toLowerCase()}'}></div><p>{stat.miles}</p></li>));return (<div className="tesla-stats"><ul>{listItems}</ul></div>)};TeslaStats.propTypes = {carstats: PropTypes.array}export default TeslaStats;
TeslaStats is also a presentational component that receives state, and it takes a list of arrays containing model values by props and renders them.
First, let’s consider how to transform a list in JavaScript. The following code uses the map() function to take a numbers array and return a double value.
This code prints [2, 4, 6, 8, 10] to the console.
const numbers = [1, 2, 3, 4, 5];const doubled = numbers.map((number) => number * 2);console.log(doubled);
Converting an array to a list in React is almost identical. Here we use the JavaScript map function to iterate through the props.carstats array.
For each iteration, it returns a <li> element containing the model and a <li> element surrounding the <p> tag containing miles.
Finally, it returns the listItems array in the <ul> element.
1.10.1 TeslaStats Component Style
Next, create a TeslaStats.css file in the src/components/TeslaStats directory and type the following style. Since the code is long and omitted here, let’s check the source code
....tesla-stats {margin: -70px 0 30px;}.tesla-stats ul {text-align: center;}...
The task that this component performs is to iterate through the props.carstats array and bind a particular class to an element based on stat.model. You can then replace the background image to display the Tesla model.
1.10.2 Import TeslaStats component in TeslaBattery Container
Then add following import to use the TeslaStats component in TeslaBattery.js.
...import TeslaStats from '../components/TeslaStats/TeslaStats';...render() {const { config, carstats } = this.state;return (<form className="tesla-battery"><h1>Range Per Charge</h1><TeslaCar wheelsize={config.wheels}/><TeslaStats carstats={carstats}/><TeslaNotice /></form>)}...
We need to pass the carstats array to props, so let’s set the value using BatteryService we’ve already implemented.
1.10.3 CalculateStats and setState
Add import getModelData first.
After the component is mounted via componentDidMount(), it calls the statsUpdate() function. When calculateStats() function that receives carModels and the current state value as the input is executed, the object with the matching model and miles values is returned, and the return value is passed through the setState() and then state object is updated.
...import { getModelData } from '../services/BatteryService';...calculateStats = (models, value) => {const dataModels = getModelData();return models.map(model => {// ES6 Object destructuring Syntax,// takes out required values and create references to themconst { speed, temperature, climate, wheels } = value;const miles = dataModels[model][wheels][climate ? 'on' : 'off'].speed[speed][temperature];return {model,miles};});}statsUpdate() {const carModels = ['60', '60D', '75', '75D', '90D', 'P100D'];// Fetch model info from BatteryService and calculate then update statethis.setState({carstats: this.calculateStats(carModels, this.state.config)})}componentDidMount() {this.statsUpdate();}...
One caveat is that explicit binding in the TeslaBattery constructor function is required to access this in the class.
...this.calculateStats = this.calculateStats.bind(this);this.statsUpdate = this.statsUpdate.bind(this);...
1.10.4 Add Additional Style
Additional styling is required for a nice layout here.
First open the src/index.css file and delete all existing code and add the following:
@font-face {font-family: 'RobotoNormal';src: url('./assets/fonts/Roboto-Regular-webfont.eot');src: url('./assets/fonts/Roboto-Regular-webfont.eot?#iefix') format('embedded-opentype'),url('./assets/fonts/Roboto-Regular-webfont.woff') format('woff'),url('./assets/fonts/Roboto-Regular-webfont.ttf') format('truetype'),url('./assets/fonts/Roboto-Regular-webfont.svg#RobotoRegular') format('svg');font-weight: normal;font-style: normal;}*, *:before, *:after {box-sizing: border-box;margin: 0;padding: 0;font: 300 14px/1.4 'Helvetica Neue', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;}.cf:before,.cf:after {content: '';display: table;}.cf:after {clear: both;}.cf {*zoom: 1;}
Next, open the src/App.css file and delete all existing code and add the following:
.wrapper {margin: 100px 0 150px;}
The work result screen so far is as follows.
export function getModelData() {
return {
'60': {
19: {
on: {
speed: {
45: {
'-10': 224,
'0': 255,
'10': 287,
'20': 289,
'30': 287,
'40': 258
},
50: {
'-10': 211,
'0': 238,
'10': 264,
'20': 267,
'30': 267,
'40': 244
},
55: {
'-10': 198,
'0': 221,
'10': 242,
'20': 246,
'30': 245,
'40': 228
},
60: {
'-10': 184,
'0': 204,
'10': 222,
'20': 225,
'30': 226,
'40': 212
},
65: {
'-10': 170,
'0': 187,
'10': 202,
'20': 206,
'30': 208,
'40': 195
},
70: {
'-10': 156,
'0': 172,
'10': 185,
'20': 189,
'30': 190,
'40': 179
},
}
},
off: {
speed: {
45: {
'-10': 297,
'0': 312,
'10': 318,
'20': 325,
'30': 329,
'40': 333
},
50: {
'-10': 269,
'0': 283,
'10': 288,
'20': 294,
'30': 298,
'40': 304
},
55: {
'-10': 245,
'0': 256,
'10': 261,
'20': 267,
'30': 269,
'40': 277
},
60: {
'-10': 221,
'0': 231,
'10': 236,
'20': 242,
'30': 243,
'40': 252
},
65: {
'-10': 200,
'0': 209,
'10': 214,
'20': 219,
'30': 222,
'40': 230
},
70: {
'-10': 181,
'0': 189,
'10': 194,
'20': 199,
'30': 202,
'40': 209
},
}
}
},
21: {
on: {
speed: {
45: {
'-10': 220,
'0': 251,
'10': 283,
'20': 285,
'30': 282,
'40': 284
},
50: {
'-10': 208,
'0': 234,
'10': 260,
'20': 262,
'30': 262,
'40': 240
},
55: {
'-10': 194,
'0': 216,
'10': 238,
'20': 241,
'30': 240,
'40': 224
},
60: {
'-10': 180,
'0': 199,
'10': 217,
'20': 220,
'30': 221,
'40': 208
},
65: {
'-10': 166,
'0': 183,
'10': 198,
'20': 202,
'30': 203,
'40': 191
},
70: {
'-10': 152,
'0': 167,
'10': 180,
'20': 184,
'30': 185,
'40': 174
},
}
},
off: {
speed: {
45: {
'-10': 292,
'0': 307,
'10': 314,
'20': 320,
'30': 324,
'40': 328
},
50: {
'-10': 265,
'0': 278,
'10': 283,
'20': 289,
'30': 293,
'40': 298
},
55: {
'-10': 240,
'0': 251,
'10': 256,
'20': 261,
'30': 264,
'40': 272
},
60: {
'-10': 217,
'0': 226,
'10': 231,
'20': 236,
'30': 238,
'40': 247
},
65: {
'-10': 196,
'0': 204,
'10': 209,
'20': 214,
'30': 217,
'40': 225
},
70: {
'-10': 177,
'0': 184,
'10': 189,
'20': 194,
'30': 197,
'40': 204
},
}
}
}
},
'60D': {
19: {
on: {
speed: {
45: {
'-10': 227,
'0': 258,
'10': 291,
'20': 293,
'30': 292,
'40': 264
},
50: {
'-10': 215,
'0': 242,
'10': 269,
'20': 271,
'30': 272,
'40': 250
},
55: {
'-10': 201,
'0': 224,
'10': 247,
'20': 250,
'30': 251,
'40': 235
},
60: {
'-10': 187,
'0': 207,
'10': 226,
'20': 229,
'30': 232,
'40': 217
},
65: {
'-10': 172,
'0': 191,
'10': 207,
'20': 211,
'30': 213,
'40': 201
},
70: {
'-10': 158,
'0': 175,
'10': 189,
'20': 193,
'30': 195,
'40': 185
},
}
},
off: {
speed: {
45: {
'-10': 301,
'0': 317,
'10': 323,
'20': 330,
'30': 336,
'40': 339
},
50: {
'-10': 275,
'0': 288,
'10': 294,
'20': 301,
'30': 306,
'40': 311
},
55: {
'-10': 249,
'0': 260,
'10': 266,
'20': 273,
'30': 278,
'40': 283
},
60: {
'-10': 225,
'0': 236,
'10': 241,
'20': 248,
'30': 251,
'40': 258
},
65: {
'-10': 204,
'0': 214,
'10': 219,
'20': 225,
'30': 229,
'40': 236
},
70: {
'-10': 184,
'0': 193,
'10': 198,
'20': 205,
'30': 207,
'40': 215
},
}
}
},
21: {
on: {
speed: {
45: {
'-10': 223,
'0': 255,
'10': 287,
'20': 289,
'30': 288,
'40': 260
},
50: {
'-10': 211,
'0': 238,
'10': 264,
'20': 267,
'30': 267,
'40': 246
},
55: {
'-10': 197,
'0': 220,
'10': 242,
'20': 246,
'30': 246,
'40': 230
},
60: {
'-10': 183,
'0': 203,
'10': 221,
'20': 225,
'30': 227,
'40': 212
},
65: {
'-10': 168,
'0': 186,
'10': 202,
'20': 206,
'30': 208,
'40': 196
},
70: {
'-10': 155,
'0': 171,
'10': 184,
'20': 188,
'30': 190,
'40': 181
},
}
},
off: {
speed: {
45: {
'-10': 297,
'0': 312,
'10': 319,
'20': 326,
'30': 331,
'40': 335
},
50: {
'-10': 270,
'0': 283,
'10': 289,
'20': 296,
'30': 301,
'40': 306
},
55: {
'-10': 244,
'0': 256,
'10': 261,
'20': 268,
'30': 272,
'40': 278
},
60: {
'-10': 221,
'0': 231,
'10': 236,
'20': 242,
'30': 246,
'40': 253
},
65: {
'-10': 199,
'0': 209,
'10': 214,
'20': 220,
'30': 223,
'40': 231
},
70: {
'-10': 180,
'0': 188,
'10': 193,
'20': 200,
'30': 202,
'40': 210
},
}
}
}
},
'75': {
19: {
on: {
speed: {
45: {
'-10': 271,
'0': 309,
'10': 347,
'20': 350,
'30': 347,
'40': 312
},
50: {
'-10': 256,
'0': 288,
'10': 320,
'20': 323,
'30': 323,
'40': 295
},
55: {
'-10': 240,
'0': 267,
'10': 293,
'20': 297,
'30': 297,
'40': 276
},
60: {
'-10': 222,
'0': 246,
'10': 268,
'20': 272,
'30': 273,
'40': 257
},
65: {
'-10': 205,
'0': 227,
'10': 245,
'20': 250,
'30': 252,
'40': 236
},
70: {
'-10': 189,
'0': 206,
'10': 224,
'20': 228,
'30': 230,
'40': 216
},
}
},
off: {
speed: {
45: {
'-10': 359,
'0': 377,
'10': 385,
'20': 393,
'30': 398,
'40': 403
},
50: {
'-10': 326,
'0': 342,
'10': 349,
'20': 356,
'30': 360,
'40': 368
},
55: {
'-10': 296,
'0': 309,
'10': 316,
'20': 323,
'30': 326,
'40': 335
},
60: {
'-10': 268,
'0': 280,
'10': 286,
'20': 292,
'30': 295,
'40': 305
},
65: {
'-10': 242,
'0': 253,
'10': 259,
'20': 265,
'30': 268,
'40': 278
},
70: {
'-10': 219,
'0': 229,
'10': 234,
'20': 241,
'30': 244,
'40': 253
},
}
}
},
21: {
on: {
speed: {
45: {
'-10': 267,
'0': 304,
'10': 342,
'20': 344,
'30': 342,
'40': 308
},
50: {
'-10': 251,
'0': 283,
'10': 314,
'20': 317,
'30': 317,
'40': 290
},
55: {
'-10': 235,
'0': 262,
'10': 287,
'20': 291,
'30': 291,
'40': 271
},
60: {
'-10': 218,
'0': 241,
'10': 262,
'20': 266,
'30': 267,
'40': 251
},
65: {
'-10': 201,
'0': 222,
'10': 239,
'20': 244,
'30': 246,
'40': 231
},
70: {
'-10': 184,
'0': 203,
'10': 218,
'20': 223,
'30': 224,
'40': 211
},
}
},
off: {
speed: {
45: {
'-10': 353,
'0': 372,
'10': 279,
'20': 387,
'30': 392,
'40': 397
},
50: {
'-10': 320,
'0': 336,
'10': 343,
'20': 350,
'30': 354,
'40': 361
},
55: {
'-10': 290,
'0': 303,
'10': 309,
'20': 316,
'30': 319,
'40': 329
},
60: {
'-10': 262,
'0': 274,
'10': 279,
'20': 286,
'30': 288,
'40': 299
},
65: {
'-10': 237,
'0': 247,
'10': 253,
'20': 259,
'30': 262,
'40': 272
},
70: {
'-10': 214,
'0': 223,
'10': 229,
'20': 235,
'30': 238,
'40': 247
},
}
}
}
},
'75D': {
19: {
on: {
speed: {
45: {
'-10': 227,
'0': 316,
'10': 356,
'20': 358,
'30': 357,
'40': 323
},
50: {
'-10': 262,
'0': 296,
'10': 328,
'20': 332,
'30': 332,
'40': 305
},
55: {
'-10': 246,
'0': 274,
'10': 302,
'20': 306,
'30': 307,
'40': 287
},
60: {
'-10': 228,
'0': 253,
'10': 276,
'20': 280,
'30': 283,
'40': 265
},
65: {
'-10': 211,
'0': 233,
'10': 253,
'20': 257,
'30': 260,
'40': 246
},
70: {
'-10': 194,
'0': 214,
'10': 231,
'20': 236,
'30': 238,
'40': 226
},
}
},
off: {
speed: {
45: {
'-10': 368,
'0': 387,
'10': 395,
'20': 404,
'30': 410,
'40': 415
},
50: {
'-10': 335,
'0': 351,
'10': 359,
'20': 367,
'30': 374,
'40': 380
},
55: {
'-10': 304,
'0': 318,
'10': 325,
'20': 334,
'30': 339,
'40': 346
},
60: {
'-10': 275,
'0': 288,
'10': 294,
'20': 303,
'30': 307,
'40': 316
},
65: {
'-10': 249,
'0': 261,
'10': 267,
'20': 275,
'30': 279,
'40': 289
},
70: {
'-10': 225,
'0': 236,
'10': 242,
'20': 250,
'30': 253,
'40': 263
},
}
}
},
21: {
on: {
speed: {
45: {
'-10': 273,
'0': 311,
'10': 351,
'20': 354,
'30': 352,
'40': 318
},
50: {
'-10': 258,
'0': 291,
'10': 323,
'20': 326,
'30': 327,
'40': 300
},
55: {
'-10': 241,
'0': 269,
'10': 296,
'20': 300,
'30': 301,
'40': 281
},
60: {
'-10': 223,
'0': 248,
'10': 270,
'20': 275,
'30': 277,
'40': 259
},
65: {
'-10': 206,
'0': 228,
'10': 247,
'20': 252,
'30': 254,
'40': 240
},
70: {
'-10': 189,
'0': 209,
'10': 225,
'20': 230,
'30': 232,
'40': 221
},
}
},
off: {
speed: {
45: {
'-10': 363,
'0': 382,
'10': 390,
'20': 398,
'30': 405,
'40': 409
},
50: {
'-10': 330,
'0': 346,
'10': 353,
'20': 361,
'30': 368,
'40': 373
},
55: {
'-10': 299,
'0': 312,
'10': 319,
'20': 327,
'30': 333,
'40': 340
},
60: {
'-10': 270,
'0': 282,
'10': 288,
'20': 296,
'30': 301,
'40': 309
},
65: {
'-10': 244,
'0': 255,
'10': 261,
'20': 269,
'30': 273,
'40': 282
},
70: {
'-10': 219,
'0': 230,
'10': 236,
'20': 244,
'30': 247,
'40': 257
},
}
}
}
},
'90D': {
19: {
on: {
speed: {
45: {
'-10': 308,
'0': 349,
'10': 392,
'20': 394,
'30': 392,
'40': 357
},
50: {
'-10': 292,
'0': 326,
'10': 362,
'20': 365,
'30': 365,
'40': 338
},
55: {
'-10': 273,
'0': 303,
'10': 332,
'20': 336,
'30': 337,
'40': 317
},
60: {
'-10': 254,
'0': 280,
'10': 305,
'20': 308,
'30': 310,
'40': 293
},
65: {
'-10': 235,
'0': 258,
'10': 279,
'20': 283,
'30': 285,
'40': 273
},
70: {
'-10': 216,
'0': 238,
'10': 256,
'20': 260,
'30': 263,
'40': 253
},
}
},
off: {
speed: {
45: {
'-10': 406,
'0': 426,
'10': 434,
'20': 443,
'30': 451,
'40': 455
},
50: {
'-10': 370,
'0': 386,
'10': 394,
'20': 403,
'30': 412,
'40': 416
},
55: {
'-10': 336,
'0': 350,
'10': 358,
'20': 366,
'30': 274,
'40': 380
},
60: {
'-10': 304,
'0': 317,
'10': 324,
'20': 332,
'30': 338,
'40': 347
},
65: {
'-10': 276,
'0': 288,
'10': 295,
'20': 302,
'30': 308,
'40': 317
},
70: {
'-10': 250,
'0': 261,
'10': 268,
'20': 275,
'30': 279,
'40': 290
},
}
}
},
21: {
on: {
speed: {
45: {
'-10': 304,
'0': 345,
'10': 386,
'20': 388,
'30': 387,
'40': 352
},
50: {
'-10': 287,
'0': 321,
'10': 356,
'20': 359,
'30': 360,
'40': 332
},
55: {
'-10': 268,
'0': 297,
'10': 326,
'20': 330,
'30': 330,
'40': 311
},
60: {
'-10': 249,
'0': 274,
'10': 299,
'20': 302,
'30': 303,
'40': 287
},
65: {
'-10': 230,
'0': 253,
'10': 273,
'20': 277,
'30': 279,
'40': 267
},
70: {
'-10': 211,
'0': 232,
'10': 250,
'20': 254,
'30': 257,
'40': 247
},
}
},
off: {
speed: {
45: {
'-10': 401,
'0': 420,
'10': 428,
'20': 437,
'30': 446,
'40': 449
},
50: {
'-10': 364,
'0': 380,
'10': 388,
'20': 397,
'30': 405,
'40': 410
},
55: {
'-10': 330,
'0': 344,
'10': 351,
'20': 359,
'30': 367,
'40': 373
},
60: {
'-10': 298,
'0': 311,
'10': 318,
'20': 325,
'30': 331,
'40': 340
},
65: {
'-10': 270,
'0': 282,
'10': 288,
'20': 296,
'30': 301,
'40': 310
},
70: {
'-10': 244,
'0': 255,
'10': 262,
'20': 269,
'30': 273,
'40': 284
},
}
}
}
},
'P100D': {
19: {
on: {
speed: {
45: {
'-10': 341,
'0': 390,
'10': 439,
'20': 442,
'30': 440,
'40': 401
},
50: {
'-10': 323,
'0': 365,
'10': 405,
'20': 409,
'30': 410,
'40': 380
},
55: {
'-10': 303,
'0': 339,
'10': 372,
'20': 376,
'30': 379,
'40': 353
},
60: {
'-10': 282,
'0': 313,
'10': 341,
'20': 345,
'30': 347,
'40': 329
},
65: {
'-10': 261,
'0': 289,
'10': 312,
'20': 317,
'30': 318,
'40': 306
},
70: {
'-10': 240,
'0': 265,
'10': 285,
'20': 290,
'30': 293,
'40': 283
},
}
},
off: {
speed: {
45: {
'-10': 447,
'0': 474,
'10': 485,
'20': 496,
'30': 505,
'40': 509
},
50: {
'-10': 408,
'0': 431,
'10': 441,
'20': 451,
'30': 461,
'40': 466
},
55: {
'-10': 372,
'0': 391,
'10': 400,
'20': 409,
'30': 419,
'40': 425
},
60: {
'-10': 337,
'0': 354,
'10': 362,
'20': 371,
'30': 377,
'40': 388
},
65: {
'-10': 306,
'0': 321,
'10': 329,
'20': 337,
'30': 341,
'40': 354
},
70: {
'-10': 277,
'0': 291,
'10': 299,
'20': 307,
'30': 311,
'40': 323
},
}
}
},
21: {
on: {
speed: {
45: {
'-10': 322,
'0': 369,
'10': 414,
'20': 417,
'30': 416,
'40': 379
},
50: {
'-10': 306,
'0': 347,
'10': 384,
'20': 388,
'30': 389,
'40': 360
},
55: {
'-10': 228,
'0': 323,
'10': 354,
'20': 358,
'30': 360,
'40': 336
},
60: {
'-10': 269,
'0': 299,
'10': 325,
'20': 329,
'30': 331,
'40': 313
},
65: {
'-10': 250,
'0': 276,
'10': 299,
'20': 303,
'30': 305,
'40': 292
},
70: {
'-10': 230,
'0': 254,
'10': 273,
'20': 278,
'30': 281,
'40': 271
},
}
},
off: {
speed: {
45: {
'-10': 422,
'0': 447,
'10': 458,
'20': 468,
'30': 477,
'40': 481
},
50: {
'-10': 387,
'0': 409,
'10': 418,
'20': 428,
'30': 437,
'40': 442
},
55: {
'-10': 353,
'0': 372,
'10': 380,
'20': 389,
'30': 398,
'40': 404
},
60: {
'-10': 322,
'0': 338,
'10': 345,
'20': 354,
'30': 359,
'40': 370
},
65: {
'-10': 293,
'0': 307,
'10': 315,
'20': 323,
'30': 326,
'40': 339
},
70: {
'-10': 265,
'0': 279,
'10': 286,
'20': 294,
'30': 298,
'40': 310
},
}
}
}
}
}
}