У меня есть фрагмент кода ниже -
class Sum extends React.Component {
constructor(props) {
super(props)
this.state = { a : 0 }
}
// let's call this ADD-1
add = () => {
this.setState({ a: this.state.a + 1 })
this.setState({ a: this.state.a + 2 })
this.setState({ a: this.state.a + 3 })
}
render() {
return (<div>
<button onClick = {this.add}> click me </button>
<div> sum {this.state.a} </div>
</div>)
}
}
это отображается при нажатии кнопки
sum = 3
где, как я надеялся, он отобразит sum = 6, т.е. 1 + 2 + 3
Кроме того, если я изменю свой метод add на что-то вроде приспособления к условиям гонки prevState -
// let's call this ADD-2
add = () => {
this.setState({ a: this.state.a + 1 })
this.setState({ a: this.state.a + 2 })
this.setState(prevState => ({ a: prevState.a + 1 }))
this.setState(prevState => ({ a: prevState.a + 4 }))
}
он отображает sum = 7, тогда как я надеялся на sum = 8, т.е. (1 + 2 + 1 + 4)
На ум приходят два вопроса:
1) Почему мы видим результаты, указанные выше, а не те, которых я ожидал?
2) Почему я не вижу перехода добавления в UI?
Скажем, если мы рассмотрим метод с тегом ADD-1, я должен увидеть что-то вроде sum = 1, затем sum = 3, затем sum = 6. Это из-за пакетирования обновлений, но пакетирование помещает их в очередь выполнения, на мой взгляд, это ничего не отменяет.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


«React может объединять несколько вызовов setState () в одно обновление для повышения производительности».
От Документы
Убедитесь, что вы передаете функцию в setState, когда ваше обновление зависит от текущего состояния, чтобы оно не было перезаписано последующим setState.
Пример
class App extends React.Component {
state = { a: 0 };
add = () => {
this.setState(previousState => {
return { a: previousState.a + 1 };
});
this.setState(previousState => {
return { a: previousState.a + 2 };
});
this.setState(previousState => {
return { a: previousState.a + 3 };
});
};
render() {
return (
<div>
<button onClick = {this.add}> click me </button>
<div> sum {this.state.a} </div>
</div>
);
}
}
Обновление состояния может быть асинхронным. Отметьте это отвечать.
В отвечать Дэна Абрамова указано, что обновления состояния в рамках одного вызова события будут производить только один повторный рендеринг в конце события.
no matter how many setState() calls in how many components you do inside a React event handler, they will produce only a single re-render at the end of the event.
А также пакетирование происходит только для обновлений состояния в обработчике событий React, т.е. пакетирование не происходит внутри вызовов AJAX.
promise.then(() => {
// We're not in an event handler, so these are flushed separately.
this.setState({a: true}); // Re-renders with {a: true, b: false }
this.setState({b: true}); // Re-renders with {a: true, b: true }
this.props.setParentState(); // Re-renders the parent
});
Но вы можете добиться того, чего хотите, передав обратный вызов методу setState.
add = () => {
this.setState({ a: this.state.a + 1 },
() => {
this.setState({ a: this.state.a + 2 },
() => {
this.setState({ a: this.state.a + 3 })
})
})
}
Вышеупомянутое вернет sum = 6.
Когда не использовать обратные вызовы в setState:
PureComponentandshouldComponentUpdatecan be used to tune up a component’s performance. They work by preventing lifecycle methods from firing when props and state haven’t changed.The
setStatecallback fires regardless of whatshouldComponentUpdatereturns. So, thesetStatecallback will fire, even when state hasn’t changed.
изменение состояния может произойти только через setState, но если вы получите доступ и измените this.state до setState (this.state.a + 1), это не отразится. поэтому каждый раз, когда вы обращаетесь к this.state.a, он получает 0, т.е. начальное значение.
add = () => {
this.setState({ a: this.state.a + 1 }) // 0 + 1
this.setState({ a: this.state.a + 2 }) // 0 + 2
this.setState({ a: this.state.a + 3 }) // 0 + 3
}
this.setState((previousState) => { // change state using previousState} );
это способ обновить состояние
setState является асинхронным, все они вызываются "по существу" сразу. Это означает, что последний устанавливает состояние на 0 + 3. Метод setState имеет обратный вызов, если вы хотите дождаться его обновления, затем вызовите другой метод setState. this.setState ({значение: значение + 1}, () => {this.setState ({значение: значение + 2})}) medium.com/@wereHamster/…