1.11 Reusable TeslaCounter Component

Tesla’s speed and external temperature controls should be reusable components, so I’ll make them a generic Counter component that allows for other metadata such as step, minimum, maximum, and title and units (mph / degrees).

Also, unlike the components we have created so far, we need an action to change the state value in response to user input (button click, checkbox selection, etc.). Let’s look at how to handle events that occur in a subcomponent.

Create the src/components/TeslaCounter directory as before, create a TeslaCounter.js file in it, and enter the following code:

import React from 'react';
import PropTypes from 'react';
import './TeslaCounter.css';
const TeslaCounter = (props) => (
<div className="tesla-counter">
<p className="tesla-counter__title">{props.initValues.title}</p>
<div className="tesla-counter__container cf">
<div className="tesla-counter__item">
<p className="tesla-counter__number">
{ props.currentValue }
<span>{ props.initValues.unit }</span>
</p>
<div className="tesla-counter__controls">
<button
onClick={(e) => props.increment(e, props.initValues.title)}
disabled={props.currentValue >= props.initValues.max}
>
</button>
<button
onClick={(e) => props.decrement(e, props.initValues.title)}
disabled={props.currentValue <= props.initValues.min}
>
</button>
</div>
</div>
</div>
</div>
);
TeslaCounter.propTypes = {
currentValue: PropTypes.number,
increment: PropTypes.func,
decrement: PropTypes.func,
initValues: PropTypes.object
}
export default TeslaCounter;

Let’s think about what we want here. Each time you click and change the speed and temperature, you must update the state so that the value is reflected between the maximum and minimum values.

Since the component only needs to update its own state, TeslaBattery passes the callback (increment, decrement) to the TeslaCounter each time it needs to update its state. You can use the onClick event on a button to notify the event. The callback passed by TeslaBattery calls setState() and the app is updated.

We will implement a callback that will be passed by TeslaBattery in a few moments.

1.11.1 TeslaCounter Component Style

Let’s implement the style first. Create a TeslaCounter.css file in the src/components/TeslaCounter directory and specify the following styles. Since the code is long and omitted here, let’s check the source code

.tesla-counter {
float: left;
width: 230px;
}
.tesla-counter__title {
letter-spacing: 2px;
font-size: 16px;
}
...

1.11.2 Import TeslaCounter Component in TeslaBattery Container

Now, we will implement callback in TeslaBattery and pass it to the TeslaCounter component.

First, add import to use the TeslaCounter component in TeslaBattery.js.

We also implement the callback functions increment() and decrement(), and the internal function updateCounterState() and bind it in the constructor. Then pass the callback function to the TeslaCounter component with props.

...
constructor(props) {
super(props);
this.calculateStats = this.calculateStats.bind(this);
this.statsUpdate = this.statsUpdate.bind(this);
this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this);
this.updateCounterState = this.updateCounterState.bind(this);
this.state = {
carstats: [],
config: {
speed: 55,
temperature: 20,
climate: true,
wheels: 19
}
}
}
...
updateCounterState(title, newValue) {
const config = { ...this.state.config };
// update config state with new value
title === 'Speed' ? config['speed'] = newValue : config['temperature'] = newValue;
// update our state
this.setState({ config });
}
increment(e, title) {
e.preventDefault();
let currentValue, maxValue, step;
const { speed, temperature } = this.props.counterDefaultVal;
if (title === 'Speed') {
currentValue = this.state.config.speed;
maxValue = speed.max;
step = speed.step;
} else {
currentValue = this.state.config.temperature;
maxValue = temperature.max;
step = temperature.step;
}
if (currentValue < maxValue) {
const newValue = currentValue + step;
this.updateCounterState(title, newValue);
}
}
decrement(e, title) {
e.preventDefault();
let currentValue, minValue, step;
const { speed, temperature } = this.props.counterDefaultVal;
if (title === 'Speed') {
currentValue = this.state.config.speed;
minValue = speed.min;
step = speed.step;
} else {
currentValue = this.state.config.temperature;
minValue = temperature.min;
step = temperature.step;
}
if (currentValue > minValue) {
const newValue = currentValue - step;
this.updateCounterState(title, newValue);
}
}
...
render() {
return (
<form className="tesla-battery">
<h1>Range Per Charge</h1>
<TeslaCar wheelsize={config.wheels} />
<TeslaStats carstats={carstats} />
<div className="tesla-controls cf">
<TeslaCounter
currentValue={this.state.config.speed}
initValues={this.props.counterDefaultVal.speed}
increment={this.increment}
decrement={this.decrement}
/>
<div className="tesla-climate-container cf">
<TeslaCounter
currentValue={this.state.config.temperature}
initValues={this.props.counterDefaultVal.temperature}
increment={this.increment}
decrement={this.decrement}
/>
</div>
</div>
<TeslaNotice />
</form>
)
}

1.11.3 TeslaBattery Container Style

An additional style is required for TeslaBattery as soon as the TeslaCounter component is added. Open the TeslaBattery.css file and add the following:

.tesla-climate-container {
float: left;
width: 420px;
padding: 0 40px;
margin: 0 40px 0 0;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
}
.tesla-controls {
display: block;
width: 100%;
}

1.11.4 Default Value Props

Here, initValues passed to TeslaCounter is a constant value and is passed from App which is a parent component of TeslaBattery.

Open App.js and pass the counterDefaultVal object to the TeslaBattery component as follows:

import React, { Component } from 'react';
import './App.css';
import Header from './components/Header/Header';
import TeslaBattery from './containers/TeslaBattery';
const counterDefaultVal = {
speed: {
title: "Speed",
unit: "mph",
step: 5,
min: 45,
max: 70
},
temperature: {
title: "Outside Temperature",
unit: "°",
step: 10,
min: -10,
max: 40
}
};
class App extends Component {
render() {
return (
<div className="App">
<Header />
<TeslaBattery counterDefaultVal={counterDefaultVal}/>
</div>
);
}
}
export default App;

Now, when you click Speed and Temperature, you can see that the changed values are updated and re-rendered in the state object through the React Developer Tool.

widget
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
              },
            }
          }
        }
      }
    }
  }

1.11.5 Virtual DOM

What a single-page application can give us is a seamless user experience and smooth interaction.

In our app, car model values are updated without having to reload the entire page every time the user changes speed or temperature. Even if you need to connect to the server to get the data. To provide this user experience, you need to know which part of the DOM you need to update when changes or interactions occur.

Each JavaScript framework uses a different strategy: Ember uses data-binding, Angular1 uses dirty checking, and React uses Virtual DOM.

In React, the first time the component’s rendering method is called, it prints a virtual DOM model, rather than the actual DOM element itself. The virtual DOM is a JavaScript data structure that represents the appearance of DOM. React then takes this model and creates the actual DOM element.

Then, whenever the component’s state changes (eg, setState is called), the rendering method of the component is called and a new virtual DOM is created, and this new virtual DOM is replaced with the previous virtual DOM. The result of this comparison is to show the actual DOM changes and the DOM will be ‘patched’ with the changes and the screen will change.

The car model information does not change yet as the speed and temperature change. This will eventually be implemented later.