UNPKG

7.85 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, Render and Unmount
12 - [mount](#mount)
13 - [Reusing a Mount to Update Later](#Reusing-a-Mount-to-Update-Later)
14 - [Hydration](#Hydration)
15 - [render](#render)
16 - [How to Use Render](#How-to-Use-Render)
17 - [Unmount](#unmount)
18 - [Remount an Unmounted Functional Component](#Remount-an-Unmounted-Functional-Component)
19 - [Summary](#Summary)
20- [Components](./components.md)
21- [State](./state.md)
22- [Lifecycle Methods](./lifecycle.md)
23- [Events](./events.md)
24- [Styles](./styles.md)
25- [Unmount](./unmount.md)
26- [State Management with DataStore](./data-store.md)
27- [Third Party Libraries](./third-party.md)
28- [Deployment](./deployment.md)
29- [Differrences with React](./composi-react.md)
30
31## mount
32
33This function is used to inject a function component into the DOM. It takes two arguments: the tag to convert to nodes and the element in which to inject the tag. The container can be indicated with a valid CSS selector, or an actualy DOM node. The `mount` function always returns a reference to the element injected into the DOM. You can use this as an argument to the `render` function so that it can update the already mounted component.
34
35
36Here is an example of using `mount`:
37
38```javascript
39import {h, mount} from 'composi'
40
41// Define a functional component:
42function Header({message}) {
43 return (
44 <nav>
45 <h1>{message}</h1>
46 </nav>
47 )
48}
49
50// Mount the functional component in the document's header element:
51mount(<Header message="Hello, World!" />, "header")
52```
53
54## Reusing a Mount to Update Later
55
56The `mount` function returns a virtual node representing the current state of the functional component. You can capture that virtual node in a variable and pass it to the [render](#render) function to update it.
57
58## Hydration
59
60
61You can hydrate content rendered service-side, embuing it with Composi functionality. To do so, just provide a third argument to the `mount` function for the element in the DOM you wish to hydrate. This must be a node reference or a valid selector. Be aware that a selector should indicate a unique element in the document, otherwise it will choose the first occurence in the document.
62
63Hydration creates a virtual node from the target element and uses this to patch the DOM with the functional component. This allows Composi to add events and dynamic functionality to server-rendered DOM elements.
64
65Suppose we had a list rendered on the server like this:
66
67```html
68<ul class='list'>
69 <li>Apples</li>
70 <li>Oranges</li>
71</ul>
72```
73And when it loads we want to update it as a component. We'll define the component and then mount it while also passing a reference to this list:
74
75```javascript import { h, mount } from 'composi'
76function List(props) {
77 return (
78 <ul class='list'>
79 {
80 props.data.map(item => <li key={item.key}>{item.value}</li>)
81 }
82 </ul>
83 )
84}
85// We pass a third argument with a selector for the server-renered list:
86mount(<List data={fruits}/> 'section', './list')
87```
88
89
90## render
91
92Functional components let you create components that are simple yet powerful. The `mount` function makes it easy to inject them into the DOM. But many times you may need to update the component when props or data change. For that you use the `render` function. To use it, you will need to import it into your code:
93
94```javascript
95import {h, mount, render} from 'composi'
96
97```
98`render` takes three parameters:
99
1001. vnode - the vnode returned by the mount function
1012. tag - the element to create and insert into the DOM
1023. container - the element in which the component is mounted
103
104When rendering a functional component, always capture the latest vnode node in the varable you used when you mounted it. This gets passed as the first argument, followed by the tag to use to update the component. Although the tag might look exactly like the tag you used to mount, the values of its props can be different depending on events or interactions with the component. Please note that because the component reference from mounting will get reassigned with each render, you must use `let`, not `const` or you will get an error.
105
106
107## How to Use Render
108
109```javascript
110import {h, mount, render} from 'composi'
111
112const fruits = ['Apples', 'Oranges', 'Bananas']
113
114// Define function that returns JSX:
115function createList({fruits}) {
116 return (
117 <div>
118 <p>
119 <input type='text'/>
120 <button>Add</button>
121 </p>
122 <ul>
123 {
124 fruits.map(fruit => <li>{fruit}</li>)
125 }
126 </ul>
127 </div>
128 )
129}
130
131// Insert the list into the document body:
132const list = mount(<List fruits={fruits}/>, 'body')
133
134// Define event object:
135const listEvents = {
136 // Define event handler:
137 handleEvent(e) {
138 e.target.nodeName === 'BUTTON' && this.addItem()
139 },
140 // Store reference to form input:
141 input : document.querySelector('input')
142 // Define method to add item and update list:
143 addItem() {
144 const value = this.document.value
145 if (value) {
146 fruits.push(value)
147 // Update the list component with "render".
148 // Capture the latest vnode version of the component in the variable used to mount.
149 // This will get passed in on the next render.
150 list = render(list, <List fruits={fruits}/>, 'body')
151 // Clear input value:
152 input.value = ''
153 } else {
154 alert('Please provide a value before submitting.')
155 }
156 }
157}
158```
159
160In the above example, each subsequent call of the `render` function will update the DOM tree structure with new data. Technically, if we wanted to modify the order of the list items, we would want to render them with a key.
161
162## unmount
163
164The `unmount` function lets you remove a mounted functional component from the DOM. To do so you pass it the reference to the functional component that was returned by the `mount` function:
165
166```javascript
167function Title({message}) {
168 return (
169 <nav>
170 <h1>Hello, {message}!</h1>
171 </nav>
172 )
173}
174let title = mount(<Title message='World'/>, 'header')
175
176// Unmount the title after 5 seconds:
177setTimeout(() => unmount(title), 5000)
178```
179
180In most cases using conditional logic to render a functional component makes more sense. However, if conditional logic is not feasable or adds too much complexity to a component, you can use `unmount` to remove the mounted functional component from the DOM.
181
182## Remount an Unmounted Functional Component
183
184After you've unmounted a functional component, you can remount it later using the `mount` function:
185
186```javascript
187function Title({message}) {
188 return (
189 <nav>
190 <h1>Hello, {message}!</h1>
191 </nav>
192 )
193}
194let title = mount(<Title message='World'/>, 'header')
195
196// Unmount the title after 5 seconds:
197setTimeout(() => unmount(title), 5000)
198
199// Remount the title 5 seconds after it was unmounted:
200setTimeout() => {
201 title = mount(<Title message='World'/>, 'header')
202}, 10000)
203```
204
205## Summary
206
207Both `mount` and `render` are similar in purpose to [`ReactDOM.render`](https://facebook.github.io/react/docs/react-dom.html#render). The main difference is that Composi separates mounting from updating. These means the two function have difference arguments. `mount` expects a second argument for where to inject the component, whereas `render` expects a second argument of the DOM tree to update. If your components need local state, class components might be a better choice. Or not. It depends on your specific needs and your design choices. If you do not like ES6 classes, you can stick with just `mount` and `render` for creating functional components. If your components are very complex, class components may solve your problems better and result in better organization of responsibilities and concerns.
\No newline at end of file