Imagine incrementing một truy cập trong một số thành phần:
class SomeComponent extends Component{
state = {
updatedByDiv: '',
updatedByBtn: '',
counter: 0
}
divCountHandler =() => {
this.setState({
updatedByDiv: 'Div',
counter: this.state.counter + 1
});
console.log('divCountHandler executed');
}
btnCountHandler =() => {
this.setState({
updatedByBtn: 'Button',
counter: this.state.counter + 1
});
console.log('btnCountHandler executed');
}
...
...
render(){
return (
...
// a parent div
<div onClick={this.divCountHandler}>
// a child button
<button onClick={this.btnCountHandler}>Increment Count</button>
</div>
...
)
}
}
Có một handler đếm gắn liền với cả phụ huynh và các thành phần con. Điều này được thực hiện cố ý để chúng ta có thể thực hiện setState() hai lần trong cùng một sự kiện nhấp chuột bubbling context, nhưng từ bên trong 2 trình xử lý khác nhau. Như chúng ta sẽ tưởng tượng, một sự kiện nhấp chuột duy nhất trên nút sẽ kích hoạt cả hai trình xử lý này kể từ khi bong bóng sự kiện từ mục tiêu đến vùng chứa ngoài cùng trong giai đoạn tạo bọt.
Do đó btnCountHandler() thực hiện đầu tiên, dự kiến sẽ làm tăng số lần cho 1 và sau đó là divCountHandler() thực hiện, dự kiến sẽ làm tăng số lần để 2.
Tuy nhiên số lượng chỉ increments tới 1 như bạn có thể kiểm tra trong công cụ React Developer.
này chứng minh rằng phản ứng
hàng đợi tất cả các setstate gọi
trở lại vào hàng đợi này sau khi thực hiện phương pháp cuối cùng trong bối cảnh (các divCountHandler trong trường hợp này)
kết hợp tất cả các đột biến đối tượng xảy ra trong nhiều cuộc gọi setState trong cùng một ngữ cảnh (tất cả các cuộc gọi phương thức trong một pha sự kiện đơn lẻ là cùng một bối cảnh ví dụ) thành một cú pháp đột biến đối tượng đơn lẻ. e vì đây là lý do tại sao chúng tôi có thể cập nhật các thuộc tính trạng thái độc lập trong setState() ở vị trí đầu tiên)
và chuyển nó vào một setState() đơn lẻ để ngăn hiển thị lại do nhiều lệnh setState() một mô tả rất nguyên thủy của đợt).
đang Resultant chạy bằng phản ứng:
this.setState({
updatedByDiv: 'Div',
updatedByBtn: 'Button',
counter: this.state.counter + 1
})
Để ngăn chặn hành vi này, thay vì đi qua đối tượng như các đối số cho phương thức setstate, callbacks được thông qua.
divCountHandler =() => {
this.setState((prevState, props) => {
return {
updatedByDiv: 'Div',
counter: prevState.counter + 1
};
});
console.log('divCountHandler executed');
}
btnCountHandler =() => {
this.setState((prevState, props) => {
return {
updatedByBtn: 'Button',
counter: prevState.counter + 1
};
});
console.log('btnCountHandler executed');
}
Sau khi phương thức cuối cùng kết thúc thực hiện và khi phản hồi trả về để xử lý hàng đợi setState, nó gọi đơn giản gọi lại cho mỗi setState xếp hàng, đi qua trạng thái thành phần trước đó.
Cách này phản ứng đảm bảo rằng lần gọi lại cuối cùng trong hàng đợi được cập nhật trạng thái mà tất cả các đối tác trước đó của nó đã đặt tay lên.
Xem http://stackoverflow.com/questions/28922275/in-reactjs-why-does-setstate-behave-differently-when-called-synchronously – lux