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

hooks.md docs/

1
# React Hooks
2
3
React Hooks provide a way to use state and lifecycle features in function components. They enable stateful logic reuse and eliminate the need for class components in most cases.
4
5
## Capabilities
6
7
### State Hooks
8
9
#### useState
10
11
Adds state to function components with getter and setter.
12
13
```javascript { .api }
14
/**
15
* Returns stateful value and function to update it
16
* @param initialState - Initial state value or function that returns initial state
17
* @returns Tuple with current state and state setter function
18
*/
19
function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
20
21
// State setter type
22
type Dispatch<A> = (value: A) => void;
23
type SetStateAction<S> = S | ((prevState: S) => S);
24
```
25
26
**Usage Examples:**
27
28
```javascript
29
import { useState } from 'react';
30
31
// Basic usage
32
const [count, setCount] = useState(0);
33
const [user, setUser] = useState({ name: 'John', age: 30 });
34
35
// Functional updates
36
setCount(prevCount => prevCount + 1);
37
setUser(prevUser => ({ ...prevUser, age: prevUser.age + 1 }));
38
39
// Lazy initial state
40
const [expensiveValue, setExpensiveValue] = useState(() => {
41
return computeExpensiveValue();
42
});
43
```
44
45
#### useReducer
46
47
Manages complex state with reducer pattern, alternative to useState for complex state logic.
48
49
```javascript { .api }
50
/**
51
* State management with reducer pattern
52
* @param reducer - Function that determines state updates
53
* @param initialArg - Initial state or value for lazy initialization
54
* @param init - Optional lazy initialization function
55
* @returns Tuple with current state and dispatch function
56
*/
57
function useReducer<R extends Reducer<any, any>>(
58
reducer: R,
59
initialArg: ReducerState<R>,
60
init?: ReducerStateWithoutAction<R>
61
): [ReducerState<R>, Dispatch<ReducerAction<R>>];
62
63
// Reducer types
64
type Reducer<S, A> = (prevState: S, action: A) => S;
65
type ReducerState<R extends Reducer<any, any>> = R extends Reducer<infer S, any> ? S : never;
66
type ReducerAction<R extends Reducer<any, any>> = R extends Reducer<any, infer A> ? A : never;
67
```
68
69
**Usage Examples:**
70
71
```javascript
72
import { useReducer } from 'react';
73
74
// Counter reducer
75
function counterReducer(state, action) {
76
switch (action.type) {
77
case 'increment':
78
return { count: state.count + 1 };
79
case 'decrement':
80
return { count: state.count - 1 };
81
case 'set':
82
return { count: action.payload };
83
default:
84
throw new Error();
85
}
86
}
87
88
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
89
90
// Dispatch actions
91
dispatch({ type: 'increment' });
92
dispatch({ type: 'set', payload: 42 });
93
```
94
95
### Effect Hooks
96
97
#### useEffect
98
99
Performs side effects in function components - equivalent to componentDidMount, componentDidUpdate, and componentWillUnmount combined.
100
101
```javascript { .api }
102
/**
103
* Performs side effects after render
104
* @param effect - Function containing side effect logic
105
* @param deps - Optional dependency array to control when effect runs
106
*/
107
function useEffect(effect: EffectCallback, deps?: DependencyList): void;
108
109
type EffectCallback = () => (void | Destructor);
110
type Destructor = () => void | { [UNDEFINED_VOID_ONLY]: never };
111
type DependencyList = ReadonlyArray<any>;
112
```
113
114
**Usage Examples:**
115
116
```javascript
117
import { useEffect, useState } from 'react';
118
119
function UserProfile({ userId }) {
120
const [user, setUser] = useState(null);
121
122
// Effect with dependencies
123
useEffect(() => {
124
fetchUser(userId).then(setUser);
125
}, [userId]);
126
127
// Effect with cleanup
128
useEffect(() => {
129
const timer = setInterval(() => {
130
console.log('Timer tick');
131
}, 1000);
132
133
return () => clearInterval(timer);
134
}, []);
135
136
// Effect on every render (no deps array)
137
useEffect(() => {
138
console.log('Component rendered');
139
});
140
}
141
```
142
143
#### useLayoutEffect
144
145
Synchronous version of useEffect that fires before browser paints, useful for DOM measurements.
146
147
```javascript { .api }
148
/**
149
* Synchronous side effects that fire before browser paint
150
* @param effect - Function containing side effect logic
151
* @param deps - Optional dependency array to control when effect runs
152
*/
153
function useLayoutEffect(effect: EffectCallback, deps?: DependencyList): void;
154
```
155
156
**Usage Examples:**
157
158
```javascript
159
import { useLayoutEffect, useRef } from 'react';
160
161
function MeasuredComponent() {
162
const ref = useRef();
163
164
useLayoutEffect(() => {
165
// Synchronously measure DOM before paint
166
const rect = ref.current.getBoundingClientRect();
167
console.log('Element height:', rect.height);
168
});
169
170
return <div ref={ref}>Content</div>;
171
}
172
```
173
174
#### useInsertionEffect
175
176
Special effect hook for CSS-in-JS libraries to insert styles before layout effects.
177
178
```javascript { .api }
179
/**
180
* Effect hook for CSS-in-JS libraries to insert styles
181
* @param effect - Function containing style insertion logic
182
* @param deps - Optional dependency array to control when effect runs
183
*/
184
function useInsertionEffect(effect: EffectCallback, deps?: DependencyList): void;
185
```
186
187
### Performance Hooks
188
189
#### useMemo
190
191
Memoizes expensive computations to avoid recalculation on every render.
192
193
```javascript { .api }
194
/**
195
* Memoizes expensive calculations
196
* @param factory - Function that returns value to memoize
197
* @param deps - Dependency array to determine when to recalculate
198
* @returns Memoized value
199
*/
200
function useMemo<T>(factory: () => T, deps: DependencyList): T;
201
```
202
203
**Usage Examples:**
204
205
```javascript
206
import { useMemo, useState } from 'react';
207
208
function ExpensiveComponent({ items, query }) {
209
const filteredItems = useMemo(() => {
210
return items.filter(item =>
211
item.name.toLowerCase().includes(query.toLowerCase())
212
);
213
}, [items, query]);
214
215
const expensiveValue = useMemo(() => {
216
return computeExpensiveValue(items);
217
}, [items]);
218
219
return <div>{/* render filtered items */}</div>;
220
}
221
```
222
223
#### useCallback
224
225
Memoizes functions to prevent unnecessary re-renders of child components.
226
227
```javascript { .api }
228
/**
229
* Memoizes callback functions
230
* @param callback - Function to memoize
231
* @param deps - Dependency array to determine when to recreate function
232
* @returns Memoized callback function
233
*/
234
function useCallback<T extends Function>(callback: T, deps: DependencyList): T;
235
```
236
237
**Usage Examples:**
238
239
```javascript
240
import { useCallback, useState } from 'react';
241
242
function ParentComponent({ onItemClick }) {
243
const [count, setCount] = useState(0);
244
const [items, setItems] = useState([]);
245
246
const handleClick = useCallback((id) => {
247
onItemClick(id);
248
setCount(prev => prev + 1);
249
}, [onItemClick]);
250
251
const addItem = useCallback(() => {
252
setItems(prev => [...prev, { id: Date.now() }]);
253
}, []);
254
255
return (
256
<div>
257
<ItemList items={items} onItemClick={handleClick} />
258
<button onClick={addItem}>Add Item</button>
259
</div>
260
);
261
}
262
```
263
264
### Ref Hooks
265
266
#### useRef
267
268
Creates mutable ref object that persists across re-renders.
269
270
```javascript { .api }
271
/**
272
* Creates mutable ref object
273
* @param initialValue - Initial value for the ref
274
* @returns Mutable ref object with current property
275
*/
276
function useRef<T>(initialValue: T): MutableRefObject<T>;
277
function useRef<T>(initialValue: T | null): RefObject<T>;
278
function useRef<T = undefined>(): MutableRefObject<T | undefined>;
279
280
interface MutableRefObject<T> {
281
current: T;
282
}
283
```
284
285
**Usage Examples:**
286
287
```javascript
288
import { useRef, useEffect } from 'react';
289
290
function InputComponent() {
291
const inputRef = useRef(null);
292
const countRef = useRef(0);
293
294
useEffect(() => {
295
// Focus input on mount
296
inputRef.current.focus();
297
}, []);
298
299
const handleClick = () => {
300
// Mutable value that doesn't trigger re-render
301
countRef.current += 1;
302
console.log('Click count:', countRef.current);
303
};
304
305
return (
306
<div>
307
<input ref={inputRef} />
308
<button onClick={handleClick}>Click me</button>
309
</div>
310
);
311
}
312
```
313
314
#### useImperativeHandle
315
316
Customizes the instance value exposed when using ref with forwardRef.
317
318
```javascript { .api }
319
/**
320
* Customizes ref handle for forwardRef components
321
* @param ref - Ref object to customize
322
* @param createHandle - Function that returns the custom handle
323
* @param deps - Optional dependency array
324
*/
325
function useImperativeHandle<T, R extends T>(
326
ref: Ref<T> | undefined,
327
init: () => R,
328
deps?: DependencyList
329
): void;
330
```
331
332
**Usage Examples:**
333
334
```javascript
335
import { forwardRef, useImperativeHandle, useRef } from 'react';
336
337
const CustomInput = forwardRef((props, ref) => {
338
const inputRef = useRef();
339
340
useImperativeHandle(ref, () => ({
341
focus: () => inputRef.current.focus(),
342
blur: () => inputRef.current.blur(),
343
getValue: () => inputRef.current.value,
344
}), []);
345
346
return <input ref={inputRef} {...props} />;
347
});
348
349
// Usage
350
function ParentComponent() {
351
const customInputRef = useRef();
352
353
const handleClick = () => {
354
customInputRef.current.focus();
355
console.log(customInputRef.current.getValue());
356
};
357
358
return (
359
<div>
360
<CustomInput ref={customInputRef} />
361
<button onClick={handleClick}>Focus Input</button>
362
</div>
363
);
364
}
365
```
366
367
### Context Hooks
368
369
#### useContext
370
371
Consumes context values from React context providers.
372
373
```javascript { .api }
374
/**
375
* Consumes context value from nearest provider
376
* @param context - Context object created by createContext
377
* @returns Current context value
378
*/
379
function useContext<T>(context: Context<T>): T;
380
```
381
382
**Usage Examples:**
383
384
```javascript
385
import { createContext, useContext } from 'react';
386
387
const ThemeContext = createContext('light');
388
const UserContext = createContext(null);
389
390
function ThemedButton() {
391
const theme = useContext(ThemeContext);
392
const user = useContext(UserContext);
393
394
return (
395
<button className={`btn-${theme}`}>
396
Hello, {user?.name || 'Guest'}
397
</button>
398
);
399
}
400
401
function App() {
402
const user = { name: 'John', id: 1 };
403
404
return (
405
<ThemeContext.Provider value="dark">
406
<UserContext.Provider value={user}>
407
<ThemedButton />
408
</UserContext.Provider>
409
</ThemeContext.Provider>
410
);
411
}
412
```
413
414
### Concurrent Features Hooks
415
416
#### useTransition
417
418
Marks state updates as non-urgent transitions to avoid blocking urgent updates.
419
420
```javascript { .api }
421
/**
422
* Marks state updates as non-urgent transitions
423
* @returns Tuple with isPending boolean and startTransition function
424
*/
425
function useTransition(): [boolean, (callback: () => void) => void];
426
```
427
428
**Usage Examples:**
429
430
```javascript
431
import { useTransition, useState } from 'react';
432
433
function SearchComponent() {
434
const [query, setQuery] = useState('');
435
const [results, setResults] = useState([]);
436
const [isPending, startTransition] = useTransition();
437
438
const handleSearch = (newQuery) => {
439
setQuery(newQuery); // Urgent update
440
441
startTransition(() => {
442
// Non-urgent update that won't block typing
443
setResults(performExpensiveSearch(newQuery));
444
});
445
};
446
447
return (
448
<div>
449
<input
450
value={query}
451
onChange={(e) => handleSearch(e.target.value)}
452
/>
453
{isPending && <div>Searching...</div>}
454
<ResultsList results={results} />
455
</div>
456
);
457
}
458
```
459
460
#### useDeferredValue
461
462
Defers updating a value to avoid blocking urgent updates.
463
464
```javascript { .api }
465
/**
466
* Defers value updates for performance
467
* @param value - Value to defer
468
* @returns Deferred version of the value
469
*/
470
function useDeferredValue<T>(value: T): T;
471
```
472
473
**Usage Examples:**
474
475
```javascript
476
import { useDeferredValue, useState, useMemo } from 'react';
477
478
function ProductList({ products }) {
479
const [filter, setFilter] = useState('');
480
const deferredFilter = useDeferredValue(filter);
481
482
const filteredProducts = useMemo(() => {
483
return products.filter(product =>
484
product.name.includes(deferredFilter)
485
);
486
}, [products, deferredFilter]);
487
488
return (
489
<div>
490
<input
491
value={filter}
492
onChange={(e) => setFilter(e.target.value)}
493
placeholder="Filter products..."
494
/>
495
<div>
496
{filteredProducts.map(product => (
497
<ProductCard key={product.id} product={product} />
498
))}
499
</div>
500
</div>
501
);
502
}
503
```
504
505
### Utility Hooks
506
507
#### useId
508
509
Generates stable unique IDs for accessibility attributes.
510
511
```javascript { .api }
512
/**
513
* Generates unique IDs for accessibility
514
* @returns Stable unique ID string
515
*/
516
function useId(): string;
517
```
518
519
**Usage Examples:**
520
521
```javascript
522
import { useId } from 'react';
523
524
function FormField({ label, ...props }) {
525
const id = useId();
526
527
return (
528
<div>
529
<label htmlFor={id}>{label}</label>
530
<input id={id} {...props} />
531
</div>
532
);
533
}
534
535
function LoginForm() {
536
const passwordHintId = useId();
537
538
return (
539
<form>
540
<FormField label="Username" type="text" />
541
<FormField
542
label="Password"
543
type="password"
544
aria-describedby={passwordHintId}
545
/>
546
<div id={passwordHintId}>
547
Password must be at least 8 characters
548
</div>
549
</form>
550
);
551
}
552
```
553
554
#### useDebugValue
555
556
Displays custom labels for custom hooks in React DevTools.
557
558
```javascript { .api }
559
/**
560
* Displays debug labels in React DevTools
561
* @param value - Value to display
562
* @param format - Optional formatting function
563
*/
564
function useDebugValue<T>(value: T, format?: (value: T) => any): void;
565
```
566
567
**Usage Examples:**
568
569
```javascript
570
import { useDebugValue, useState, useEffect } from 'react';
571
572
function useOnlineStatus() {
573
const [isOnline, setIsOnline] = useState(navigator.onLine);
574
575
useEffect(() => {
576
const handleOnline = () => setIsOnline(true);
577
const handleOffline = () => setIsOnline(false);
578
579
window.addEventListener('online', handleOnline);
580
window.addEventListener('offline', handleOffline);
581
582
return () => {
583
window.removeEventListener('online', handleOnline);
584
window.removeEventListener('offline', handleOffline);
585
};
586
}, []);
587
588
// Show in DevTools
589
useDebugValue(isOnline ? 'Online' : 'Offline');
590
591
return isOnline;
592
}
593
594
function useLocalStorage(key, initialValue) {
595
const [storedValue, setStoredValue] = useState(() => {
596
try {
597
const item = window.localStorage.getItem(key);
598
return item ? JSON.parse(item) : initialValue;
599
} catch (error) {
600
return initialValue;
601
}
602
});
603
604
// Custom format function
605
useDebugValue({key, storedValue}, ({key, storedValue}) =>
606
`${key}: ${JSON.stringify(storedValue)}`
607
);
608
609
return [storedValue, setStoredValue];
610
}
611
```
612
613
### External Store Hooks
614
615
#### useSyncExternalStore
616
617
Subscribes to external data stores and syncs with React's rendering.
618
619
```javascript { .api }
620
/**
621
* Subscribes to external data stores
622
* @param subscribe - Function to subscribe to store changes
623
* @param getSnapshot - Function to get current store value
624
* @param getServerSnapshot - Optional server-side snapshot getter
625
* @returns Current store value
626
*/
627
function useSyncExternalStore<Snapshot>(
628
subscribe: (onStoreChange: () => void) => () => void,
629
getSnapshot: () => Snapshot,
630
getServerSnapshot?: () => Snapshot
631
): Snapshot;
632
```
633
634
**Usage Examples:**
635
636
```javascript
637
import { useSyncExternalStore } from 'react';
638
639
// External store example
640
const store = {
641
state: { count: 0 },
642
listeners: new Set(),
643
644
getState() {
645
return this.state;
646
},
647
648
setState(newState) {
649
this.state = { ...this.state, ...newState };
650
this.listeners.forEach(listener => listener());
651
},
652
653
subscribe(listener) {
654
this.listeners.add(listener);
655
return () => this.listeners.delete(listener);
656
}
657
};
658
659
function useStore() {
660
return useSyncExternalStore(
661
store.subscribe.bind(store),
662
store.getState.bind(store)
663
);
664
}
665
666
function Counter() {
667
const state = useStore();
668
669
return (
670
<div>
671
<p>Count: {state.count}</p>
672
<button onClick={() => store.setState({ count: state.count + 1 })}>
673
Increment
674
</button>
675
</div>
676
);
677
}
678
```
679
680
#### useMutableSource
681
682
Legacy hook for subscribing to mutable external sources (deprecated in favor of useSyncExternalStore).
683
684
```javascript { .api }
685
/**
686
* Subscribe to mutable external data sources (deprecated)
687
* @param source - Mutable source created by createMutableSource
688
* @param getSnapshot - Function to get current value from source
689
* @param subscribe - Function to subscribe to source changes
690
* @returns Current source value
691
*/
692
function useMutableSource<Source, Snapshot>(
693
source: MutableSource<Source>,
694
getSnapshot: MutableSourceGetSnapshotFn<Source, Snapshot>,
695
subscribe: MutableSourceSubscribeFn<Source, Snapshot>
696
): Snapshot;
697
```