Одна вещь, которую я заметил, заключается в том, что действительно легко неявно обновить объект состояния, как если бы вы написали this.state.object = newObject
, не подозревая о последствиях.
Допустим, у нас есть объект cars
, установленный в состоянии, и мы хотим обновить одну машину новыми свойствами. Что-то вроде этого:
updateCar = car => { // Get car id. const id = { car }; // Get current cars from state. const { cars } = this.state; // Update passed car. cars[id] = car; // Update state object, for the first time, or is it? this.setState({ cars }); }
На самом деле мы неявно обновляем this.state.cars
в строке: cars[id] = car
. Как будто вместо этого мы написали этот код:
updateCar = car => { // Get car id. const id = { car }; // Get current cars from state. // You're 100% positive you're passing object value via reference. const cars = this.state.cars; // Update passed car. // At this point you know you're modifing original object values. cars[id] = car; // Update state object, for the first time, or is it? // This kinda seems redundant now? At least you know you've already updated the state (although React isn't aware of it). this.setState({ cars }); }
Я заметил это совершенно случайно, потому что обновлял объект даты из состояния каждый раз, когда его проверяла функция. Что-то вроде этого:
checkDataValidity = (date = new Date) => { const { latestDate } = this.state; const ttlSeconds = 15 * 60; latestDate.setSeconds(latestDate.getSeconds() + ttlSeconds); return latestDate.getTime() > date.getTime(); }
Я считаю, что очень легко не заметить такую ситуацию. Проблема в том, что я довольно часто вызываю эту функцию. И он увеличивается на latestDate
каждый раз, когда я вызываю функцию, что делает ее совершенно бесполезной.
Таким образом, объект состояния изменяется, и хотя эта дата отображается где-то на странице, она визуально не обновляется, потому что мы не вызывали setState
с ней позже явно.
Я считаю, что в первом примере в статье отсутствует подобная ситуация, потому что это легко упустить из виду, поскольку это происходит только с объектами.