Deprecated
Issues mentioned in README
should be solved by other approaches:
.addEventListener()
is blazing fast and is not a real performance issue- to solve issues with ordering in case when regular DOM event propogation is not available consider to use things like https://github.com/palmerhq/react-register-nodes.
Please avoid usages of this library.
Event Stack
A React component for binding events on the global scope.
Installation
yarn add @semantic-ui-react/event-stack
# or
npm install @semantic-ui-react/event-stack
Why?
The EventStack
solves two design problems:
- Reduces the number of connected listeners to DOM nodes compared to
element.addListener()
. - Respects event ordering. Example, two modals are open and you only want the top modal to close on document click.
Usage
import React, { Component } from 'react'
import EventStack from '@semantic-ui-react/event-stack'
class MyComponent extends Component {
handleResize = () => {
console.log('resize')
}
render() {
return (
<div>
<EventStack name="resize" on={this.handleResize} target="window" />
</div>
)
}
}
Note on server-side rendering
When doing server side rendering, document and window aren't available. You can use a string as a target
, or check that they exist before rendering the component with exenv
, for example.
Note on performance
You should avoid passing inline functions for listeners, because this creates a new Function instance on every render, defeating EventListener
's shouldComponentUpdate
, and triggering an update cycle where it removes its old listeners and adds its new listeners (so that it can stay up-to-date with the props you passed in).
Implementation details
The EventStack
is a public API that allows subscribing a DOM node to events. The event subscription for each unique DOM node creates a new EventTarget
object.
+------------+ +-------------+
| | 0..* | |
| EventStack | +------> | EventTarget |
| | | |
+------------+ +-------------+
EventTarget
Each EventTarget
is assigned to an unique DOM node. An EventTarget
tracks event handlers for the target's DOM node. Making multiple subscriptions to a click
event for a single DOM node will result in a single registered handler
for that DOM node. An EventPool
also handles EventPool
relations, it stores only unique pools.
+-------------+ +---------+
| | 0..* | |
| EventTarget | +------> | handler |
| | | |
+-------------+ +---------+
+ +-----------+
| 0..* | |
+----------------> | EventPool |
| |
+-----------+
A handler
is a generated function that will notify the corresponding subscribed EventPool
.
EventPool & EventSet
An EventPool
notifies its EventSet
, while an EventSet
stores a set of subscribed event handlers. An EventSet
is also responsible for event ordering and dispatching to subscribed handlers.
+-----------+ +----------+
| | 1 | |
| EventPool | +---> | EventSet |
| | | |
+-----------+ +----------+
Credits
The idea of a React component is taken from react-event-listener
.