0
# VDOM and Rendering
1
2
Virtual DOM system for efficient component rendering and layout management. ReactPy uses a virtual DOM representation to optimize rendering performance and provide a declarative interface for UI construction.
3
4
## Capabilities
5
6
### VDOM Creation
7
8
The `vdom` function creates virtual DOM elements programmatically:
9
10
```python { .api }
11
def vdom(tag: str, *children, **attributes) -> VdomDict: ...
12
```
13
14
**Parameters:**
15
- `tag`: HTML/SVG tag name
16
- `*children`: Child elements (strings, other VDOM elements, Components)
17
- `**attributes`: Element attributes as keyword arguments
18
19
**Returns:** VdomDict representing the virtual DOM element
20
21
**Usage Examples:**
22
23
```python
24
from reactpy import vdom
25
26
# Basic element
27
element = vdom("div", "Hello World")
28
29
# Element with attributes
30
styled_element = vdom("div", "Styled content", className="my-class", id="unique")
31
32
# Nested elements
33
nested = vdom("div",
34
vdom("h1", "Title"),
35
vdom("p", "Paragraph content"),
36
vdom("button", "Click me", onClick=handler)
37
)
38
```
39
40
### VDOM Constructor Creation
41
42
Create custom element constructors:
43
44
```python { .api }
45
def make_vdom_constructor(tag: str, allow_children: bool = True) -> Callable[..., VdomDict]: ...
46
```
47
48
**Parameters:**
49
- `tag`: HTML/SVG tag name
50
- `allow_children`: Whether the element can have children
51
52
**Returns:** Constructor function for the element
53
54
**Usage Examples:**
55
56
```python
57
# Create custom constructors
58
my_div = make_vdom_constructor("div")
59
my_img = make_vdom_constructor("img", allow_children=False)
60
61
# Use custom constructors
62
content = my_div(
63
{"className": "container"},
64
my_img({"src": "image.jpg", "alt": "Description"})
65
)
66
```
67
68
### VDOM Validation
69
70
Validate VDOM structure:
71
72
```python { .api }
73
def validate_vdom_json(value: Any) -> VdomDict: ...
74
```
75
76
**Parameters:**
77
- `value`: Value to validate as VDOM
78
79
**Returns:** Validated VdomDict
80
81
**Raises:** ValidationError if invalid
82
83
### HTML/VDOM Conversion
84
85
Convert between HTML strings and VDOM:
86
87
```python { .api }
88
def html_to_vdom(html_string: str) -> VdomDict: ...
89
def vdom_to_html(vdom_dict: VdomDict) -> str: ...
90
```
91
92
**Usage Examples:**
93
94
```python
95
# Convert HTML to VDOM
96
html_str = "<div class='container'><h1>Title</h1></div>"
97
vdom_element = html_to_vdom(html_str)
98
99
# Convert VDOM to HTML
100
vdom_element = vdom("div", vdom("h1", "Title"), className="container")
101
html_output = vdom_to_html(vdom_element)
102
```
103
104
### Layout System
105
106
The Layout class manages component rendering and updates:
107
108
```python { .api }
109
class Layout:
110
def __init__(self, component: ComponentType) -> None: ...
111
async def render() -> LayoutUpdate: ...
112
async def deliver(event: LayoutEvent) -> None: ...
113
```
114
115
**Methods:**
116
- `render()`: Render component tree and return layout update
117
- `deliver(event)`: Deliver event to appropriate component
118
119
**Usage Examples:**
120
121
```python
122
from reactpy.core.layout import Layout
123
124
@component
125
def MyComponent():
126
return html.h1("Hello Layout!")
127
128
layout = Layout(MyComponent)
129
130
# Render the layout
131
update = await layout.render()
132
133
# Handle events
134
event = {
135
"type": "click",
136
"target": {"id": "button1"},
137
"clientX": 100,
138
"clientY": 50
139
}
140
await layout.deliver(event)
141
```
142
143
### Layout Types
144
145
Type definitions for layout system:
146
147
```python { .api }
148
# Layout update message
149
class LayoutUpdate(TypedDict):
150
type: Literal["layout-update"]
151
body: dict[str, Any]
152
153
# Layout event message
154
class LayoutEvent(TypedDict):
155
type: Literal["layout-event"]
156
target: str
157
data: dict[str, Any]
158
159
# Layout update body structure
160
class LayoutUpdateBody(TypedDict):
161
root: VdomDict
162
mutations: list[dict[str, Any]]
163
event_handlers: dict[str, str]
164
```
165
166
### VDOM Structure
167
168
VdomDict structure for virtual DOM elements:
169
170
```python { .api }
171
class VdomDict(TypedDict):
172
tagName: str
173
children: list[VdomChild]
174
attributes: dict[str, Any]
175
eventHandlers: dict[str, EventHandler]
176
key: str | None
177
```
178
179
**Usage Examples:**
180
181
```python
182
# Manual VDOM construction
183
vdom_element = {
184
"tagName": "div",
185
"attributes": {"className": "container", "id": "main"},
186
"children": [
187
"Text content",
188
{
189
"tagName": "button",
190
"attributes": {"type": "button"},
191
"children": ["Click me"],
192
"eventHandlers": {"onClick": event_handler},
193
"key": None
194
}
195
],
196
"eventHandlers": {},
197
"key": None
198
}
199
```
200
201
### Component Rendering Pipeline
202
203
Understanding the rendering process:
204
205
```python
206
@component
207
def RenderingExample():
208
# 1. Component function is called
209
# 2. Hooks are executed (state, effects, etc.)
210
# 3. VDOM is returned
211
# 4. Layout processes VDOM
212
# 5. Differences are calculated
213
# 6. Updates are sent to client
214
215
count, set_count = use_state(0) # Hook execution
216
217
return html.div( # VDOM creation
218
html.h1(f"Count: {count}"),
219
html.button(
220
{"onClick": lambda: set_count(count + 1)},
221
"Increment"
222
)
223
)
224
```
225
226
### Performance Optimization
227
228
VDOM enables efficient updates:
229
230
```python
231
@component
232
def OptimizedList(items):
233
# Keys help VDOM identify which items changed
234
return html.ul(
235
*[
236
html.li(item["text"], key=item["id"])
237
for item in items
238
]
239
)
240
241
@component
242
def MemoizedComponent():
243
expensive_value = use_memo(
244
lambda: expensive_computation(),
245
[] # Empty deps = compute once
246
)
247
248
# VDOM only updates when expensive_value changes
249
return html.div(f"Result: {expensive_value}")
250
```
251
252
### Error Handling
253
254
VDOM validation and error handling:
255
256
```python
257
from reactpy.core.vdom import validate_vdom_json
258
259
try:
260
# Validate VDOM structure
261
valid_vdom = validate_vdom_json({
262
"tagName": "div",
263
"children": ["content"],
264
"attributes": {}
265
})
266
except ValidationError as e:
267
print(f"Invalid VDOM: {e}")
268
269
# Common VDOM errors:
270
# - Missing required keys (tagName, children, attributes)
271
# - Invalid children types
272
# - Circular references
273
# - Invalid attribute values
274
```