react: Chrome 56 breaks touch events
Do you want to request a feature or report a bug? Bug
What is the current behavior?
React attaches events to the document node which causes the latest version of Chrome to issue the following warning.
Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080
It appears that Chrome now treats all document level touch events as passive.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template: https://jsfiddle.net/reactjs/69z2wepo/).
class App extends Component {
  render() {
    return (
      <div
          className="box"
          onTouchStart={e=>{e.preventDefault()}}
          onTouchMove={e=>{e.preventDefault()}}
      >
          Drag Me
      </div>
    );
  }
}
What is the expected behavior?
preventDefault should be allowed, which means React should pass { passive: false } when adding event listeners.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React? React 15.4.1, Chrome 56.0.2924.87, Windows 10
About this issue
- Original URL
 - State: closed
 - Created 7 years ago
 - Reactions: 45
 - Comments: 17 (2 by maintainers)
 
Commits related to this issue
- Use { passive: false } in addEventListener to allow for preventDefault Fixes #23. No functional change. https://developers.google.com/web/updates/2017/01/scrolling-intervention As of today, this has ... — committed to strateos/react-map-interaction by scottyantipa 5 years ago
 - Use { passive: false } in addEventListener to allow for preventDefault Fixes #23. No functional change. https://developers.google.com/web/updates/2017/01/scrolling-intervention As of today, this has ... — committed to strateos/react-map-interaction by scottyantipa 5 years ago
 - Use { passive: false } in addEventListener to allow for preventDefault Fixes #23. No functional change. https://developers.google.com/web/updates/2017/01/scrolling-intervention As of today, this has ... — committed to strateos/react-map-interaction by scottyantipa 5 years ago
 - Use { passive: false } in addEventListener to allow for preventDefault Fixes #23. No functional change. https://developers.google.com/web/updates/2017/01/scrolling-intervention As of today, this has ... — committed to strateos/react-map-interaction by scottyantipa 5 years ago
 - Use { passive: false } in addEventListener to allow for preventDefault Fixes #23. No functional change. https://developers.google.com/web/updates/2017/01/scrolling-intervention As of today, this has ... — committed to strateos/react-map-interaction by scottyantipa 5 years ago
 - Use { passive: false } in addEventListener to allow for preventDefault (#26) Fixes #23. No functional change. https://developers.google.com/web/updates/2017/01/scrolling-intervention As of today, t... — committed to strateos/react-map-interaction by scottyantipa 5 years ago
 
Ok. This will be interesting to deal with. If Chrome makes a breaking change, does that mean libraries should respond by unbreaking it? Effectively undoing the purpose.
Now this whole thing will be complicated further by the fact that React Fiber is a whole shift to be able to write 60fps apps with active event listeners. In that world defaulting to active makes more sense.
On the flip side we’re not quite there yet in the ecosystem and there is some action from apps to be able to make that palatable.
This will need some careful consideration to make the right choices for defaults.
@oliviertassinari Manually attaching listeners seems wrong. I think this should be fixed in React.
No, it wasn’t.
Rather than set passive:false, it’s much better to apply the appropriate touch-action to disable scrolling where desired. See here.
I would link that issue with #6436.
@mstijak If you are looking for a workaround. You can manually use the
addEventListenerandremoveEventListenerDOM API with the right option.Yes, we’ve accidentally “fixed” this with that change in one of the RCs, but in the 17 we’re explicily making
onWheel,onTouchStart, andonTouchMovepassive to align with the browser behavior. Since this change has improved the scrolling performance on the web overall, we don’t think it would be productive to “undo” the fix — as it’s still likely going to lead to performance problems. For now, you can keep using refs +addEventListeneras a workaround if you need active event listeners.Relevant Chromium issue for context: https://bugs.chromium.org/p/chromium/issues/detail?id=639227
@mstijak mouse and touch are orthogonal here. You can/should still call
preventDefault, just also settouch-actionto indicate declaratively what touch gestures you want disabled.@sebmarkbage it can, in at least the same scenarios you can disable scrolling via TouchEvent.preventDefault in Safari. I.e. once scrolling has started you can’t change it. You may want to set
pan-upwhen at the bottom.