npm-react

Description
React is a JavaScript library for building user interfaces with declarative, component-based architecture.
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/npm-react@18.3.0

components.md docs/

1
# Component Classes
2
3
React component classes provide the foundation for creating stateful class-based components with lifecycle methods. While function components with hooks are now preferred, class components remain important for certain use cases and legacy codebases.
4
5
## Capabilities
6
7
### Component
8
9
Base class for React class components providing state management and lifecycle methods.
10
11
```javascript { .api }
12
/**
13
* Base class for React class components
14
*/
15
class Component<P = {}, S = {}, SS = any> {
16
/**
17
* Component constructor
18
* @param props - Component props
19
*/
20
constructor(props: P);
21
22
/**
23
* Component props (read-only)
24
*/
25
readonly props: Readonly<P> & Readonly<{ children?: ReactNode }>;
26
27
/**
28
* Component state
29
*/
30
state: Readonly<S>;
31
32
/**
33
* Context value (legacy context API)
34
*/
35
context: any;
36
37
/**
38
* Update component state
39
* @param partialState - Partial state update or updater function
40
* @param callback - Optional callback after state update
41
*/
42
setState<K extends keyof S>(
43
state: ((prevState: Readonly<S>, props: Readonly<P>) => Pick<S, K> | S | null) | Pick<S, K> | S | null,
44
callback?: () => void
45
): void;
46
47
/**
48
* Force component re-render
49
* @param callback - Optional callback after update
50
*/
51
forceUpdate(callback?: () => void): void;
52
53
/**
54
* Render method that returns JSX
55
* @returns React element or null
56
*/
57
render(): ReactNode;
58
59
// Lifecycle methods
60
componentDidMount?(): void;
61
componentDidUpdate?(prevProps: Readonly<P>, prevState: Readonly<S>, snapshot?: SS): void;
62
componentWillUnmount?(): void;
63
shouldComponentUpdate?(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: any): boolean;
64
getSnapshotBeforeUpdate?(prevProps: Readonly<P>, prevState: Readonly<S>): SS | null;
65
66
// Error handling
67
componentDidCatch?(error: Error, errorInfo: ErrorInfo): void;
68
static getDerivedStateFromError?(error: Error): any;
69
static getDerivedStateFromProps?<P, S>(props: P, state: S): Partial<S> | null;
70
}
71
```
72
73
**Usage Examples:**
74
75
```javascript
76
import React, { Component } from 'react';
77
78
class Counter extends Component {
79
constructor(props) {
80
super(props);
81
this.state = {
82
count: props.initialCount || 0,
83
lastUpdated: Date.now()
84
};
85
}
86
87
componentDidMount() {
88
console.log('Counter component mounted');
89
// Set up timers, fetch data, etc.
90
}
91
92
componentDidUpdate(prevProps, prevState) {
93
if (prevState.count !== this.state.count) {
94
console.log(`Count changed from ${prevState.count} to ${this.state.count}`);
95
}
96
}
97
98
componentWillUnmount() {
99
console.log('Counter component will unmount');
100
// Clean up timers, subscriptions, etc.
101
}
102
103
shouldComponentUpdate(nextProps, nextState) {
104
// Only update if count actually changed
105
return nextState.count !== this.state.count;
106
}
107
108
handleIncrement = () => {
109
this.setState(prevState => ({
110
count: prevState.count + 1,
111
lastUpdated: Date.now()
112
}));
113
};
114
115
handleDecrement = () => {
116
this.setState(prevState => ({
117
count: prevState.count - 1,
118
lastUpdated: Date.now()
119
}), () => {
120
console.log('State updated!');
121
});
122
};
123
124
render() {
125
const { count, lastUpdated } = this.state;
126
const { title } = this.props;
127
128
return (
129
<div>
130
<h2>{title}</h2>
131
<p>Count: {count}</p>
132
<p>Last updated: {new Date(lastUpdated).toLocaleTimeString()}</p>
133
<button onClick={this.handleIncrement}>+</button>
134
<button onClick={this.handleDecrement}>-</button>
135
</div>
136
);
137
}
138
}
139
140
// Usage
141
<Counter title="My Counter" initialCount={5} />
142
```
143
144
### PureComponent
145
146
Optimized component class that implements shouldComponentUpdate with shallow prop and state comparison.
147
148
```javascript { .api }
149
/**
150
* Component class with built-in shallow comparison optimization
151
*/
152
class PureComponent<P = {}, S = {}, SS = any> extends Component<P, S, SS> {
153
/**
154
* Automatically implements shouldComponentUpdate with shallow comparison
155
* Only re-renders if props or state have shallowly changed
156
*/
157
}
158
```
159
160
**Usage Examples:**
161
162
```javascript
163
import React, { PureComponent } from 'react';
164
165
class UserCard extends PureComponent {
166
render() {
167
const { user, onEdit } = this.props;
168
169
console.log('UserCard rendering'); // Only logs when props change
170
171
return (
172
<div className="user-card">
173
<img src={user.avatar} alt={user.name} />
174
<h3>{user.name}</h3>
175
<p>{user.email}</p>
176
<button onClick={() => onEdit(user.id)}>Edit</button>
177
</div>
178
);
179
}
180
}
181
182
class UserList extends PureComponent {
183
state = {
184
users: [
185
{ id: 1, name: 'John', email: 'john@example.com', avatar: 'john.jpg' },
186
{ id: 2, name: 'Jane', email: 'jane@example.com', avatar: 'jane.jpg' }
187
],
188
selectedId: null
189
};
190
191
handleEdit = (userId) => {
192
this.setState({ selectedId: userId });
193
};
194
195
render() {
196
const { users, selectedId } = this.state;
197
198
return (
199
<div>
200
<h2>Users</h2>
201
{users.map(user => (
202
<UserCard
203
key={user.id}
204
user={user}
205
onEdit={this.handleEdit}
206
isSelected={user.id === selectedId}
207
/>
208
))}
209
</div>
210
);
211
}
212
}
213
```
214
215
### Error Boundaries
216
217
Components that catch JavaScript errors in their child component tree and display fallback UI.
218
219
```javascript { .api }
220
/**
221
* Error boundary lifecycle methods
222
*/
223
interface ErrorBoundaryMethods {
224
/**
225
* Catch errors during rendering, lifecycle methods, and constructors
226
* @param error - The error that was thrown
227
* @param errorInfo - Information about the error
228
*/
229
componentDidCatch?(error: Error, errorInfo: ErrorInfo): void;
230
231
/**
232
* Update state in response to an error
233
* @param error - The error that was thrown
234
* @returns New state or null
235
*/
236
static getDerivedStateFromError?(error: Error): any;
237
}
238
239
interface ErrorInfo {
240
componentStack: string;
241
}
242
```
243
244
**Usage Examples:**
245
246
```javascript
247
import React, { Component } from 'react';
248
249
class ErrorBoundary extends Component {
250
constructor(props) {
251
super(props);
252
this.state = {
253
hasError: false,
254
error: null,
255
errorInfo: null
256
};
257
}
258
259
static getDerivedStateFromError(error) {
260
// Update state to show fallback UI
261
return { hasError: true };
262
}
263
264
componentDidCatch(error, errorInfo) {
265
console.error('Error caught by boundary:', error);
266
console.error('Error info:', errorInfo);
267
268
this.setState({
269
error: error,
270
errorInfo: errorInfo
271
});
272
273
// Log error to error reporting service
274
logErrorToService(error, errorInfo);
275
}
276
277
render() {
278
if (this.state.hasError) {
279
return (
280
<div className="error-boundary">
281
<h2>Something went wrong.</h2>
282
<details style={{ whiteSpace: 'pre-wrap' }}>
283
{this.state.error && this.state.error.toString()}
284
<br />
285
{this.state.errorInfo.componentStack}
286
</details>
287
<button onClick={() => this.setState({ hasError: false, error: null, errorInfo: null })}>
288
Try again
289
</button>
290
</div>
291
);
292
}
293
294
return this.props.children;
295
}
296
}
297
298
// Problem component that might throw
299
class ProblematicComponent extends Component {
300
constructor(props) {
301
super(props);
302
this.state = { counter: 0 };
303
}
304
305
handleClick = () => {
306
this.setState(({ counter }) => {
307
if (counter === 5) {
308
throw new Error('Counter reached 5!');
309
}
310
return { counter: counter + 1 };
311
});
312
};
313
314
render() {
315
return (
316
<div>
317
<p>Counter: {this.state.counter}</p>
318
<button onClick={this.handleClick}>Increment</button>
319
</div>
320
);
321
}
322
}
323
324
// Usage with error boundary
325
function App() {
326
return (
327
<div>
328
<h1>My App</h1>
329
<ErrorBoundary>
330
<ProblematicComponent />
331
</ErrorBoundary>
332
</div>
333
);
334
}
335
```
336
337
### Lifecycle Methods
338
339
Complete reference for React class component lifecycle methods.
340
341
```javascript { .api }
342
/**
343
* Component lifecycle methods
344
*/
345
interface ComponentLifecycle<P, S, SS = any> {
346
// Mounting
347
constructor?(props: P);
348
componentDidMount?(): void;
349
350
// Updating
351
shouldComponentUpdate?(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: any): boolean;
352
getSnapshotBeforeUpdate?(prevProps: Readonly<P>, prevState: Readonly<S>): SS | null;
353
componentDidUpdate?(prevProps: Readonly<P>, prevState: Readonly<S>, snapshot?: SS): void;
354
355
// Unmounting
356
componentWillUnmount?(): void;
357
358
// Error handling
359
componentDidCatch?(error: Error, errorInfo: ErrorInfo): void;
360
361
// Static methods
362
static getDerivedStateFromProps?<P, S>(props: P, state: S): Partial<S> | null;
363
static getDerivedStateFromError?(error: Error): any;
364
}
365
```
366
367
**Usage Examples:**
368
369
```javascript
370
import React, { Component } from 'react';
371
372
class DataFetcher extends Component {
373
constructor(props) {
374
super(props);
375
this.state = {
376
data: null,
377
loading: false,
378
error: null
379
};
380
}
381
382
// Static method to update state based on props
383
static getDerivedStateFromProps(nextProps, prevState) {
384
// Reset data when URL changes
385
if (nextProps.url !== prevState.previousUrl) {
386
return {
387
data: null,
388
loading: false,
389
error: null,
390
previousUrl: nextProps.url
391
};
392
}
393
return null;
394
}
395
396
// Called once after component mounts
397
componentDidMount() {
398
this.fetchData();
399
}
400
401
// Called when props or state change
402
componentDidUpdate(prevProps, prevState) {
403
// Fetch new data if URL changed
404
if (prevProps.url !== this.props.url) {
405
this.fetchData();
406
}
407
}
408
409
// Called before component unmounts
410
componentWillUnmount() {
411
// Cancel any pending requests
412
if (this.abortController) {
413
this.abortController.abort();
414
}
415
}
416
417
// Optimize re-renders
418
shouldComponentUpdate(nextProps, nextState) {
419
return (
420
nextProps.url !== this.props.url ||
421
nextState.data !== this.state.data ||
422
nextState.loading !== this.state.loading ||
423
nextState.error !== this.state.error
424
);
425
}
426
427
// Capture values before update
428
getSnapshotBeforeUpdate(prevProps, prevState) {
429
// Preserve scroll position if data was loading
430
if (prevState.loading && !this.state.loading) {
431
return window.scrollY;
432
}
433
return null;
434
}
435
436
fetchData = async () => {
437
this.setState({ loading: true, error: null });
438
439
try {
440
this.abortController = new AbortController();
441
const response = await fetch(this.props.url, {
442
signal: this.abortController.signal
443
});
444
445
if (!response.ok) {
446
throw new Error(`HTTP error! status: ${response.status}`);
447
}
448
449
const data = await response.json();
450
this.setState({ data, loading: false });
451
} catch (error) {
452
if (error.name !== 'AbortError') {
453
this.setState({ error: error.message, loading: false });
454
}
455
}
456
};
457
458
render() {
459
const { data, loading, error } = this.state;
460
461
if (loading) return <div>Loading...</div>;
462
if (error) return <div>Error: {error}</div>;
463
if (!data) return <div>No data</div>;
464
465
return (
466
<div>
467
<h2>Data:</h2>
468
<pre>{JSON.stringify(data, null, 2)}</pre>
469
</div>
470
);
471
}
472
}
473
474
// Usage
475
<DataFetcher url="https://api.example.com/users" />
476
```
477
478
## Types
479
480
```javascript { .api }
481
// Component class types
482
interface ComponentClass<P = {}, S = ComponentState> extends StaticLifecycle<P, S> {
483
new (props: P, context?: any): Component<P, S>;
484
contextType?: Context<any>;
485
defaultProps?: Partial<P>;
486
displayName?: string;
487
}
488
489
// Props with children
490
type PropsWithChildren<P> = P & { children?: ReactNode };
491
492
// Error info for error boundaries
493
interface ErrorInfo {
494
componentStack: string;
495
}
496
497
// State type
498
type ComponentState = any;
499
```