0
# Fragments and Utilities
1
2
Fragment support for grouping elements without wrapper nodes, and utility functions for advanced VNode manipulation and DOM access.
3
4
## Capabilities
5
6
### Fragment
7
8
Symbol used to create fragment VNodes that group multiple elements without adding a wrapper DOM element.
9
10
```typescript { .api }
11
/**
12
* Symbol used to create fragment VNodes for grouping elements without wrapper
13
*/
14
const Fragment: unique symbol;
15
```
16
17
**Usage Examples:**
18
19
```typescript
20
import { Fragment, createVNode, createFragment, VNodeFlags, ChildFlags } from "inferno";
21
22
// Using Fragment directly with createVNode
23
const fragmentVNode = createVNode(VNodeFlags.Fragment, Fragment, null, [
24
createVNode(VNodeFlags.HtmlElement, 'h1', null, 'Title'),
25
createVNode(VNodeFlags.HtmlElement, 'p', null, 'Content without wrapper div')
26
], ChildFlags.HasNonKeyedChildren);
27
28
// Using createFragment helper (recommended)
29
const fragment = createFragment([
30
createVNode(VNodeFlags.HtmlElement, 'li', null, 'Item 1'),
31
createVNode(VNodeFlags.HtmlElement, 'li', null, 'Item 2'),
32
createVNode(VNodeFlags.HtmlElement, 'li', null, 'Item 3')
33
], ChildFlags.HasNonKeyedChildren);
34
35
// In a component
36
class ListComponent extends Component {
37
render() {
38
return createVNode(VNodeFlags.HtmlElement, 'ul', null, [
39
fragment, // Multiple li elements without wrapper
40
createVNode(VNodeFlags.HtmlElement, 'li', null, 'Additional item')
41
]);
42
}
43
}
44
```
45
46
### Empty Object Constant
47
48
Immutable empty object used for performance optimization to avoid creating new empty objects.
49
50
```typescript { .api }
51
/**
52
* Immutable empty object used for performance optimization
53
*/
54
const EMPTY_OBJ: {};
55
```
56
57
**Usage Examples:**
58
59
```typescript
60
import { EMPTY_OBJ, Component } from "inferno";
61
62
class OptimizedComponent extends Component {
63
constructor(props) {
64
super(props);
65
// Use EMPTY_OBJ instead of {} for consistency
66
this.context = this.context || EMPTY_OBJ;
67
}
68
69
render() {
70
// Use for default props to avoid object creation
71
const props = this.props || EMPTY_OBJ;
72
return createVNode(VNodeFlags.HtmlElement, 'div', null, props.children);
73
}
74
}
75
```
76
77
### Find DOM From VNode
78
79
Utility function to find the actual DOM element associated with a VNode.
80
81
```typescript { .api }
82
/**
83
* Finds the actual DOM element associated with a VNode
84
* @param vNode - VNode to find DOM element for
85
* @param start - Whether to search from the start of the VNode tree
86
* @returns DOM element or null if not found
87
*/
88
function findDOMFromVNode(vNode: VNode, start: boolean): Element | null;
89
```
90
91
**Usage Examples:**
92
93
```typescript
94
import { findDOMFromVNode, createVNode, VNodeFlags } from "inferno";
95
96
class DOMAccessComponent extends Component {
97
componentDidMount() {
98
// Find DOM element from the component's VNode
99
const domElement = findDOMFromVNode(this.$LI, true);
100
if (domElement) {
101
console.log('Component DOM element:', domElement);
102
domElement.style.border = '2px solid blue';
103
}
104
}
105
106
render() {
107
return createVNode(VNodeFlags.HtmlElement, 'div', 'component-container', 'Component content');
108
}
109
}
110
```
111
112
### Direct Clone
113
114
Creates a direct clone of a VNode for safe reuse in different parts of the virtual DOM tree.
115
116
```typescript { .api }
117
/**
118
* Creates a direct clone of a VNode for safe reuse
119
* @param vNodeToClone - VNode to clone
120
* @returns New VNode instance with same properties
121
*/
122
function directClone(vNodeToClone: VNode): VNode;
123
```
124
125
**Usage Examples:**
126
127
```typescript
128
import { directClone, createVNode, VNodeFlags } from "inferno";
129
130
class ReusableNodeComponent extends Component {
131
render() {
132
// Create a VNode once
133
const iconVNode = createVNode(VNodeFlags.HtmlElement, 'i', 'icon icon-star', null);
134
135
// Clone for reuse in multiple places
136
return createVNode(VNodeFlags.HtmlElement, 'div', null, [
137
createVNode(VNodeFlags.HtmlElement, 'h1', null, ['Favorites ', iconVNode]),
138
createVNode(VNodeFlags.HtmlElement, 'p', null, ['Rate this ', directClone(iconVNode)]),
139
createVNode(VNodeFlags.HtmlElement, 'button', null, [directClone(iconVNode), ' Add to favorites'])
140
]);
141
}
142
}
143
```
144
145
### Options Configuration
146
147
Global configuration object for customizing Inferno behavior.
148
149
```typescript { .api }
150
/**
151
* Global options for configuring Inferno behavior
152
*/
153
const options: {
154
/** Hook called after VNode creation for custom processing */
155
createVNode: ((vNode: VNode) => void) | null;
156
/** Enable React-style CSS property naming (camelCase) */
157
reactStyles?: boolean;
158
};
159
```
160
161
**Usage Examples:**
162
163
```typescript
164
import { options } from "inferno";
165
166
// Hook into VNode creation for debugging
167
options.createVNode = (vNode) => {
168
console.log('VNode created:', vNode.type);
169
};
170
171
// Enable React-compatible CSS styling
172
options.reactStyles = true;
173
```
174
175
### Version Information
176
177
Current version of the Inferno library.
178
179
```typescript { .api }
180
/**
181
* Current version string of the Inferno library
182
*/
183
const version: string;
184
```
185
186
**Usage Examples:**
187
188
```typescript
189
import { version } from "inferno";
190
191
console.log('Inferno version:', version);
192
// Logs something like: "Inferno version: 9.0.3"
193
194
// Conditional feature detection
195
if (version.startsWith('9.')) {
196
// Use v9-specific features
197
}
198
```
199
200
### Rerender Function
201
202
Triggers a global re-render of all mounted components.
203
204
```typescript { .api }
205
/**
206
* Triggers a global re-render of all mounted components
207
*/
208
function rerender(): void;
209
```
210
211
**Usage Examples:**
212
213
```typescript
214
import { rerender } from "inferno";
215
216
// Force global re-render (use sparingly)
217
rerender();
218
219
// Useful for debugging or after global state changes
220
window.debugRerender = rerender;
221
```
222
223
## Animation Queues
224
225
System for managing animation lifecycle hooks with proper timing and coordination.
226
227
```typescript { .api }
228
/**
229
* Manages animation lifecycle hooks with proper timing
230
*/
231
class AnimationQueues {
232
/** Functions to call when components appear */
233
componentDidAppear: Array<() => void>;
234
/** Functions to call when components will disappear */
235
componentWillDisappear: Array<() => void>;
236
}
237
```
238
239
**Usage Examples:**
240
241
```typescript
242
import { AnimationQueues } from "inferno";
243
244
// Used internally by the rendering system
245
const animations = new AnimationQueues();
246
247
// Add animation hooks
248
animations.componentDidAppear.push(() => {
249
console.log('Component appeared');
250
});
251
252
animations.componentWillDisappear.push(() => {
253
console.log('Component will disappear');
254
});
255
```
256
257
## Advanced Fragment Usage
258
259
### Conditional Fragments
260
261
```typescript
262
class ConditionalFragment extends Component {
263
render() {
264
const showHeader = this.props.showHeader;
265
266
return createVNode(VNodeFlags.HtmlElement, 'div', 'container', [
267
showHeader ? createFragment([
268
createVNode(VNodeFlags.HtmlElement, 'h1', null, 'Title'),
269
createVNode(VNodeFlags.HtmlElement, 'nav', null, 'Navigation')
270
], ChildFlags.HasNonKeyedChildren) : null,
271
createVNode(VNodeFlags.HtmlElement, 'main', null, this.props.children)
272
]);
273
}
274
}
275
```
276
277
### Nested Fragments
278
279
```typescript
280
class NestedFragments extends Component {
281
render() {
282
const headerFragment = createFragment([
283
createVNode(VNodeFlags.HtmlElement, 'h1', null, 'Main Title'),
284
createVNode(VNodeFlags.HtmlElement, 'h2', null, 'Subtitle')
285
], ChildFlags.HasNonKeyedChildren);
286
287
const contentFragment = createFragment([
288
createVNode(VNodeFlags.HtmlElement, 'p', null, 'First paragraph'),
289
createVNode(VNodeFlags.HtmlElement, 'p', null, 'Second paragraph')
290
], ChildFlags.HasNonKeyedChildren);
291
292
return createFragment([headerFragment, contentFragment], ChildFlags.HasNonKeyedChildren);
293
}
294
}
295
```
296
297
## Utility Function Patterns
298
299
### Performance Optimization with EMPTY_OBJ
300
301
```typescript
302
class OptimizedComponent extends Component {
303
// Use EMPTY_OBJ to avoid creating new objects
304
static defaultProps = EMPTY_OBJ;
305
306
constructor(props) {
307
super(props);
308
this.state = this.getInitialState();
309
}
310
311
getInitialState() {
312
// Return EMPTY_OBJ when no state is needed
313
return this.props.hasState ? { count: 0 } : EMPTY_OBJ;
314
}
315
316
render() {
317
return createVNode(VNodeFlags.HtmlElement, 'div', null, 'Optimized component');
318
}
319
}
320
```
321
322
### VNode Reuse Patterns
323
324
```typescript
325
class ReusableComponents extends Component {
326
constructor(props) {
327
super(props);
328
329
// Create reusable VNodes
330
this.iconVNodes = {
331
star: createVNode(VNodeFlags.HtmlElement, 'i', 'icon icon-star'),
332
heart: createVNode(VNodeFlags.HtmlElement, 'i', 'icon icon-heart'),
333
check: createVNode(VNodeFlags.HtmlElement, 'i', 'icon icon-check')
334
};
335
}
336
337
render() {
338
return createVNode(VNodeFlags.HtmlElement, 'div', null, [
339
createVNode(VNodeFlags.HtmlElement, 'button', null, [
340
directClone(this.iconVNodes.star),
341
' Favorite'
342
]),
343
createVNode(VNodeFlags.HtmlElement, 'button', null, [
344
directClone(this.iconVNodes.heart),
345
' Like'
346
]),
347
createVNode(VNodeFlags.HtmlElement, 'button', null, [
348
directClone(this.iconVNodes.check),
349
' Complete'
350
])
351
]);
352
}
353
}
354
```
355
356
## Performance Tips
357
358
1. **Use EMPTY_OBJ**: Reuse the constant instead of creating `{}` objects
359
2. **Clone VNodes for reuse**: Use `directClone()` when reusing VNodes in different locations
360
3. **Optimize with fragments**: Avoid unnecessary wrapper elements
361
4. **Cache VNode creation**: Create reusable VNodes once and clone when needed
362
5. **Use appropriate flags**: Let `getFlagsForElementVnode()` determine optimal flags