npm-react

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

How to use

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

utilities.md docs/

1
# Utilities
2
3
Utility functions for working with React elements, children manipulation, and development tools. These utilities provide helpful functions for common React operations.
4
5
## Capabilities
6
7
### isValidElement
8
9
Verifies whether an object is a valid React element.
10
11
```typescript { .api }
12
/**
13
* Checks if object is a valid React element
14
* @param object - Object to test
15
* @returns True if object is a React element
16
*/
17
function isValidElement(object: any): object is React.ReactElement;
18
```
19
20
**Usage Examples:**
21
22
```typescript
23
import React, { isValidElement } from "react";
24
25
function SafeRenderer({ content }: { content: unknown }) {
26
if (isValidElement(content)) {
27
return <div>{content}</div>;
28
}
29
30
if (typeof content === "string") {
31
return <span>{content}</span>;
32
}
33
34
if (typeof content === "number") {
35
return <span>{content.toString()}</span>;
36
}
37
38
return <span>Invalid content</span>;
39
}
40
41
// Usage examples
42
const validElement = <p>Hello</p>;
43
const invalidContent = { foo: "bar" };
44
45
console.log(isValidElement(validElement)); // true
46
console.log(isValidElement("string")); // false
47
console.log(isValidElement(123)); // false
48
console.log(isValidElement(invalidContent)); // false
49
50
function ConditionalRenderer({ items }: { items: unknown[] }) {
51
return (
52
<div>
53
{items.map((item, index) => {
54
if (isValidElement(item)) {
55
return <div key={index}>{item}</div>;
56
}
57
return <div key={index}>Not a React element</div>;
58
})}
59
</div>
60
);
61
}
62
```
63
64
### cloneElement
65
66
Clones and returns a new React element using the original element as the starting point.
67
68
```typescript { .api }
69
/**
70
* Clones a React element with new props
71
* @param element - Element to clone
72
* @param props - Additional or replacement props
73
* @param children - New children (replaces existing children)
74
* @returns Cloned React element
75
*/
76
function cloneElement<P>(
77
element: React.ReactElement<P>,
78
props?: Partial<P> & React.Attributes,
79
...children: React.ReactNode[]
80
): React.ReactElement<P>;
81
```
82
83
**Usage Examples:**
84
85
```typescript
86
import React, { cloneElement } from "react";
87
88
function Button({
89
className = "",
90
onClick,
91
children
92
}: {
93
className?: string;
94
onClick?: () => void;
95
children: React.ReactNode;
96
}) {
97
return (
98
<button className={`btn ${className}`} onClick={onClick}>
99
{children}
100
</button>
101
);
102
}
103
104
function ButtonGroup({ children }: { children: React.ReactNode }) {
105
return (
106
<div className="button-group">
107
{React.Children.map(children, (child, index) => {
108
if (isValidElement(child) && child.type === Button) {
109
// Clone button with additional props
110
return cloneElement(child, {
111
className: `${child.props.className || ""} group-item`,
112
onClick: () => {
113
console.log(`Button ${index} clicked`);
114
child.props.onClick?.();
115
}
116
});
117
}
118
return child;
119
})}
120
</div>
121
);
122
}
123
124
// Usage
125
function App() {
126
return (
127
<ButtonGroup>
128
<Button onClick={() => alert("Save clicked")}>Save</Button>
129
<Button onClick={() => alert("Cancel clicked")}>Cancel</Button>
130
<Button className="danger">Delete</Button>
131
</ButtonGroup>
132
);
133
}
134
135
// Advanced cloning with children replacement
136
function WrapperComponent({ children }: { children: React.ReactNode }) {
137
return (
138
<div>
139
{React.Children.map(children, (child) => {
140
if (isValidElement(child)) {
141
return cloneElement(
142
child,
143
{ className: "wrapped" },
144
<span>🎁</span>, // Replace children
145
child.props.children
146
);
147
}
148
return child;
149
})}
150
</div>
151
);
152
}
153
```
154
155
### Children Utilities
156
157
Utilities for working with the children prop in React components.
158
159
```typescript { .api }
160
/**
161
* Utilities for manipulating children
162
*/
163
const Children: {
164
/**
165
* Maps over children and returns an array
166
* @param children - Children to map over
167
* @param fn - Function to call for each child
168
* @returns Array of mapped children
169
*/
170
map<T, C>(
171
children: C | readonly C[],
172
fn: (child: C, index: number) => T
173
): C extends null | undefined ? C : Array<Exclude<T, boolean | null | undefined>>;
174
175
/**
176
* Iterates over children
177
* @param children - Children to iterate over
178
* @param fn - Function to call for each child
179
*/
180
forEach<C>(
181
children: C | readonly C[],
182
fn: (child: C, index: number) => void
183
): void;
184
185
/**
186
* Counts the number of children
187
* @param children - Children to count
188
* @returns Number of children
189
*/
190
count(children: any): number;
191
192
/**
193
* Converts children to an array
194
* @param children - Children to convert
195
* @returns Array of children
196
*/
197
toArray(children: React.ReactNode | React.ReactNode[]): React.ReactElement[];
198
199
/**
200
* Returns the only child (throws if more than one)
201
* @param children - Children (must be exactly one)
202
* @returns Single child
203
*/
204
only<T>(children: T): T extends any[] ? never : T;
205
};
206
```
207
208
**Usage Examples:**
209
210
```typescript
211
import React, { Children } from "react";
212
213
// Children.map example
214
function List({ children }: { children: React.ReactNode }) {
215
return (
216
<ul>
217
{Children.map(children, (child, index) => (
218
<li key={index} className="list-item">
219
{child}
220
</li>
221
))}
222
</ul>
223
);
224
}
225
226
// Children.forEach example
227
function DebugChildren({ children }: { children: React.ReactNode }) {
228
Children.forEach(children, (child, index) => {
229
console.log(`Child ${index}:`, child);
230
});
231
232
return <div>{children}</div>;
233
}
234
235
// Children.count example
236
function ChildCounter({ children }: { children: React.ReactNode }) {
237
const count = Children.count(children);
238
239
return (
240
<div>
241
<p>Number of children: {count}</p>
242
{children}
243
</div>
244
);
245
}
246
247
// Children.toArray example
248
function ReversedChildren({ children }: { children: React.ReactNode }) {
249
const childArray = Children.toArray(children);
250
const reversed = childArray.reverse();
251
252
return <div>{reversed}</div>;
253
}
254
255
// Children.only example
256
function SingleChildWrapper({ children }: { children: React.ReactNode }) {
257
const onlyChild = Children.only(children);
258
259
return (
260
<div className="wrapper">
261
<h2>Single Child:</h2>
262
{onlyChild}
263
</div>
264
);
265
}
266
267
// Usage examples
268
function App() {
269
return (
270
<div>
271
<List>
272
<span>Item 1</span>
273
<span>Item 2</span>
274
<span>Item 3</span>
275
</List>
276
277
<ChildCounter>
278
<p>First child</p>
279
<p>Second child</p>
280
</ChildCounter>
281
282
<ReversedChildren>
283
<div>First</div>
284
<div>Second</div>
285
<div>Third</div>
286
</ReversedChildren>
287
288
<SingleChildWrapper>
289
<button>Only Button</button>
290
</SingleChildWrapper>
291
</div>
292
);
293
}
294
```
295
296
### Development and Testing Utilities
297
298
#### act
299
300
Testing utility for wrapping code that triggers React updates.
301
302
```typescript { .api }
303
/**
304
* Wraps code that triggers React updates for testing
305
* @param callback - Function that triggers React updates
306
* @returns Promise that resolves when updates are complete
307
*/
308
function act<T>(callback: () => T | Promise<T>): Promise<T>;
309
```
310
311
**Usage Examples:**
312
313
```typescript
314
import React, { useState } from "react";
315
import { act } from "react";
316
import { render, screen } from "@testing-library/react";
317
318
function Counter() {
319
const [count, setCount] = useState(0);
320
321
return (
322
<div>
323
<span data-testid="count">{count}</span>
324
<button onClick={() => setCount(c => c + 1)}>
325
Increment
326
</button>
327
</div>
328
);
329
}
330
331
// Test example (with testing library)
332
test("counter increments", async () => {
333
render(<Counter />);
334
335
const button = screen.getByText("Increment");
336
const countElement = screen.getByTestId("count");
337
338
expect(countElement).toHaveTextContent("0");
339
340
// Wrap state updates in act
341
await act(async () => {
342
button.click();
343
});
344
345
expect(countElement).toHaveTextContent("1");
346
});
347
348
// Manual testing with act
349
async function testCounterManually() {
350
const container = document.createElement("div");
351
document.body.appendChild(container);
352
353
// Initial render
354
await act(async () => {
355
ReactDOM.render(<Counter />, container);
356
});
357
358
const button = container.querySelector("button");
359
const span = container.querySelector("span");
360
361
console.log("Initial count:", span?.textContent); // "0"
362
363
// Simulate click
364
await act(async () => {
365
button?.click();
366
});
367
368
console.log("After click:", span?.textContent); // "1"
369
370
// Cleanup
371
document.body.removeChild(container);
372
}
373
```
374
375
#### captureOwnerStack
376
377
Development-only function for capturing the current React component owner stack for debugging.
378
379
```typescript { .api }
380
/**
381
* Captures the current React component owner stack for debugging purposes
382
* @returns Stack trace string or null (only available in development builds)
383
*/
384
function captureOwnerStack(): string | null;
385
```
386
387
**Usage Examples:**
388
389
```typescript
390
import React, { captureOwnerStack } from "react";
391
392
function DebugButton() {
393
const handleClick = () => {
394
// Capture the current component stack for debugging
395
const stack = captureOwnerStack();
396
console.log("Component stack:", stack);
397
};
398
399
return <button onClick={handleClick}>Debug Stack</button>;
400
}
401
402
function Parent() {
403
return (
404
<div>
405
<h1>Parent Component</h1>
406
<Child />
407
</div>
408
);
409
}
410
411
function Child() {
412
return (
413
<div>
414
<h2>Child Component</h2>
415
<DebugButton />
416
</div>
417
);
418
}
419
420
// Custom hook for debugging component hierarchies
421
function useComponentStack() {
422
React.useEffect(() => {
423
if (process.env.NODE_ENV === 'development') {
424
const stack = captureOwnerStack();
425
console.log("Component mounted with stack:", stack);
426
}
427
}, []);
428
}
429
430
function TrackedComponent() {
431
useComponentStack();
432
return <div>This component tracks its stack</div>;
433
}
434
```
435
436
#### Version Information
437
438
```typescript { .api }
439
/**
440
* React version string
441
*/
442
const version: string;
443
```
444
445
**Usage Examples:**
446
447
```typescript
448
import React from "react";
449
450
console.log("React version:", React.version); // "19.1.0"
451
452
function VersionDisplay() {
453
return (
454
<div>
455
<p>Running React {React.version}</p>
456
</div>
457
);
458
}
459
460
// Feature detection based on version
461
function hasFeature(feature: string): boolean {
462
const [major, minor] = React.version.split(".").map(Number);
463
464
switch (feature) {
465
case "concurrent":
466
return major >= 18;
467
case "suspense":
468
return major >= 16 && minor >= 6;
469
case "hooks":
470
return major >= 16 && minor >= 8;
471
default:
472
return false;
473
}
474
}
475
```
476
477
## Advanced Utility Patterns
478
479
### Dynamic Children Manipulation
480
481
```typescript
482
import React, { Children, cloneElement, isValidElement } from "react";
483
484
interface TabsProps {
485
activeTab: string;
486
children: React.ReactNode;
487
}
488
489
interface TabProps {
490
id: string;
491
label: string;
492
children: React.ReactNode;
493
}
494
495
function Tab({ children }: TabProps) {
496
return <div>{children}</div>;
497
}
498
499
function Tabs({ activeTab, children }: TabsProps) {
500
const tabs = Children.toArray(children).filter(
501
child => isValidElement(child) && child.type === Tab
502
) as React.ReactElement<TabProps>[];
503
504
return (
505
<div>
506
<nav>
507
{tabs.map(tab => (
508
<button
509
key={tab.props.id}
510
className={activeTab === tab.props.id ? "active" : ""}
511
>
512
{tab.props.label}
513
</button>
514
))}
515
</nav>
516
517
<div>
518
{tabs.map(tab => {
519
if (tab.props.id === activeTab) {
520
return cloneElement(tab, { key: tab.props.id });
521
}
522
return null;
523
})}
524
</div>
525
</div>
526
);
527
}
528
529
// Usage
530
function App() {
531
return (
532
<Tabs activeTab="profile">
533
<Tab id="home" label="Home">
534
<h2>Home Content</h2>
535
</Tab>
536
<Tab id="profile" label="Profile">
537
<h2>Profile Content</h2>
538
</Tab>
539
<Tab id="settings" label="Settings">
540
<h2>Settings Content</h2>
541
</Tab>
542
</Tabs>
543
);
544
}
545
```
546
547
### Conditional Child Rendering
548
549
```typescript
550
import React, { Children } from "react";
551
552
interface ConditionalProps {
553
condition: boolean;
554
children: React.ReactNode;
555
fallback?: React.ReactNode;
556
}
557
558
function Conditional({ condition, children, fallback }: ConditionalProps) {
559
if (!condition) {
560
return <>{fallback}</>;
561
}
562
563
return (
564
<>
565
{Children.map(children, (child, index) => {
566
if (isValidElement(child)) {
567
return cloneElement(child, {
568
key: child.key || index,
569
"data-conditional": true
570
});
571
}
572
return child;
573
})}
574
</>
575
);
576
}
577
578
function App() {
579
const [showContent, setShowContent] = React.useState(false);
580
581
return (
582
<div>
583
<button onClick={() => setShowContent(!showContent)}>
584
Toggle Content
585
</button>
586
587
<Conditional
588
condition={showContent}
589
fallback={<p>Content is hidden</p>}
590
>
591
<h1>Main Content</h1>
592
<p>This content is conditionally rendered</p>
593
</Conditional>
594
</div>
595
);
596
}
597
```
598
599
## Server-Side Security Functions
600
601
Functions for server-side security and data protection in React Server Components.
602
603
### taintUniqueValue
604
605
Taints a unique value to prevent it from being sent to the client.
606
607
```typescript { .api }
608
/**
609
* Taints a unique value for server-side security
610
* @param message - Error message to show if value is accessed on client
611
* @param lifetime - Lifetime object for the taint
612
* @param value - Value to taint
613
*/
614
function taintUniqueValue(
615
message: string,
616
lifetime: any,
617
value: any
618
): void;
619
```
620
621
**Usage Examples:**
622
623
```typescript
624
import { taintUniqueValue } from "react";
625
626
// Taint sensitive data on the server
627
function ServerComponent() {
628
const apiKey = process.env.SECRET_API_KEY;
629
630
// Prevent API key from being sent to client
631
taintUniqueValue(
632
"API key cannot be used on the client",
633
globalThis,
634
apiKey
635
);
636
637
return <div>Server rendered content</div>;
638
}
639
```
640
641
### taintObjectReference
642
643
Taints an object reference to prevent it from being sent to the client.
644
645
```typescript { .api }
646
/**
647
* Taints an object reference for server-side security
648
* @param message - Error message to show if object is accessed on client
649
* @param object - Object to taint
650
*/
651
function taintObjectReference(
652
message: string,
653
object: any
654
): void;
655
```
656
657
**Usage Examples:**
658
659
```typescript
660
import { taintObjectReference } from "react";
661
662
// Taint server-only objects
663
function ServerDataProcessor() {
664
const serverDatabase = getServerDatabase();
665
666
// Prevent database connection from being sent to client
667
taintObjectReference(
668
"Database connection cannot be used on the client",
669
serverDatabase
670
);
671
672
return <div>Processing server data</div>;
673
}
674
```
675
676
## Types
677
678
### Utility-Related Types
679
680
```typescript { .api }
681
interface ReactChildren {
682
map<T, C>(
683
children: C | readonly C[],
684
fn: (child: C, index: number) => T
685
): C extends null | undefined ? C : Array<Exclude<T, boolean | null | undefined>>;
686
687
forEach<C>(
688
children: C | readonly C[],
689
fn: (child: C, index: number) => void
690
): void;
691
692
count(children: any): number;
693
toArray(children: ReactNode | ReactNode[]): ReactElement[];
694
only<T>(children: T): T extends any[] ? never : T;
695
}
696
697
type ReactText = string | number;
698
type ReactChild = ReactElement | ReactText;
699
type ReactFragment = {} | Iterable<ReactNode>;
700
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
701
702
interface Attributes {
703
key?: Key | null;
704
}
705
706
interface ClassAttributes<T> extends Attributes {
707
ref?: Ref<T>;
708
}
709
710
type CloneElement = <P>(
711
element: ReactElement<P>,
712
props?: Partial<P> & Attributes,
713
...children: ReactNode[]
714
) => ReactElement<P>;
715
```