Imperative API for installing DOM event handlers
See original GitHub issueCurrently React allows installing event handler on DOM events only in declarative fashion, via component attributes at the time of a component instantiation.
I think this is nice and allows automatically uninstall such handlers in case of a component disposal. But for implementing some “low-level” machinery I think it would be useful to allow handlers to be installed after the component instantiation at arbitrary moments. That would allow installing an event handler in a mixin’s componentDidMount
(with a corresponding uninstall of such event handler in componentWillUnmount
) callback.
For example currently I use jQuery for trapping clicks on anchors and invoking HTML5 pushState API instead of letting a browser to reload a page:
...
componentDidMount: function() {
$(this.getDOMNode()).on('click.react-route', 'a', function(e) {
e.preventDefault();
// invoke HTML5 pushState API
});
},
componentWillUnmount: function() {
$(this.getDOMNode()).off('click.react-route');
}
...
The problem with that is I’m not able to use goodies provided by React’s event plugins. So what I want instead is to handle click events with React’s event system and install such handler in componentDidMount
callback so I can extract such functionality into a mixin. Something like:
...
handleClick: function(e) {
// check if event's target is an anchor and invoke pushState API
},
componentDidMount: function() {
this.addEventListener(eventTypes.onClick, this.handleClick);
},
componentWillUnmount: function() {
this.removeEventListener(eventTypes.onClick, this.handleClick);
}
...
Though maybe addEventListener
and removeEventListener
names are to verbose…
Other examples include handling focus/blur and arrow key clicks to control focus inside a component, …
Issue Analytics
- State:
- Created 10 years ago
- Reactions:7
- Comments:9 (5 by maintainers)
This would be a great addition.
For example, if I want to handle triple click in a generic way, I have to wrap a component in another wrapper that would also output another element, like this
<div>
:I don’t want to use
React.cloneElement(React.Children.only(this.props.children))
and inject a newonClick
to props, because contained component might already have that event.Currently the only solution to bind new events without a new element and without altering the nested component is by using regular DOM events, which, as stated by @andreypopp, doesn’t have all the goodies of React event system, something like that:
I’d imagine it as:
Seems like this use case is very niche.
As noted above, a separate imperative API is unlikely. It seems like an intermediate component is the best solution for this use case.
The problems mentioned by @felipeochoa don’t seem related to this thread, so let’s track them in https://github.com/facebook/react/issues/285.