0
# Components
1
2
Class-based component system providing React-compatible component lifecycle management and state handling. Rax supports both regular components and pure components with automatic shallow comparison optimization.
3
4
## Capabilities
5
6
### Component Base Class
7
8
Base class for all Rax class components. Provides core component functionality including state management and lifecycle methods.
9
10
```javascript { .api }
11
/**
12
* Base component class for creating stateful class components
13
*/
14
class Component {
15
/**
16
* Creates a new component instance
17
* @param props - Component properties passed from parent
18
* @param context - Component context for accessing shared data
19
*/
20
constructor(props, context);
21
22
/**
23
* Updates component state and triggers re-render
24
* @param partialState - Object containing state changes or function returning state changes
25
* @param callback - Optional callback executed after state update
26
*/
27
setState(partialState, callback);
28
29
/**
30
* Forces component to re-render regardless of state or props changes
31
* @param callback - Optional callback executed after re-render
32
*/
33
forceUpdate(callback);
34
35
// Instance properties
36
props: Object; // Component properties
37
context: Object; // Component context
38
refs: Object; // Deprecated ref collection
39
updater: Object; // Internal updater instance
40
}
41
```
42
43
**Usage Examples:**
44
45
```javascript
46
import { createElement, Component } from 'rax';
47
48
class Counter extends Component {
49
constructor(props) {
50
super(props);
51
this.state = {
52
count: props.initialCount || 0
53
};
54
}
55
56
increment = () => {
57
this.setState({ count: this.state.count + 1 });
58
}
59
60
incrementAsync = () => {
61
this.setState(
62
(prevState) => ({ count: prevState.count + 1 }),
63
() => {
64
console.log('State updated:', this.state.count);
65
}
66
);
67
}
68
69
render() {
70
return createElement('div', null,
71
createElement('p', null, `Count: ${this.state.count}`),
72
createElement('button', { onClick: this.increment }, 'Increment'),
73
createElement('button', { onClick: this.incrementAsync }, 'Increment Async')
74
);
75
}
76
}
77
78
// Usage
79
const counter = createElement(Counter, { initialCount: 5 });
80
```
81
82
### PureComponent Class
83
84
Optimized component class that automatically implements shallow comparison for props and state. Only re-renders when shallow comparison detects changes.
85
86
```javascript { .api }
87
/**
88
* Pure component class with automatic shallow comparison optimization
89
* Extends Component and adds shallow comparison for props and state
90
*/
91
class PureComponent extends Component {
92
/**
93
* Creates a new pure component instance
94
* @param props - Component properties passed from parent
95
* @param context - Component context for accessing shared data
96
*/
97
constructor(props, context);
98
99
// Inherits all Component methods
100
// Automatically implements shouldComponentUpdate with shallow comparison
101
__isPureComponent: true; // Internal flag for pure component identification
102
}
103
```
104
105
**Usage Examples:**
106
107
```javascript
108
import { createElement, PureComponent } from 'rax';
109
110
class UserCard extends PureComponent {
111
render() {
112
const { user, theme } = this.props;
113
console.log('UserCard rendered'); // Only logs when props actually change
114
115
return createElement('div', {
116
className: `user-card ${theme}`
117
},
118
createElement('h3', null, user.name),
119
createElement('p', null, user.email),
120
createElement('span', null, `ID: ${user.id}`)
121
);
122
}
123
}
124
125
class UserList extends Component {
126
constructor(props) {
127
super(props);
128
this.state = {
129
theme: 'light',
130
users: [
131
{ id: 1, name: 'Alice', email: 'alice@example.com' },
132
{ id: 2, name: 'Bob', email: 'bob@example.com' }
133
]
134
};
135
}
136
137
toggleTheme = () => {
138
this.setState({ theme: this.state.theme === 'light' ? 'dark' : 'light' });
139
}
140
141
render() {
142
return createElement('div', null,
143
createElement('button', { onClick: this.toggleTheme },
144
`Switch to ${this.state.theme === 'light' ? 'dark' : 'light'} theme`
145
),
146
...this.state.users.map(user =>
147
createElement(UserCard, {
148
key: user.id,
149
user: user,
150
theme: this.state.theme
151
})
152
)
153
);
154
}
155
}
156
```
157
158
### Component Lifecycle
159
160
Class components support React-compatible lifecycle methods. These are called automatically by the Rax runtime during component mounting, updating, and unmounting.
161
162
**Mounting Lifecycle:**
163
1. `constructor(props, context)`
164
2. `componentDidMount()`
165
166
**Updating Lifecycle:**
167
1. `componentDidUpdate(prevProps, prevState, snapshot)`
168
2. `shouldComponentUpdate(nextProps, nextState)` (only for regular Component, not PureComponent)
169
170
**Unmounting Lifecycle:**
171
1. `componentWillUnmount()`
172
173
**Error Handling:**
174
1. `componentDidCatch(error, errorInfo)`
175
176
```javascript { .api }
177
/**
178
* Component lifecycle methods (optional implementations)
179
*/
180
interface ComponentLifecycle {
181
/**
182
* Called immediately after component is mounted to DOM
183
*/
184
componentDidMount?(): void;
185
186
/**
187
* Called immediately after component updates
188
* @param prevProps - Previous props before update
189
* @param prevState - Previous state before update
190
* @param snapshot - Value returned from getSnapshotBeforeUpdate
191
*/
192
componentDidUpdate?(prevProps: Object, prevState: Object, snapshot?: any): void;
193
194
/**
195
* Called immediately before component is unmounted and destroyed
196
*/
197
componentWillUnmount?(): void;
198
199
/**
200
* Determines if component should re-render (Component only, not PureComponent)
201
* @param nextProps - Next props that will be received
202
* @param nextState - Next state that will be set
203
* @returns true if component should update, false otherwise
204
*/
205
shouldComponentUpdate?(nextProps: Object, nextState: Object): boolean;
206
207
/**
208
* Called when an error occurs in any child component
209
* @param error - The error that was thrown
210
* @param errorInfo - Information about the error
211
*/
212
componentDidCatch?(error: Error, errorInfo: Object): void;
213
}
214
```
215
216
**Lifecycle Usage Example:**
217
218
```javascript
219
import { createElement, Component } from 'rax';
220
221
class DataFetcher extends Component {
222
constructor(props) {
223
super(props);
224
this.state = {
225
data: null,
226
loading: true,
227
error: null
228
};
229
}
230
231
async componentDidMount() {
232
try {
233
const response = await fetch(this.props.url);
234
const data = await response.json();
235
this.setState({ data, loading: false });
236
} catch (error) {
237
this.setState({ error: error.message, loading: false });
238
}
239
}
240
241
componentDidUpdate(prevProps) {
242
if (prevProps.url !== this.props.url) {
243
this.setState({ loading: true });
244
this.fetchData();
245
}
246
}
247
248
componentWillUnmount() {
249
// Cleanup any subscriptions or timers
250
if (this.timer) {
251
clearInterval(this.timer);
252
}
253
}
254
255
componentDidCatch(error, errorInfo) {
256
console.error('DataFetcher caught an error:', error, errorInfo);
257
this.setState({ error: 'Something went wrong' });
258
}
259
260
render() {
261
const { data, loading, error } = this.state;
262
263
if (loading) {
264
return createElement('div', null, 'Loading...');
265
}
266
267
if (error) {
268
return createElement('div', null, `Error: ${error}`);
269
}
270
271
return createElement('div', null,
272
createElement('pre', null, JSON.stringify(data, null, 2))
273
);
274
}
275
}
276
```
277
278
## Types
279
280
```javascript { .api }
281
// Component constructor type
282
interface ComponentConstructor {
283
new (props: Object, context?: Object): Component;
284
}
285
286
// Component instance interface
287
interface ComponentInstance {
288
props: Object;
289
context: Object;
290
state: Object;
291
refs: Object;
292
updater: Object;
293
setState(partialState: Object | Function, callback?: Function): void;
294
forceUpdate(callback?: Function): void;
295
}
296
297
// State updater function type
298
type StateUpdater<S> = (prevState: S, props: Object) => Partial<S>;
299
300
// setState parameter types
301
type SetStateParameter<S> = Partial<S> | StateUpdater<S>;
302
303
// Component lifecycle method types
304
type ComponentDidMountMethod = () => void;
305
type ComponentDidUpdateMethod = (prevProps: Object, prevState: Object, snapshot?: any) => void;
306
type ComponentWillUnmountMethod = () => void;
307
type ShouldComponentUpdateMethod = (nextProps: Object, nextState: Object) => boolean;
308
type ComponentDidCatchMethod = (error: Error, errorInfo: Object) => void;
309
```