1.14 State Update
We'll cover the following...
We'll cover the following...
Are we finally done? Even if the user changes several condition values, the difference value of the vehicle model does not change properly.
So far, we’ve only updated a part of our app’s status each time an event occurs.
this.setState({ config });
Now let’s change the carstats state whenever the config state value changes.
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)})}
Now we create a function that take the carModels and the current state value as inputs and reflects the changed carStats in the app state and pass it to this.setState as a callback.
By doing this, it is possible to update the config object first in setState(), which operates asynchronous method, and to render the changed stats on the screen based on this.
this.setState({ config }, () => {this.statsUpdate()});
This completes all the puzzles. The complete code for TeslaBattery is:
import React from 'react';import './TeslaBattery.css';import TeslaNotice from '../components/TeslaNotice/TeslaNotice';import TeslaCar from '../components/TeslaCar/TeslaCar';import TeslaStats from '../components/TeslaStats/TeslaStats';import TeslaCounter from '../components/TeslaCounter/TeslaCounter';import TeslaClimate from '../components/TeslaClimate/TeslaClimate';import TeslaWheels from '../components/TeslaWheels/TeslaWheels';import { getModelData } from '../services/BatteryService';class TeslaBattery extends React.Component {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.handleChangeClimate = this.handleChangeClimate.bind(this);this.handleChangeWheels = this.handleChangeWheels.bind(this);this.state = {carstats: [],config: {speed: 55,temperature: 20,climate: true,wheels: 19}}}calculateStats = (models, value) => {const dataModels = getModelData();return models.map(model => {const { 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();}updateCounterState(title, newValue) {const config = { ...this.state.config };// update config state with new valuetitle === 'Speed' ? config['speed'] = newValue : config['temperature'] = newValue;// update our statethis.setState({ config }, () => {this.statsUpdate()});}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);}}// handle aircon & heating click event handlerhandleChangeClimate() {const config = {...this.state.config};config['climate'] = !this.state.config.climate;this.setState({ config }, () => {this.statsUpdate()});}// handle Wheels click event handlerhandleChangeWheels(size) {const config = {...this.state.config};config['wheels'] = size;this.setState({ config }, () => {this.statsUpdate()});}render() {const { config, carstats } = this.state;return (<form className="tesla-battery"><h1>Range Per Charge</h1><TeslaCar wheelsize={config.wheels} /><TeslaStats carstats={carstats} /><div className="tesla-controls cf"><TeslaCountercurrentValue={this.state.config.speed}initValues={this.props.counterDefaultVal.speed}increment={this.increment}decrement={this.decrement}/><div className="tesla-climate-container cf"><TeslaCountercurrentValue={this.state.config.temperature}initValues={this.props.counterDefaultVal.temperature}increment={this.increment}decrement={this.decrement}/><TeslaClimatevalue={this.state.config.climate}limit={this.state.config.temperature > 10}handleChangeClimate={this.handleChangeClimate}/></div><TeslaWheelsvalue={this.state.config.wheels}handleChangeWheels={this.handleChangeWheels}/></div><TeslaNotice /></form>)}}export default TeslaBattery;
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
},
}
}
}
}
}
}