1 | # Deprecated
|
2 |
|
3 | Issues mentioned in `README` should be solved by other approaches:
|
4 | - `.addEventListener()` is blazing fast and is not a real performance issue
|
5 | - 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.
|
6 |
|
7 | Please avoid usages of this library.
|
8 |
|
9 | ---
|
10 |
|
11 |
|
12 | <h1 align="center">Event Stack</h1>
|
13 |
|
14 |
|
15 | <p align="center">
|
16 | <a href="https://www.npmjs.com/package/@semantic-ui-react/event-stack">
|
17 | <img alt="npm" src="https://img.shields.io/npm/v/@semantic-ui-react/event-stack.svg?style=flat-square" />
|
18 | </a>
|
19 | <a href="https://circleci.com/gh/layershifter/event-stack">
|
20 | <img alt="Circle CI" src="https://img.shields.io/circleci/project/github/layershifter/event-stack/master.svg?logo=circleci&style=flat-square" />
|
21 | </a>
|
22 | <a href="https://ci.appveyor.com/project/layershifter/event-stack">
|
23 | <img alt="AppVeyor CI" src="https://img.shields.io/appveyor/ci/layershifter/event-stack/master.svg?logo=appveyor&style=flat-square" />
|
24 | </a>
|
25 | <a href="https://codecov.io/gh/layershifter/event-stack">
|
26 | <img alt="Codecov" src="https://img.shields.io/codecov/c/github/layershifter/event-stack/master.svg?style=flat-square" />
|
27 | </a>
|
28 | <a href="https://david-dm.org/layershifter/event-stack">
|
29 | <img alt="David" src="https://img.shields.io/david/layershifter/event-stack.svg?style=flat-square" />
|
30 | </a>
|
31 |
|
32 | <img src="http://img.badgesize.io/https://unpkg.com/@semantic-ui-react/event-stack/lib/cjs/event-stack.production.js?compression=gzip&label=gzip%20size&style=flat-square">
|
33 | </p>
|
34 |
|
35 | > A React component for binding events on the global scope.
|
36 |
|
37 | ## Installation
|
38 |
|
39 | ```bash
|
40 | yarn add @semantic-ui-react/event-stack
|
41 | # or
|
42 | npm install @semantic-ui-react/event-stack
|
43 | ```
|
44 |
|
45 | ## Why?
|
46 |
|
47 | The `EventStack` solves two design problems:
|
48 |
|
49 | 1. Reduces the number of connected listeners to DOM nodes compared to `element.addListener()`.
|
50 | 2. Respects event ordering. Example, two modals are open and you only want the top modal to close on document click.
|
51 |
|
52 | ## Usage
|
53 |
|
54 | ```jsx
|
55 | import React, { Component } from 'react'
|
56 | import EventStack from '@semantic-ui-react/event-stack'
|
57 |
|
58 | class MyComponent extends Component {
|
59 | handleResize = () => {
|
60 | console.log('resize')
|
61 | }
|
62 |
|
63 | render() {
|
64 | return (
|
65 | <div>
|
66 | <EventStack name="resize" on={this.handleResize} target="window" />
|
67 | </div>
|
68 | )
|
69 | }
|
70 | }
|
71 | ```
|
72 |
|
73 | ##### Note on server-side rendering
|
74 |
|
75 | 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`](https://github.com/JedWatson/exenv), for example.
|
76 |
|
77 | ##### Note on performance
|
78 |
|
79 | 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).
|
80 |
|
81 | ## Implementation details
|
82 |
|
83 | The `EventStack` is a public API that allows subscribing a DOM node to events. The event subscription for
|
84 | each unique DOM node creates a new `EventTarget` object.
|
85 |
|
86 | ```
|
87 | +------------+ +-------------+
|
88 | | | 0..* | |
|
89 | | EventStack | +------> | EventTarget |
|
90 | | | | |
|
91 | +------------+ +-------------+
|
92 | ```
|
93 |
|
94 | ## EventTarget
|
95 |
|
96 | Each `EventTarget` is assigned to an unique DOM node. An `EventTarget` tracks event handlers for
|
97 | the target's DOM node. Making multiple subscriptions to a `click` event for a single DOM node will
|
98 | result in a single registered `handler` for that DOM node. An `EventPool` also handles `EventPool`
|
99 | relations, it stores only unique pools.
|
100 |
|
101 | ```
|
102 | +-------------+ +---------+
|
103 | | | 0..* | |
|
104 | | EventTarget | +------> | handler |
|
105 | | | | |
|
106 | +-------------+ +---------+
|
107 |
|
108 | + +-----------+
|
109 | | 0..* | |
|
110 | +----------------> | EventPool |
|
111 | | |
|
112 | +-----------+
|
113 | ```
|
114 |
|
115 | A `handler` is a generated function that will notify the corresponding subscribed `EventPool`.
|
116 |
|
117 | ## EventPool & EventSet
|
118 |
|
119 | An `EventPool` notifies its `EventSet`, while an `EventSet` stores a set of subscribed
|
120 | event handlers. An `EventSet` is also responsible for event ordering and dispatching to
|
121 | subscribed handlers.
|
122 |
|
123 | ```
|
124 | +-----------+ +----------+
|
125 | | | 1 | |
|
126 | | EventPool | +---> | EventSet |
|
127 | | | | |
|
128 | +-----------+ +----------+
|
129 | ```
|
130 |
|
131 | #### Credits
|
132 |
|
133 | The idea of a React component is taken from [`react-event-listener`](https://www.npmjs.com/package/react-event-listener).
|