UNPKG

5.22 kBMarkdownView Raw
1Composi
2=======
3
4Contents
5--------
6- [Installation](../README.md)
7- [JSX](./jsx.md)
8- [Hyperx](./hyperx.md)
9- [Hyperscript](./hyperscript.md)
10- [Functional Components](./functional-components.md)
11- [Mount and Render](./render.md)
12- [Components](./components.md)
13- [State](./state.md)
14- [Lifecycle Methods](./lifecycle.md)
15- [Events](./events.md)
16- [Styles](./styles.md)
17- Unmount
18- [Third Party Libraries](./third-party.md)
19- [Deployment](./deployment.md)
20
21Unmount
22-------
23
24Components have an `unmount` method. This allows you to destroy a component instance. This does several things.
25
261. If the component has a `componentWillUnmount` method, it fires this first. Please note that `componentWillUnmount` will be asynchronous. It could take longer to execute than the actual unmounting of the component.
272. It deletes the component from the DOM. It does this based on the base element you used to define your component. This is the same node prepresented by the component's `this.element` value.
283. It nulls out the properties of the component instance for garbage collection.
29
30As you may have noticed, there is nothing here to remove any events. Inline events don't need to be removed. They're just properties, afterall. If you've used the `handleEvent` interface, then you'll need to remove the event yourself. You'll need to do this before unmounting the component. Since we use a component's `element` property to bind events, this is easy. Just execute `removeEventListener` on it and pass in the `handleEvent` object.
31
32Removing Event from Component Instance
33--------------------------------------
34
35```javascript
36import {h, Component} from 'composi'
37
38export const list = new Component({
39 container: 'section',
40 render: (fruits) => (
41 <ul>
42 {
43 fruits.map(fruit => <li>{fruit}</li>)
44 }
45 </ul>
46 ),
47 // Pass in component instance so we can bind event listener:
48 componentWasCreated() {
49 list.element.addEventListener('click', eventObj)
50 }
51})
52
53// Define eventHandler object:
54const eventObj = {
55 handleEvent(e) {
56 eventObj.announceItem(e)
57 },
58 announceItem(e) {
59 alert(e.target.textContent)
60 }
61}
62
63```
64
65To remove the above event before unmounting, we would need to do this:
66
67```javascript
68// Remove event from component, passing in handleEvent object:
69list.element.removeEventListener('click', eventObj)
70
71// Then we can unmount the component:
72list.unmount()
73```
74
75
76Removing Event from Extended Component
77--------------------------------------
78
79```javascript
80import {h, Component} from 'composi'
81
82export class List extends Component {
83 constructor(props) {
84 super(props)
85 this.container = 'section'
86 }
87 handleEvent(e) {
88 if (e.target.nodeName === 'LI') {
89 alert(e.target.textContent.trim())
90 } else if (e.target.id === 'add-item') {
91 this.componentShouldUpdate = true
92 const input = this.element.querySelector('input')
93 const value = input.value
94 if (value) {
95 let state = this.state
96 state.unshift({id: String(uuid()), name: value, checked: false})
97 this.state = state
98 input.value = ''
99 }
100 } else if (e.target.type === 'checkbox') {
101 this.componentShouldUpdate = false
102 const id = e.target.closest('li').dataset.id
103 let state = this.state
104 const index = state.findIndex(item => id === item.id)
105 console.log(`The index is: ${index}`)
106 state[index].checked = !state[index].checked
107 this.state = state
108 /**
109 * Remove all events from this component and unmount it!
110 */
111 } else if (e.target.id === 'unmount') {
112 // Unbind event by passing in "this" as reference:
113 this.element.removeEventListener('click', this)
114 // Unmount the component:
115 this.unmount()
116 }
117 }
118 componentWasCreated() {
119 this.element.addEventListener('click', this)
120 }
121 render(data) {
122 return (
123 <div>
124 <p><button id='unmount'>Unmount Component</button></p>
125 <p>
126 <input type="text"/>
127 <button id='add-item'>Add Item</button>
128 </p>
129 <ul class='list'>
130 {
131 data.map(item => <li key={item.id} data-id={item.id}><input type="checkbox" checked={item.checked}/> {item.name}</li>)
132 }
133 </ul>
134 </div>
135 )
136 }
137}
138```
139
140In the above example, we really only have one event registered that we are using for all the interactions on this component. This is called event delegation. The `handleEvent` interface makes this easy. Unbinding this event is also easy. Notice in the code slice from the above example how we execute the `removeEventListener` method on the component's `element` property. Then we pass in the 'click' event type. For a reference to the `handleEvent` interface we just pass in `this`. When we set up the event, we did the same.
141```javascript
142// Setup event:
143this.element.addEventListener('click', this)
144
145// Remove event:
146this.element.removeEventListener('click', this)
147```
148After removing the event, we can unmount it:
149
150```javascript
151this.unmount()
152```
153
154Using the `handleEvent` interface when extending the Component class gives us more power and easier to manage events, both adding and removing. Read the documentation for [events](events.md) for more details.
\No newline at end of file