question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug: Bubbled onFocus handler that triggers an update prevents onChange handler in createRoot

See original GitHub issue

React version: I think any experimental version. Tested using:

  • 0.0.0-experimental-5faf377df and
  • 0.0.0-experimental-e5d06e34b at least.

Steps To Reproduce

  1. Open CodeSandbox: https://codesandbox.io/s/createroot-broken-focus-onchange-ysrut?file=/src/App.js
  2. Attempt to click on the label text for the checkbox in the createRoot section
  3. Notice that the checkbox won’t check - onChange isn’t called
  4. Attempt to click on the label text for the checkbox in the render section
  5. Notice that the checkbox will check - onChange is called

Link to code example: https://codesandbox.io/s/createroot-broken-focus-onchange-ysrut?file=/src/App.js

The current behavior

When rendering using createRoot:

  • onFocus is called
  • onChange is not called

When rendering using render:

  • onFocus is called
  • onChange is called

My coworker and I spent a bit of time debugging this, if we at all schedule the onFocus setState handler (using setTimeout, or requestAnimationFrame for example), then onChange is always called from the input.

e.g.

handleFocus = () => {
  setTimeout(() => this.setState({ isHovered: true }), 0)
  // or
  requestAnimationFrame(() => this.setState({ isHovered: true }))
}

Additionally, if the label is a sibling to the input:

return (
  <>
    <input id="id" onChange={} type="checkbox" checked={} />
    <label htmlFor="id" onFocus={}>
      label text
    </label>
  </>
)

then the onChange handler will be called as well (Note: onFocus won’t be called in this case because there isn’t a focusable element within it).

Also worth noting, re-implementing the checkbox component using hooks will still run into the same bug - no differences between using classes vs hooks.

The expected behavior

Calling setState in onFocus shouldn’t prevent onChange on a nested input element to be called. Both onFocus and onChange should be called.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

6reactions
gaearoncommented, Feb 10, 2021

This does not appear reproducible in a sandbox using the build from https://github.com/facebook/react/pull/20792. That PR enables some flags that aren’t enabled yet, but will be closer to the release. Essentially, they make discrete events (including checkbox clicks) flush in a microtask.

https://codesandbox.io/s/createroot-broken-focus-onchange-forked-9195f?file=/src/index.js

I think we can close this since it’s not directly actionable, but it will take some time before this behavior gets to an experimental build because we need to do more testing. Thanks for raising this!

4reactions
awearycommented, Apr 13, 2020

Thanks for the detailed bug report @hamlim. I verified the same behavior with the latest experimental release as well (0.0.0-experimental-e5d06e34b). You can temporarily get around this by flushing the state update in handleFocus synchronously using ReactDOM.flushSync

ReactDOM.flushSync(() => {
  this.setState({ isHovered: true })
})
Read more comments on GitHub >

github_iconTop Results From Across the Web

Documentation
Registers an error handler method that executes when child scope errors. Only the nearest scope error handlers execute. Rethrow to trigger up the...
Read more >
react-quill loses focus when onChange is called
The reason it's loses focus when keypress is probably because the quill component is recreating when rerendering.
Read more >
react-test-renderer
Design simple views for each state in your application, and React will efficiently update and render just the right components when your data...
Read more >
Handling Events in React js [Complete tutorial with examples]
This react js tutorial explains everything about Handling events in React js, how to handle onchange event in react, react event handler ......
Read more >
Events
The Before update event occurs before the control content changed by the user is written into the data source. The linked macro can,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found