0
# Core Virtual DOM
1
2
Essential functions for creating and rendering virtual DOM elements. These functions provide the foundation for all Preact applications, enabling efficient DOM manipulation through a virtual representation.
3
4
## Capabilities
5
6
### Render Function
7
8
Renders virtual DOM nodes to actual DOM elements, managing the entire component lifecycle.
9
10
```typescript { .api }
11
/**
12
* Renders a virtual node to a DOM container
13
* @param vnode - Virtual node or component to render
14
* @param parent - DOM container element
15
*/
16
function render(vnode: ComponentChild, parent: ContainerNode): void;
17
18
/**
19
* @deprecated The replaceNode parameter will be removed in v11
20
* Renders with optional replacement node
21
*/
22
function render(
23
vnode: ComponentChild,
24
parent: ContainerNode,
25
replaceNode?: Element | Text
26
): void;
27
28
interface ContainerNode {
29
readonly nodeType: number;
30
readonly parentNode: ContainerNode | null;
31
readonly firstChild: ContainerNode | null;
32
readonly childNodes: ArrayLike<ContainerNode>;
33
34
contains(other: ContainerNode | null): boolean;
35
insertBefore(node: ContainerNode, child: ContainerNode | null): ContainerNode;
36
appendChild(node: ContainerNode): ContainerNode;
37
removeChild(child: ContainerNode): ContainerNode;
38
}
39
```
40
41
**Usage Examples:**
42
43
```typescript
44
import { render, createElement } from "preact";
45
46
// Render a simple element
47
render(
48
createElement("h1", null, "Hello World"),
49
document.getElementById("app")
50
);
51
52
// Render a component
53
function App() {
54
return createElement("div", null,
55
createElement("h1", null, "Welcome"),
56
createElement("p", null, "This is a Preact app")
57
);
58
}
59
60
render(createElement(App), document.body);
61
```
62
63
### Hydrate Function
64
65
Hydrates server-rendered markup with interactive Preact components, preserving existing DOM structure.
66
67
```typescript { .api }
68
/**
69
* Hydrates server-rendered content with Preact components
70
* @param vnode - Virtual node to hydrate
71
* @param parent - DOM container with server-rendered content
72
*/
73
function hydrate(vnode: ComponentChild, parent: ContainerNode): void;
74
```
75
76
**Usage Examples:**
77
78
```typescript
79
import { hydrate, createElement } from "preact";
80
81
// Hydrate server-rendered content
82
function App() {
83
return createElement("div", null,
84
createElement("h1", null, "Server Rendered"),
85
createElement("button", {
86
onClick: () => alert("Interactive!")
87
}, "Click me")
88
);
89
}
90
91
// Assumes server rendered the same structure
92
hydrate(createElement(App), document.getElementById("app"));
93
```
94
95
### Create Element Function
96
97
Creates virtual DOM nodes from components, HTML elements, or fragments.
98
99
```typescript { .api }
100
/**
101
* Creates a virtual DOM node
102
* @param type - Component type or HTML tag name
103
* @param props - Properties and attributes for the element
104
* @param children - Child elements or content
105
* @returns Virtual node representation
106
*/
107
function createElement<P>(
108
type: ComponentType<P> | string,
109
props: (Attributes & P) | null,
110
...children: ComponentChildren[]
111
): VNode<P>;
112
113
/**
114
* JSX pragma alias for createElement
115
*/
116
function h<P>(
117
type: ComponentType<P> | string,
118
props: (Attributes & P) | null,
119
...children: ComponentChildren[]
120
): VNode<P>;
121
```
122
123
**Usage Examples:**
124
125
```typescript
126
import { createElement, h } from "preact";
127
128
// HTML elements
129
const heading = createElement("h1", { className: "title" }, "Hello");
130
const button = createElement("button",
131
{ onClick: () => console.log("clicked") },
132
"Click me"
133
);
134
135
// With JSX pragma (h)
136
const element = h("div", { id: "container" },
137
h("p", null, "Using h function"),
138
h("span", null, "Works the same")
139
);
140
141
// Functional component
142
function Greeting({ name }: { name: string }) {
143
return createElement("h1", null, `Hello ${name}!`);
144
}
145
146
const greeting = createElement(Greeting, { name: "World" });
147
148
// Multiple children
149
const list = createElement("ul", null,
150
createElement("li", null, "Item 1"),
151
createElement("li", null, "Item 2"),
152
createElement("li", null, "Item 3")
153
);
154
```
155
156
### Clone Element Function
157
158
Creates a copy of an existing virtual node with modified properties or children.
159
160
```typescript { .api }
161
/**
162
* Clones a virtual node with new props and/or children
163
* @param vnode - Virtual node to clone
164
* @param props - New or overriding properties
165
* @param children - New children to replace existing ones
166
* @returns New virtual node with modifications
167
*/
168
function cloneElement<P>(
169
vnode: VNode<P>,
170
props?: any,
171
...children: ComponentChildren[]
172
): VNode<P>;
173
```
174
175
**Usage Examples:**
176
177
```typescript
178
import { createElement, cloneElement } from "preact";
179
180
const original = createElement("button",
181
{ className: "btn", disabled: false },
182
"Click me"
183
);
184
185
// Clone with new props
186
const disabled = cloneElement(original, { disabled: true });
187
188
// Clone with new children
189
const newText = cloneElement(original, null, "New Text");
190
191
// Clone with both new props and children
192
const modified = cloneElement(original,
193
{ className: "btn btn-primary" },
194
"Save Changes"
195
);
196
```
197
198
### Fragment Component
199
200
Groups multiple elements without creating an additional DOM wrapper node.
201
202
```typescript { .api }
203
/**
204
* Fragment component for grouping elements
205
* @param props - Props containing children
206
* @returns The children without wrapper
207
*/
208
const Fragment: FunctionComponent<{ children?: ComponentChildren }>;
209
```
210
211
**Usage Examples:**
212
213
```typescript
214
import { createElement, Fragment } from "preact";
215
216
// Multiple top-level elements without wrapper
217
function MultipleElements() {
218
return createElement(Fragment, null,
219
createElement("h1", null, "Title"),
220
createElement("p", null, "Paragraph 1"),
221
createElement("p", null, "Paragraph 2")
222
);
223
}
224
225
// Conditional rendering with fragments
226
function ConditionalContent({ showExtra }: { showExtra: boolean }) {
227
return createElement("div", null,
228
createElement("h1", null, "Always shown"),
229
showExtra && createElement(Fragment, null,
230
createElement("p", null, "Extra content 1"),
231
createElement("p", null, "Extra content 2")
232
)
233
);
234
}
235
```
236
237
### Utility Functions
238
239
Additional utilities for working with virtual DOM elements and children.
240
241
```typescript { .api }
242
/**
243
* Creates a mutable ref object
244
* @returns Ref object with current property
245
*/
246
function createRef<T = any>(): RefObject<T>;
247
248
/**
249
* Checks if a value is a valid Preact element
250
* @param vnode - Value to check
251
* @returns True if value is a valid VNode
252
*/
253
function isValidElement(vnode: any): vnode is VNode;
254
255
/**
256
* Normalizes children to a flat array
257
* @param children - Children to normalize
258
* @param out - Optional accumulator array to use
259
* @returns Flat array of VNodes and primitives
260
*/
261
function toChildArray(children: ComponentChildren, out?: Array<VNode | string | number>): Array<VNode | string | number>;
262
```
263
264
**Usage Examples:**
265
266
```typescript
267
import { createRef, isValidElement, toChildArray, createElement } from "preact";
268
269
// Ref usage
270
const inputRef = createRef<HTMLInputElement>();
271
272
function InputComponent() {
273
const focusInput = () => {
274
if (inputRef.current) {
275
inputRef.current.focus();
276
}
277
};
278
279
return createElement("div", null,
280
createElement("input", { ref: inputRef, type: "text" }),
281
createElement("button", { onClick: focusInput }, "Focus Input")
282
);
283
}
284
285
// Element validation
286
const element = createElement("div", null, "Hello");
287
console.log(isValidElement(element)); // true
288
console.log(isValidElement("string")); // false
289
290
// Children normalization
291
const children = [
292
"text",
293
createElement("span", null, "element"),
294
["nested", "array"]
295
];
296
const normalized = toChildArray(children);
297
// Result: ["text", VNode, "nested", "array"]
298
```