1 | Composi
|
2 | =======
|
3 |
|
4 | Contents
|
5 | --------
|
6 | - [Components](./components.md)
|
7 | - [JSX](./jsx.md)
|
8 | - [Hyperx](./hyperx.md)
|
9 | - [Hyperscript](./hyperscript.md)
|
10 | - [Mount and Render](./render.md)
|
11 | - [State](./state.md)
|
12 | - Lifecycle Methods
|
13 | - [Events](./events.md)
|
14 | - [Styles](./styles.md)
|
15 | - [Unmount](./unmount.md)
|
16 | - [Installation](../README.md)
|
17 | - [Third Party Libraries](./third-party.md)
|
18 | - [Functional Components](./functional-components.md)
|
19 | - [Deployment](./deployment.md)
|
20 |
|
21 | Lifecycle Methods
|
22 | -----------------
|
23 |
|
24 | Composi has the following five lifecycle methods:
|
25 |
|
26 | 1. componentWillMount
|
27 | 2. ComponentDidMount
|
28 | 3. componentWillUpdate
|
29 | 4. componentDidUpdate
|
30 | 5. componentWillUnmount
|
31 |
|
32 | 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.
|
33 |
|
34 | `componentWillMount` is executed before the component is created and inserted into the DOM.
|
35 |
|
36 | `componentDidMount` is executed after the component is inserted into the DOM.
|
37 |
|
38 | `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.
|
39 |
|
40 | `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.
|
41 |
|
42 | `componentWillUnmount` is executed before a component is unmounted with its `unmount` method.
|
43 |
|
44 | Lifecycle Methods are Asynchronous
|
45 | ----------------------------------
|
46 | When using lifecycle methods, be aware that they are asynchronous. For example, with `componentWillMount` your component will probably be created and inserted into the DOM before your method can finish. Similarly, when using `componentWillUnmount`, the component will probably be unmounted and destroyed before your code in this method completes. If you want to handle these two in a synchronous manner for tighter control, you have two choices. Use a method that returns a promise, or use the [ES7 async functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/async_function). If your browser target includes IE9, you will need to polyfill promises for either of these to work.
|
47 |
|
48 | Order of Execution
|
49 | ------------------
|
50 | 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:
|
51 |
|
52 | ```javascript
|
53 | class List extends Component {
|
54 | //... setup here.
|
55 | componentDidMount() {
|
56 | // Do stuff after component was created.
|
57 | }
|
58 | componentDidUpdate() {
|
59 | // Do stuff every time component is updated.
|
60 | }
|
61 | }
|
62 | ```
|
63 |
|
64 | Lifecycle Methods with Component Instance
|
65 | -----------------------------------------
|
66 |
|
67 | In the following example we use `componentDidMount` to start a timer and `componentWillUnmount` to terminate the timer.
|
68 |
|
69 | In our first example of lifecycle methods, we'll use a Component instance. This poses several problems for the lifecycle methods. They do not have access to the component itself. This forces us to use global variables to pass things around.
|
70 |
|
71 | ```javascript
|
72 | import {h, Component} from 'composi'
|
73 |
|
74 | function tick() {
|
75 | clock.setState({
|
76 | time: new Date()
|
77 | });
|
78 | }
|
79 | let timerID
|
80 | const clock = new Component({
|
81 | root: '#clock',
|
82 | state: {time: new Date()},
|
83 | render: (date) => {
|
84 | return (
|
85 | <div>
|
86 | <h2>The Current Time</h2>
|
87 | <p>It is {date.time.toLocaleTimeString()}.</p>
|
88 | </div>
|
89 | )},
|
90 |
|
91 | componentDidMount() {
|
92 | timerID = setInterval(
|
93 | () => {
|
94 | tick()
|
95 | },
|
96 | 1000
|
97 | );
|
98 | },
|
99 |
|
100 | componentWillUnmount() {
|
101 | clearInterval(timerID);
|
102 | }
|
103 | })
|
104 |
|
105 | clock.update()
|
106 | ```
|
107 |
|
108 | Lifecycle Methods with Extended Component
|
109 | -----------------------------------------
|
110 |
|
111 | 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.
|
112 |
|
113 | ```javascript
|
114 | import {h, Component} from 'composi'
|
115 |
|
116 | class Clock extends Component {
|
117 | constructor(props) {
|
118 | super(props)
|
119 | this.root = '#clock'
|
120 | this.state = {date: new Date()};
|
121 | }
|
122 |
|
123 | render() {
|
124 | return (
|
125 | <div>
|
126 | <h2>Current Time</h2>
|
127 | <h2>It is {this.getLocalTime()}.</h2>
|
128 | </div>
|
129 | )
|
130 | }
|
131 |
|
132 | getLocalTime() {
|
133 | return this.state.date.toLocaleTimeString()
|
134 | }
|
135 |
|
136 | componentDidMount() {
|
137 | // Store timer referrence so we can clear it later:
|
138 | this.timerID = setInterval(
|
139 | () => this.tick(),
|
140 | 1000
|
141 | );
|
142 | }
|
143 |
|
144 | // If component is unmounted, end interval loop:
|
145 | componentWillUnmount() {
|
146 | clearInterval(this.timerID);
|
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 | ```
|