Right now you can only dispatch native events to the DOM nodes, but there's not any way to dispatch synthetic events on the Virtual DOM nodes.
I'd like to be able to dispatch synthetic events, in addition, I'd like a way to define custom event listeners.
For example, I've a component decorator that adds a resize
event on a DOM element when it get resized. I'd like to be able to dispatch the resize
event to such element and be able to listen to it using onResize
.
Example:
function DecoratedComponent(props) {
return <div onResize={evt => console.log('resized')}>foobar</div>;
}
resizeAware(DecoratedComponent);
For reference, this is the logic of my decorator that would dispatch the event.
https://gist.github.com/FezVrasta/0324991bbdf044fd2723eebbc344adff
As you see, right now I'm using findDOMNode(this.componentNode).dispatchEvent(new Event('resize'))
which makes the resize
event available only to the real DOM node.
This means that I must listen for the event in this way:
class DecoratedComponent extends React.Component {
componentDidMount() {
findDOMNode(this).addEventListener('resize', evt => console.log('resized'));
}
render() {
return <div>foobar</div>;
}
}
resizeAware(DecoratedComponent);
This is very inconvenient and not flexible. We'd need a way to dispatch synthetic events and be able to listen to them using the onSomething
properties.
I think it would be a great addition to React.
Incidentally, this might get solved by the "Custom Events" part of https://github.com/facebook/react/issues/2836, so this is a duplicate of that issue (to some extent).
This is also a partial duplicate of https://github.com/facebook/react/issues/3249
In general, however, augmenting primitive DOM nodes to add additional behaviors is a practice that we generally frown upon. It can cause confusion for people reading/maintaining your code because components (like div
) now behave differently from the expectation/documentation. It would be better practice for you to have your composite component take in a callback (eg. onResize
) and call that callback when the component is resized. That way, people are registering with your component/api, since your component is the one providing the event.
This is still the top hit on Google and neither of those tickets seem to address the original question.
How can we create custom synthetic events?
e.g. I want to replace an <input>
element with a custom <Input>
component without changing the API of onChange
. How would I create a synthetic change event object with the same structure?
It wouldn't be a problem for brand new components because I can define my own API (although sticking to a standard would still be preferable), but when trying to replace old components without breaking existing change handlers, this becomes tricky.
Same use-case here. I've got a ToggleButton component that works in the same way as a radio button. However, I'd like to create a new SyntheticEvent for the ToggleButton's onChange
prop so that the API between both these components is consistent.
Right now, the only way (as far as I know) to create a true SyntheticEvent is to let my ToggleButton render an additional radio button off-screen and trigger that to create and dispatch the events. Not exactly pretty.
Yeah this is a React bug, I think there is no problem to create synthetic event. Awaiting a fix from React devs
There is no bug being discussed here. To avoid further confusion I鈥檓 locking this issue.
If you experience a bug in React please file a new issue with a reproducing example. Thanks.
Most helpful comment
This is still the top hit on Google and neither of those tickets seem to address the original question.
How can we create custom synthetic events?
e.g. I want to replace an
<input>
element with a custom<Input>
component without changing the API ofonChange
. How would I create a synthetic change event object with the same structure?It wouldn't be a problem for brand new components because I can define my own API (although sticking to a standard would still be preferable), but when trying to replace old components without breaking existing change handlers, this becomes tricky.