1 | Composi
|
2 | =======
|
3 |
|
4 | Contents
|
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, Render and Unmount](./render.md)
|
12 | - [Components](./components.md)
|
13 | - [State](./state.md)
|
14 | - Lifecycle Methods
|
15 | - [Lifecycle Methods](#Lifecycle-Methods)
|
16 | - [Order of Execution](#Order-of-Execution)
|
17 | - [Lifecycle Method Use](#Lifecycle-Method-Use)
|
18 | - [Events](./events.md)
|
19 | - [Styles](./styles.md)
|
20 | - [Unmount](./unmount.md)
|
21 | - [State Management with DataStore](./data-store.md)
|
22 | - [Third Party Libraries](./third-party.md)
|
23 | - [Deployment](./deployment.md)
|
24 | - [Differrences with React](./composi-react.md)
|
25 |
|
26 | ## Lifecycle Methods
|
27 |
|
28 | Composi has the following five lifecycle methods:
|
29 |
|
30 | 1. componentWillMount
|
31 | 2. componentDidMount
|
32 | 3. componentWillUpdate
|
33 | 4. componentDidUpdate
|
34 | 5. componentWillUnmount
|
35 |
|
36 | Lifecycle methods let you implement maintenance and clean up code based on the status of a component from when it is created and injected into the DOM, when it is updated and when it is removed from the DOM. These do not work exactly the same as the React equivalents, so pay attention to the documentation for each one.
|
37 |
|
38 | `componentWillMount` is executed before the component is created and inserted into the DOM. This gets passed a `done` callback. This callback is required to complete the mounting. If you exclude `done` the component will never mount. Since mounting is triggered by an initial state value, you should never use this to set state. Instead use it to do some environmental setup before the component is mounted.
|
39 |
|
40 | ```javascript
|
41 | componentWillMount(done) {
|
42 | console.log('Mounting in 3 seconds.')
|
43 | // Do whatever you need to do before mounting...
|
44 | setTimeout(() => {
|
45 | console.log('We are now mounting!')
|
46 | // Don't forget to call done:
|
47 | done()
|
48 | }, 3000)
|
49 | }
|
50 | ```
|
51 |
|
52 | `componentDidMount` is executed after the component is inserted into the DOM. You can use it to attach events to component elements or to query the DOM of the newly mounted component. The base element of a mounted component is available through the component's `this.element` property. In the following example, notice how we set focus on a component's input:
|
53 |
|
54 | ```javascript
|
55 | componentDidMount() {
|
56 | // Access the component base element.
|
57 | // Use it to find its input and focus it.
|
58 | this.element.querySelector('input').focus()
|
59 | }
|
60 | ```
|
61 |
|
62 | `componentWillUpdate` is executed right before the component is updated. If a component is updated with the same data, then no update will occur, meaning this will not execute. Like `componentWillMount`, this gets passed a `done` callback. This callback is required to complete the update. If you exclude `done` the component will never update. You can use this hook to examine the component properties, such as `element`, `currentVNode`, `oldVnode`, etc. State changes always trigger updates. As such, the previous state is not available to the lifecycle hooks. However, you can check the `oldVnode` property on the component to see what the previous state produced. Because this is executed before the update, we cannot know what the next update will produce.
|
63 |
|
64 | Notice how in the following example we delay the update by three seconds:
|
65 |
|
66 | ```javascript
|
67 | componentWillUpdate(done) {
|
68 | console.log('Updating in 3 seconds.')
|
69 | setTimeout(() => {
|
70 | console.log('We are now updating!')
|
71 | // Don't forget to call done:
|
72 | done()
|
73 | }, 3000)
|
74 | }
|
75 | ```
|
76 |
|
77 | `componentDidUpdate` is executed immediately after the component was updated. If a component is updated with the same data, then no update will occur, meaning this will not execute. Note that if you both a `componentWillUpdate` and `componentDidUpdate` lifecycle hook, `componentDidUpdate` will execute only after the `done` callback in `componentWillUpdate`.
|
78 |
|
79 | `componentWillUnmount` is executed before a component is unmounted with its `unmount` method. This gets passed a `done` callback. This callback is required to complete the unmounting. If you exclude the `done` callback, unmounting will not occur. Notice in the following example how we delay the unmounting for 3 seconds in our unmount hook:
|
80 |
|
81 | ```javascript
|
82 | componentWillUnmount(done) {
|
83 | console.log('Unmounting in 3 seconds.')
|
84 | setTimeout(() => {
|
85 | console.log('We are now unmounting!')
|
86 | // Don't forget to call done:
|
87 | done()
|
88 | }, 3000)
|
89 | }
|
90 | ```
|
91 |
|
92 | ## Order of Execution
|
93 |
|
94 | The first time a component is rendered, `componentDidMount` and `componentWillMount` will be executed. `componentWillUpdate` and `componentWillUpdate` will not be executed at this time. After the component was created, each render will fire `componentWillUpdate` and `componentDidUpdate`. So, if you wanted to do something when the component is initially created and after it updates, you would need to do this:
|
95 |
|
96 | ```javascript
|
97 | class List extends Component {
|
98 | //... setup here.
|
99 | componentDidMount() {
|
100 | // Do stuff after component was created.
|
101 | }
|
102 | componentDidUpdate() {
|
103 | // Do stuff every time component is updated.
|
104 | }
|
105 | }
|
106 | ```
|
107 |
|
108 | ## Lifecycle Method Use
|
109 |
|
110 | When we create a new component by extending the Component class, we can access component properties directly through the `this` keyword. This is so because we define the lifecycle methods as class methods. Notice how we do this in the example below.
|
111 |
|
112 | ```javascript
|
113 | import {h, Component} from 'composi'
|
114 |
|
115 | class Clock extends Component {
|
116 | constructor(props) {
|
117 | super(props)
|
118 | this.root = '#clock'
|
119 | this.state = {date: new Date()};
|
120 | }
|
121 |
|
122 | render() {
|
123 | return (
|
124 | <div>
|
125 | <h2>Current Time</h2>
|
126 | <h2>It is {this.getLocalTime()}.</h2>
|
127 | </div>
|
128 | )
|
129 | }
|
130 |
|
131 | getLocalTime() {
|
132 | return this.state.date.toLocaleTimeString()
|
133 | }
|
134 |
|
135 | componentDidMount() {
|
136 | // Store timer referrence so we can clear it later:
|
137 | this.timerID = setInterval(
|
138 | () => this.tick(),
|
139 | 1000
|
140 | );
|
141 | }
|
142 |
|
143 | // If component is unmounted, end interval loop:
|
144 | componentWillUnmount(done) {
|
145 | clearInterval(this.timerID)
|
146 | done()
|
147 | }
|
148 |
|
149 | tick() {
|
150 | this.setState({
|
151 | time: new Date()
|
152 | });
|
153 | }
|
154 | }
|
155 |
|
156 | // Instantiated clock will create and start it:
|
157 | const clock = new Clock()
|
158 | ```
|