Skip to content

Receive outside events, without leaving React's system #7795

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
philipp-spiess opened this issue Sep 22, 2016 · 1 comment
Closed

Receive outside events, without leaving React's system #7795

philipp-spiess opened this issue Sep 22, 2016 · 1 comment

Comments

@philipp-spiess
Copy link
Contributor

This is a feature request.

Right now, the only way to respond to "outside world" events is to leave the React's event system and add a native DOM listener. This is bad, since it will require more mental overhead when you have to work with this (you need to think about your event listener receiving a native event, or a react synthetic event). It will also simply not be possible for computed SyntheticEvents (e.g. onChange).

It also makes it very hard for react events handlers to interrupt the DOM handlers. Consider the following example, where it's not intuitive why the React listener can not stop propagation to the document. (Spoiler: React also listens on document, that's why you'd have to use SyntheticEvent#nativeEvent.stopImmediatePropagation():

var Example = React.createClass({
  render: function (){
    return (
      <div onKeyDown={function(e) { e.stopPropagation() }} />
    );
  }
});

document.addEventListener("keydown", function () {
  alert('why does this still fire?');
});

ReactDOM.render(
  <Example name="react"/>,
  document.getElementById('react')
);

An example for when you want to deal with outside events is a simple drawing tool, that must listen on keyup to stop the drawing process.

To solve this problem, I propose a new public API, something like an EventRoot. It should behave like a regular DOM Node, so that you can addEventListener() and removeEventListener(), but it's callbacks will receive the SyntheticEvent. It will get called when triggering a two phase dispatch. It respects the capture and bubble order as well as stopPropagation(). Everything you'd expect when listening on document.

For the above example, you'd only have to replace document with the new event root. The stopPropagation() can now correctly be applied.

@aweary
Copy link
Contributor

aweary commented Sep 22, 2016

Thanks for the writeup @philipp-spiess, I agree that there may be some utility in providing such an API. We've had discussion about this in the past, see #285. Would you mind posting there instead?

I'm going to close this so we don't fragment the discussion, but I encourage you to check out #285 and post your proposal there!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants