React: potential race condition for Controlled Components
There is the following code in the React tutorial:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
There is also a warning about the setState method:
setState() does not always immediately update the component. It may
batch or defer the update until later. This makes reading this.state
right after calling setState() a potential pitfall.
Q: Is the following scenario possible:
handleChange is fired;
setState is queued in the React;
handleSubmit is fired and it reads an obsolete value of this.state.value;
setState is actually processed.
Or there is some kind of protection preventing such scenario from happening?
javascript reactjs
add a comment |
There is the following code in the React tutorial:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
There is also a warning about the setState method:
setState() does not always immediately update the component. It may
batch or defer the update until later. This makes reading this.state
right after calling setState() a potential pitfall.
Q: Is the following scenario possible:
handleChange is fired;
setState is queued in the React;
handleSubmit is fired and it reads an obsolete value of this.state.value;
setState is actually processed.
Or there is some kind of protection preventing such scenario from happening?
javascript reactjs
add a comment |
There is the following code in the React tutorial:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
There is also a warning about the setState method:
setState() does not always immediately update the component. It may
batch or defer the update until later. This makes reading this.state
right after calling setState() a potential pitfall.
Q: Is the following scenario possible:
handleChange is fired;
setState is queued in the React;
handleSubmit is fired and it reads an obsolete value of this.state.value;
setState is actually processed.
Or there is some kind of protection preventing such scenario from happening?
javascript reactjs
There is the following code in the React tutorial:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
There is also a warning about the setState method:
setState() does not always immediately update the component. It may
batch or defer the update until later. This makes reading this.state
right after calling setState() a potential pitfall.
Q: Is the following scenario possible:
handleChange is fired;
setState is queued in the React;
handleSubmit is fired and it reads an obsolete value of this.state.value;
setState is actually processed.
Or there is some kind of protection preventing such scenario from happening?
javascript reactjs
javascript reactjs
asked Nov 15 '18 at 9:43
Denis KulaginDenis Kulagin
4,30163681
4,30163681
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
I hope this
answers your question:
In React 16, if you call setState inside a React event handler, it is flushed when React exits the browser event handler. So it's not synchronous but happens in the same top-level stack.
In React 16, if you call setState outside a React event handler, it is flushed immediately.
Let's examine what happens (main points):
- entering
handleChange
react event handler; - all
setState
calls are batched inside; - exiting
handleChange
- flushing
setState
changes
render
is called- entering
handleSubmit
- accessing correctly commited values from
this.state
- exiting
handleSubmit
So as you see, race condition can't happen as long as updates are scheduled within React
event handlers, since React
commits all batched state
updates in the end of every event handler call.
add a comment |
In your case reading old value is impossible. Under "It may batch or defer the update until later" it means just a case
this.setState({a: 11});
console.log(this.state.a);
so setState
may just add a change to queue but not directly update this.state
. But it does not mean you can just change input with triggering handleChange
and then click button triggering handleSubmit
and .state
is still not updated. It because how event loop works - if some code is executing browser will not process any event(you should experience cases when UI freezes for a while).
So the only thing to reproduce 'race condition' is to run one handler from another:
handleChange(event) {
this.setState({value: event.target.value});
this.handleSubmit();
}
This way, yes, you will get previous value
shown in alert.
For such a cases .setState
takes optional callback parameter
The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead.
Applied to your code it'd look like
handleChange(event) {
this.setState({value: event.target.value}, this.handleSubmit);
}
PS And sure your code may delay setState
with setTimeout
on your own like
handleChange({target: {value}}) {
setTimeout(() => {
this.setState({value});
}, 5000);
}
And there is no way to ensure handleSubmit
is operating on latest value. But in such a case it's all on your shoulders how to handle that.
[UPD] some details on how async works in JS. I have heard different terms: "event loop", "message queue", "microtask/task queue" and sometimes it means different things(and there is a difference actually). But to make things easier let's assume there is just single queue. And everything async like event handlers, Promise.then()
, setImmediate()
just go to the end of this queue.
This way each setState
(if it's in batch mode) does 2 things: adds changeset to stack(it could be array variable) and set up additional task into queue(say with setImmediate
). This additional task will process all stacked changes and run rerender just once.
Even if you would be so fast to click Submit button before those deferred updater is executed event handler would go to the end of queue. So event handler will definitely run after all batched state's changes are applied.
Sorry, I cannot just refer to React code to prove because updater code looks really complex for me. But I found article that has many details how it works under the hood. Maybe it gives some additional information to you.
[UPD] met nice article on microtasks, macrotasks and event loop: https://abc.danch.me/microtasks-macrotasks-more-on-the-event-loop-881557d7af6f?gi=599c66cc504c
it does not change the result but makes me understand all that better
It became more clear to me, but not crystal yet. Do you say that React queues setState calls to some internal JS query that is guaranteed to be processed in between handling events?
– Denis Kulagin
Nov 18 '18 at 14:11
after reviewing my own answer I see it looks overcomplicated. So I've updated answer with more details.
– skyboyer
Nov 18 '18 at 20:03
Your and Karen answers are both great and I was having a hard time deciding whom to award the bounty. I have accepted Karen's answer for being more concise. But bounty goes to your answer as being much more detailed and containing useful references to investigate this issue in depth.
– Denis Kulagin
Nov 21 '18 at 8:05
found good article on microtask/macrotask/event loop: abc.danch.me/…
– skyboyer
Nov 29 '18 at 22:19
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53316501%2freact-potential-race-condition-for-controlled-components%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I hope this
answers your question:
In React 16, if you call setState inside a React event handler, it is flushed when React exits the browser event handler. So it's not synchronous but happens in the same top-level stack.
In React 16, if you call setState outside a React event handler, it is flushed immediately.
Let's examine what happens (main points):
- entering
handleChange
react event handler; - all
setState
calls are batched inside; - exiting
handleChange
- flushing
setState
changes
render
is called- entering
handleSubmit
- accessing correctly commited values from
this.state
- exiting
handleSubmit
So as you see, race condition can't happen as long as updates are scheduled within React
event handlers, since React
commits all batched state
updates in the end of every event handler call.
add a comment |
I hope this
answers your question:
In React 16, if you call setState inside a React event handler, it is flushed when React exits the browser event handler. So it's not synchronous but happens in the same top-level stack.
In React 16, if you call setState outside a React event handler, it is flushed immediately.
Let's examine what happens (main points):
- entering
handleChange
react event handler; - all
setState
calls are batched inside; - exiting
handleChange
- flushing
setState
changes
render
is called- entering
handleSubmit
- accessing correctly commited values from
this.state
- exiting
handleSubmit
So as you see, race condition can't happen as long as updates are scheduled within React
event handlers, since React
commits all batched state
updates in the end of every event handler call.
add a comment |
I hope this
answers your question:
In React 16, if you call setState inside a React event handler, it is flushed when React exits the browser event handler. So it's not synchronous but happens in the same top-level stack.
In React 16, if you call setState outside a React event handler, it is flushed immediately.
Let's examine what happens (main points):
- entering
handleChange
react event handler; - all
setState
calls are batched inside; - exiting
handleChange
- flushing
setState
changes
render
is called- entering
handleSubmit
- accessing correctly commited values from
this.state
- exiting
handleSubmit
So as you see, race condition can't happen as long as updates are scheduled within React
event handlers, since React
commits all batched state
updates in the end of every event handler call.
I hope this
answers your question:
In React 16, if you call setState inside a React event handler, it is flushed when React exits the browser event handler. So it's not synchronous but happens in the same top-level stack.
In React 16, if you call setState outside a React event handler, it is flushed immediately.
Let's examine what happens (main points):
- entering
handleChange
react event handler; - all
setState
calls are batched inside; - exiting
handleChange
- flushing
setState
changes
render
is called- entering
handleSubmit
- accessing correctly commited values from
this.state
- exiting
handleSubmit
So as you see, race condition can't happen as long as updates are scheduled within React
event handlers, since React
commits all batched state
updates in the end of every event handler call.
edited Nov 18 '18 at 23:24
answered Nov 18 '18 at 23:06
Karen GrigoryanKaren Grigoryan
3,05011024
3,05011024
add a comment |
add a comment |
In your case reading old value is impossible. Under "It may batch or defer the update until later" it means just a case
this.setState({a: 11});
console.log(this.state.a);
so setState
may just add a change to queue but not directly update this.state
. But it does not mean you can just change input with triggering handleChange
and then click button triggering handleSubmit
and .state
is still not updated. It because how event loop works - if some code is executing browser will not process any event(you should experience cases when UI freezes for a while).
So the only thing to reproduce 'race condition' is to run one handler from another:
handleChange(event) {
this.setState({value: event.target.value});
this.handleSubmit();
}
This way, yes, you will get previous value
shown in alert.
For such a cases .setState
takes optional callback parameter
The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead.
Applied to your code it'd look like
handleChange(event) {
this.setState({value: event.target.value}, this.handleSubmit);
}
PS And sure your code may delay setState
with setTimeout
on your own like
handleChange({target: {value}}) {
setTimeout(() => {
this.setState({value});
}, 5000);
}
And there is no way to ensure handleSubmit
is operating on latest value. But in such a case it's all on your shoulders how to handle that.
[UPD] some details on how async works in JS. I have heard different terms: "event loop", "message queue", "microtask/task queue" and sometimes it means different things(and there is a difference actually). But to make things easier let's assume there is just single queue. And everything async like event handlers, Promise.then()
, setImmediate()
just go to the end of this queue.
This way each setState
(if it's in batch mode) does 2 things: adds changeset to stack(it could be array variable) and set up additional task into queue(say with setImmediate
). This additional task will process all stacked changes and run rerender just once.
Even if you would be so fast to click Submit button before those deferred updater is executed event handler would go to the end of queue. So event handler will definitely run after all batched state's changes are applied.
Sorry, I cannot just refer to React code to prove because updater code looks really complex for me. But I found article that has many details how it works under the hood. Maybe it gives some additional information to you.
[UPD] met nice article on microtasks, macrotasks and event loop: https://abc.danch.me/microtasks-macrotasks-more-on-the-event-loop-881557d7af6f?gi=599c66cc504c
it does not change the result but makes me understand all that better
It became more clear to me, but not crystal yet. Do you say that React queues setState calls to some internal JS query that is guaranteed to be processed in between handling events?
– Denis Kulagin
Nov 18 '18 at 14:11
after reviewing my own answer I see it looks overcomplicated. So I've updated answer with more details.
– skyboyer
Nov 18 '18 at 20:03
Your and Karen answers are both great and I was having a hard time deciding whom to award the bounty. I have accepted Karen's answer for being more concise. But bounty goes to your answer as being much more detailed and containing useful references to investigate this issue in depth.
– Denis Kulagin
Nov 21 '18 at 8:05
found good article on microtask/macrotask/event loop: abc.danch.me/…
– skyboyer
Nov 29 '18 at 22:19
add a comment |
In your case reading old value is impossible. Under "It may batch or defer the update until later" it means just a case
this.setState({a: 11});
console.log(this.state.a);
so setState
may just add a change to queue but not directly update this.state
. But it does not mean you can just change input with triggering handleChange
and then click button triggering handleSubmit
and .state
is still not updated. It because how event loop works - if some code is executing browser will not process any event(you should experience cases when UI freezes for a while).
So the only thing to reproduce 'race condition' is to run one handler from another:
handleChange(event) {
this.setState({value: event.target.value});
this.handleSubmit();
}
This way, yes, you will get previous value
shown in alert.
For such a cases .setState
takes optional callback parameter
The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead.
Applied to your code it'd look like
handleChange(event) {
this.setState({value: event.target.value}, this.handleSubmit);
}
PS And sure your code may delay setState
with setTimeout
on your own like
handleChange({target: {value}}) {
setTimeout(() => {
this.setState({value});
}, 5000);
}
And there is no way to ensure handleSubmit
is operating on latest value. But in such a case it's all on your shoulders how to handle that.
[UPD] some details on how async works in JS. I have heard different terms: "event loop", "message queue", "microtask/task queue" and sometimes it means different things(and there is a difference actually). But to make things easier let's assume there is just single queue. And everything async like event handlers, Promise.then()
, setImmediate()
just go to the end of this queue.
This way each setState
(if it's in batch mode) does 2 things: adds changeset to stack(it could be array variable) and set up additional task into queue(say with setImmediate
). This additional task will process all stacked changes and run rerender just once.
Even if you would be so fast to click Submit button before those deferred updater is executed event handler would go to the end of queue. So event handler will definitely run after all batched state's changes are applied.
Sorry, I cannot just refer to React code to prove because updater code looks really complex for me. But I found article that has many details how it works under the hood. Maybe it gives some additional information to you.
[UPD] met nice article on microtasks, macrotasks and event loop: https://abc.danch.me/microtasks-macrotasks-more-on-the-event-loop-881557d7af6f?gi=599c66cc504c
it does not change the result but makes me understand all that better
It became more clear to me, but not crystal yet. Do you say that React queues setState calls to some internal JS query that is guaranteed to be processed in between handling events?
– Denis Kulagin
Nov 18 '18 at 14:11
after reviewing my own answer I see it looks overcomplicated. So I've updated answer with more details.
– skyboyer
Nov 18 '18 at 20:03
Your and Karen answers are both great and I was having a hard time deciding whom to award the bounty. I have accepted Karen's answer for being more concise. But bounty goes to your answer as being much more detailed and containing useful references to investigate this issue in depth.
– Denis Kulagin
Nov 21 '18 at 8:05
found good article on microtask/macrotask/event loop: abc.danch.me/…
– skyboyer
Nov 29 '18 at 22:19
add a comment |
In your case reading old value is impossible. Under "It may batch or defer the update until later" it means just a case
this.setState({a: 11});
console.log(this.state.a);
so setState
may just add a change to queue but not directly update this.state
. But it does not mean you can just change input with triggering handleChange
and then click button triggering handleSubmit
and .state
is still not updated. It because how event loop works - if some code is executing browser will not process any event(you should experience cases when UI freezes for a while).
So the only thing to reproduce 'race condition' is to run one handler from another:
handleChange(event) {
this.setState({value: event.target.value});
this.handleSubmit();
}
This way, yes, you will get previous value
shown in alert.
For such a cases .setState
takes optional callback parameter
The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead.
Applied to your code it'd look like
handleChange(event) {
this.setState({value: event.target.value}, this.handleSubmit);
}
PS And sure your code may delay setState
with setTimeout
on your own like
handleChange({target: {value}}) {
setTimeout(() => {
this.setState({value});
}, 5000);
}
And there is no way to ensure handleSubmit
is operating on latest value. But in such a case it's all on your shoulders how to handle that.
[UPD] some details on how async works in JS. I have heard different terms: "event loop", "message queue", "microtask/task queue" and sometimes it means different things(and there is a difference actually). But to make things easier let's assume there is just single queue. And everything async like event handlers, Promise.then()
, setImmediate()
just go to the end of this queue.
This way each setState
(if it's in batch mode) does 2 things: adds changeset to stack(it could be array variable) and set up additional task into queue(say with setImmediate
). This additional task will process all stacked changes and run rerender just once.
Even if you would be so fast to click Submit button before those deferred updater is executed event handler would go to the end of queue. So event handler will definitely run after all batched state's changes are applied.
Sorry, I cannot just refer to React code to prove because updater code looks really complex for me. But I found article that has many details how it works under the hood. Maybe it gives some additional information to you.
[UPD] met nice article on microtasks, macrotasks and event loop: https://abc.danch.me/microtasks-macrotasks-more-on-the-event-loop-881557d7af6f?gi=599c66cc504c
it does not change the result but makes me understand all that better
In your case reading old value is impossible. Under "It may batch or defer the update until later" it means just a case
this.setState({a: 11});
console.log(this.state.a);
so setState
may just add a change to queue but not directly update this.state
. But it does not mean you can just change input with triggering handleChange
and then click button triggering handleSubmit
and .state
is still not updated. It because how event loop works - if some code is executing browser will not process any event(you should experience cases when UI freezes for a while).
So the only thing to reproduce 'race condition' is to run one handler from another:
handleChange(event) {
this.setState({value: event.target.value});
this.handleSubmit();
}
This way, yes, you will get previous value
shown in alert.
For such a cases .setState
takes optional callback parameter
The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead.
Applied to your code it'd look like
handleChange(event) {
this.setState({value: event.target.value}, this.handleSubmit);
}
PS And sure your code may delay setState
with setTimeout
on your own like
handleChange({target: {value}}) {
setTimeout(() => {
this.setState({value});
}, 5000);
}
And there is no way to ensure handleSubmit
is operating on latest value. But in such a case it's all on your shoulders how to handle that.
[UPD] some details on how async works in JS. I have heard different terms: "event loop", "message queue", "microtask/task queue" and sometimes it means different things(and there is a difference actually). But to make things easier let's assume there is just single queue. And everything async like event handlers, Promise.then()
, setImmediate()
just go to the end of this queue.
This way each setState
(if it's in batch mode) does 2 things: adds changeset to stack(it could be array variable) and set up additional task into queue(say with setImmediate
). This additional task will process all stacked changes and run rerender just once.
Even if you would be so fast to click Submit button before those deferred updater is executed event handler would go to the end of queue. So event handler will definitely run after all batched state's changes are applied.
Sorry, I cannot just refer to React code to prove because updater code looks really complex for me. But I found article that has many details how it works under the hood. Maybe it gives some additional information to you.
[UPD] met nice article on microtasks, macrotasks and event loop: https://abc.danch.me/microtasks-macrotasks-more-on-the-event-loop-881557d7af6f?gi=599c66cc504c
it does not change the result but makes me understand all that better
edited Nov 29 '18 at 22:19
answered Nov 18 '18 at 9:00
skyboyerskyboyer
3,98811230
3,98811230
It became more clear to me, but not crystal yet. Do you say that React queues setState calls to some internal JS query that is guaranteed to be processed in between handling events?
– Denis Kulagin
Nov 18 '18 at 14:11
after reviewing my own answer I see it looks overcomplicated. So I've updated answer with more details.
– skyboyer
Nov 18 '18 at 20:03
Your and Karen answers are both great and I was having a hard time deciding whom to award the bounty. I have accepted Karen's answer for being more concise. But bounty goes to your answer as being much more detailed and containing useful references to investigate this issue in depth.
– Denis Kulagin
Nov 21 '18 at 8:05
found good article on microtask/macrotask/event loop: abc.danch.me/…
– skyboyer
Nov 29 '18 at 22:19
add a comment |
It became more clear to me, but not crystal yet. Do you say that React queues setState calls to some internal JS query that is guaranteed to be processed in between handling events?
– Denis Kulagin
Nov 18 '18 at 14:11
after reviewing my own answer I see it looks overcomplicated. So I've updated answer with more details.
– skyboyer
Nov 18 '18 at 20:03
Your and Karen answers are both great and I was having a hard time deciding whom to award the bounty. I have accepted Karen's answer for being more concise. But bounty goes to your answer as being much more detailed and containing useful references to investigate this issue in depth.
– Denis Kulagin
Nov 21 '18 at 8:05
found good article on microtask/macrotask/event loop: abc.danch.me/…
– skyboyer
Nov 29 '18 at 22:19
It became more clear to me, but not crystal yet. Do you say that React queues setState calls to some internal JS query that is guaranteed to be processed in between handling events?
– Denis Kulagin
Nov 18 '18 at 14:11
It became more clear to me, but not crystal yet. Do you say that React queues setState calls to some internal JS query that is guaranteed to be processed in between handling events?
– Denis Kulagin
Nov 18 '18 at 14:11
after reviewing my own answer I see it looks overcomplicated. So I've updated answer with more details.
– skyboyer
Nov 18 '18 at 20:03
after reviewing my own answer I see it looks overcomplicated. So I've updated answer with more details.
– skyboyer
Nov 18 '18 at 20:03
Your and Karen answers are both great and I was having a hard time deciding whom to award the bounty. I have accepted Karen's answer for being more concise. But bounty goes to your answer as being much more detailed and containing useful references to investigate this issue in depth.
– Denis Kulagin
Nov 21 '18 at 8:05
Your and Karen answers are both great and I was having a hard time deciding whom to award the bounty. I have accepted Karen's answer for being more concise. But bounty goes to your answer as being much more detailed and containing useful references to investigate this issue in depth.
– Denis Kulagin
Nov 21 '18 at 8:05
found good article on microtask/macrotask/event loop: abc.danch.me/…
– skyboyer
Nov 29 '18 at 22:19
found good article on microtask/macrotask/event loop: abc.danch.me/…
– skyboyer
Nov 29 '18 at 22:19
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53316501%2freact-potential-race-condition-for-controlled-components%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown