0
# Component System
1
2
Class and functional component system with comprehensive lifecycle methods, state management, and performance optimizations.
3
4
## Capabilities
5
6
### Component Class
7
8
Base class for creating stateful components with lifecycle methods and state management.
9
10
```typescript { .api }
11
/**
12
* Base class for creating stateful components
13
*/
14
abstract class Component<P = Record<string, unknown>, S = Record<string, unknown>> {
15
/** Current component state */
16
state: Readonly<S | null>;
17
/** Component props passed from parent */
18
props: Readonly<{ children?: InfernoNode } & P>;
19
/** Context object from parent components */
20
context: any;
21
/** Optional display name for debugging */
22
displayName?: string;
23
24
constructor(props?: P, context?: any);
25
26
/**
27
* Updates component state and triggers re-render
28
* @param newState - New state object or updater function
29
* @param callback - Optional callback called after state update
30
*/
31
setState<K extends keyof S>(
32
newState: ((prevState: Readonly<S>, props: Readonly<{ children?: InfernoNode } & P>) => Pick<S, K> | S | null) | (Pick<S, K> | S | null),
33
callback?: () => void
34
): void;
35
36
/**
37
* Forces component to re-render regardless of shouldComponentUpdate
38
* @param callback - Optional callback called after re-render
39
*/
40
forceUpdate(callback?: (() => void) | undefined): void;
41
42
/**
43
* Renders the component's virtual DOM
44
* @param props - Current props
45
* @param state - Current state
46
* @param context - Current context
47
* @returns Virtual DOM representation
48
*/
49
abstract render(props: Readonly<{ children?: InfernoNode } & P>, state: Readonly<S>, context: any): InfernoNode;
50
51
// Lifecycle methods (optional)
52
componentDidMount?(): void;
53
componentWillMount?(): void;
54
componentWillReceiveProps?(nextProps: Readonly<{ children?: InfernoNode } & P>, nextContext: any): void;
55
shouldComponentUpdate?(nextProps: Readonly<{ children?: InfernoNode } & P>, nextState: Readonly<S>, context: any): boolean;
56
componentWillUpdate?(nextProps: Readonly<{ children?: InfernoNode } & P>, nextState: Readonly<S>, context: any): void;
57
componentDidUpdate?(prevProps: Readonly<{ children?: InfernoNode } & P>, prevState: Readonly<S>, snapshot: any): void;
58
componentWillUnmount?(): void;
59
componentDidAppear?(domNode: Element): void;
60
componentWillDisappear?(domNode: Element, callback: () => void): void;
61
componentWillMove?(parentVNode: VNode, parentDOM: Element, dom: Element): void;
62
getChildContext?(): void;
63
getSnapshotBeforeUpdate?(prevProps: Readonly<{ children?: InfernoNode } & P>, prevState: Readonly<S>): any;
64
65
// Static properties
66
static defaultProps?: Record<string, unknown> | null;
67
static getDerivedStateFromProps?(nextProps: any, state: any): any;
68
}
69
```
70
71
**Usage Examples:**
72
73
```typescript
74
import { Component, createVNode, VNodeFlags } from "inferno";
75
76
class Counter extends Component<{}, { count: number }> {
77
constructor(props) {
78
super(props);
79
this.state = { count: 0 };
80
}
81
82
componentDidMount() {
83
console.log('Counter mounted');
84
}
85
86
increment = () => {
87
this.setState(prevState => ({ count: prevState.count + 1 }));
88
};
89
90
render() {
91
return createVNode(VNodeFlags.HtmlElement, 'div', null, [
92
createVNode(VNodeFlags.HtmlElement, 'h2', null, `Count: ${this.state.count}`),
93
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Increment', ChildFlags.HasInvalidChildren, {
94
onClick: this.increment
95
})
96
]);
97
}
98
}
99
100
// With default props
101
class Greeting extends Component<{ name?: string }> {
102
static defaultProps = { name: 'World' };
103
104
render() {
105
return createVNode(VNodeFlags.HtmlElement, 'h1', null, `Hello, ${this.props.name}!`);
106
}
107
}
108
```
109
110
### Stateless Functional Components
111
112
Function-based components for simple, stateless UI elements.
113
114
```typescript { .api }
115
/**
116
* Function-based components for simple, stateless UI elements
117
*/
118
interface StatelessComponent<P = {}> {
119
(props: { children?: InfernoNode } & P & Refs<P>, context?: any): InfernoElement | null;
120
defaultProps?: Partial<P> | undefined | null;
121
defaultHooks?: Refs<P> | undefined | null;
122
}
123
124
type SFC<P = {}> = StatelessComponent<P>;
125
```
126
127
**Usage Examples:**
128
129
```typescript
130
import { createVNode, VNodeFlags } from "inferno";
131
132
// Simple functional component
133
function Welcome(props) {
134
return createVNode(VNodeFlags.HtmlElement, 'h1', null, `Welcome, ${props.name}!`);
135
}
136
137
// With default props
138
function Button(props) {
139
return createVNode(VNodeFlags.HtmlElement, 'button', props.className, props.children, ChildFlags.HasInvalidChildren, {
140
onClick: props.onClick,
141
disabled: props.disabled
142
});
143
}
144
145
Button.defaultProps = {
146
className: 'btn',
147
disabled: false
148
};
149
150
// With lifecycle hooks
151
function FadeIn(props) {
152
return createVNode(VNodeFlags.HtmlElement, 'div', 'fade-in', props.children);
153
}
154
155
FadeIn.defaultHooks = {
156
onComponentDidAppear(domNode) {
157
domNode.style.opacity = '0';
158
domNode.style.transition = 'opacity 0.3s';
159
setTimeout(() => domNode.style.opacity = '1', 10);
160
}
161
};
162
```
163
164
### Component Types
165
166
Union type for all component types.
167
168
```typescript { .api }
169
/**
170
* Union type for all component types
171
*/
172
type ComponentType<P = Record<string, unknown>> = typeof Component<P> | StatelessComponent<P>;
173
```
174
175
### Re-render Function
176
177
Force re-rendering of all queued components.
178
179
```typescript { .api }
180
/**
181
* Force re-rendering of all queued components
182
* Used internally by the state management system
183
*/
184
function rerender(): void;
185
```
186
187
## Lifecycle Methods
188
189
### Mounting Lifecycle
190
191
Called when component is being created and inserted into the DOM:
192
193
1. **constructor()** - Initialize state and bind methods
194
2. **componentWillMount()** - Called before mounting (deprecated)
195
3. **render()** - Returns virtual DOM representation
196
4. **componentDidMount()** - Called after mounting, ideal for DOM operations
197
198
### Updating Lifecycle
199
200
Called when component props or state changes:
201
202
1. **componentWillReceiveProps(nextProps, nextContext)** - Called when receiving new props
203
2. **shouldComponentUpdate(nextProps, nextState, context)** - Controls whether to re-render
204
3. **componentWillUpdate(nextProps, nextState, context)** - Called before update
205
4. **render()** - Returns updated virtual DOM
206
5. **getSnapshotBeforeUpdate(prevProps, prevState)** - Capture info before DOM changes
207
6. **componentDidUpdate(prevProps, prevState, snapshot)** - Called after update
208
209
### Unmounting Lifecycle
210
211
Called when component is being removed from the DOM:
212
213
1. **componentWillUnmount()** - Cleanup before removal
214
215
### Animation Lifecycle
216
217
Special lifecycle methods for animations:
218
219
- **componentDidAppear(domNode)** - Called when component appears
220
- **componentWillDisappear(domNode, callback)** - Called before disappearing
221
- **componentWillMove(parentVNode, parentDOM, dom)** - Called when moving
222
223
## State Management
224
225
### setState Method
226
227
Updates component state and triggers re-render:
228
229
```typescript
230
// Object update
231
this.setState({ count: 10 });
232
233
// Functional update
234
this.setState(prevState => ({ count: prevState.count + 1 }));
235
236
// With callback
237
this.setState({ loading: false }, () => {
238
console.log('State updated');
239
});
240
```
241
242
### State Update Rules
243
244
1. **Immutability**: Always return new state objects, don't mutate existing state
245
2. **Async Updates**: setState is asynchronous, use callbacks or functional updates for dependent operations
246
3. **Batching**: Multiple setState calls in the same event are batched for performance
247
4. **Constructor Restriction**: Cannot call setState in constructor, assign directly to this.state
248
249
## Context System
250
251
### Providing Context
252
253
```typescript
254
class Provider extends Component {
255
getChildContext() {
256
return { theme: 'dark', locale: 'en' };
257
}
258
259
render() {
260
return this.props.children;
261
}
262
}
263
```
264
265
### Consuming Context
266
267
```typescript
268
class Consumer extends Component {
269
constructor(props, context) {
270
super(props, context);
271
console.log(context.theme); // 'dark'
272
}
273
274
render() {
275
return createVNode(VNodeFlags.HtmlElement, 'div', this.context.theme);
276
}
277
}
278
```
279
280
## Performance Optimizations
281
282
### shouldComponentUpdate
283
284
Prevents unnecessary re-renders:
285
286
```typescript
287
shouldComponentUpdate(nextProps, nextState) {
288
return nextProps.id !== this.props.id || nextState.count !== this.state.count;
289
}
290
```
291
292
### Default Props Merging
293
294
Default props are automatically merged with provided props:
295
296
```typescript
297
class MyComponent extends Component {
298
static defaultProps = { color: 'blue', size: 'medium' };
299
300
render() {
301
// this.props will include default values for missing props
302
return createVNode(VNodeFlags.HtmlElement, 'div', `${this.props.color} ${this.props.size}`);
303
}
304
}
305
```
306
307
### Component Refs
308
309
Access component instances through refs:
310
311
```typescript
312
class Parent extends Component {
313
componentDidMount() {
314
this.childComponent.focus(); // Access child methods
315
}
316
317
render() {
318
return createComponentVNode(
319
VNodeFlags.ComponentClass,
320
ChildComponent,
321
{},
322
null,
323
(instance) => { this.childComponent = instance; }
324
);
325
}
326
}
327
```