- useEventListener()
- useReducerWithDeps()
- useStateWithDeps()
- contextualize()
- createSafeContext()
- wrapJSX()
- React ≥ 18
- TypeScript ≥ 5.4
const useEventListener: UseEventListener;
Defined in: hooks/useEventListener.ts:135
Adds handler
as a listener for the event eventName
of target
with the
provided options
applied
The following call signatures are available:
function useEventListener(eventName, handler, options?): void;
function useEventListener(target, eventName, handler, options?): void;
For the full definition of the hook's type, see UseEventListener
.
If target
is not provided, window
is used instead.
If target
is null
, no event listener is added. This is useful when
working with DOM element refs, or when the event listener needs to be removed
temporarily.
useEventListener('resize', () => {
console.log(window.innerWidth, window.innerHeight);
});
useEventListener(document, 'visibilitychange', () => {
console.log(document.visibilityState);
});
const buttonRef = useRef<HTMLButtonElement>(null);
useEventListener(buttonRef, 'click', () => console.log('click'));
function useReducerWithDeps<S, A>(
reducer,
initialState,
deps,
): [S, ActionDispatch<A>];
Defined in: hooks/useReducerWithDeps.ts:59
useReducer
hook with an additional dependency array deps
that resets the
state to initialState
when dependencies change
This hook is the reducer pattern counterpart of useStateWithDeps
.
Due to React's limitations, a change in dependencies always causes two renders when using this hook. The result of the first render is thrown away as described in useState > Storing information from previous renders.
For motivation and examples, see facebook/react#33041.
The react-hooks/exhaustive-deps
ESLint rule doesn't support hooks where
the dependency array parameter is at any other position than the second.
However, as we would like to keep the hook as compatible with useReducer
as
possible, we don't want to artificially change the parameter's position.
Therefore, there will be no warnings about missing dependencies.
Because of that, additional caution is advised!
Be sure to check that no dependencies are missing from the deps
array.
Related issue: facebook/react#25443.
Unlike eslint-plugin-react-hooks
maintained by React's team, the unofficial
useExhaustiveDependencies
rule provided for Biome by Biome's team
does actually have support for dependency arrays at other positions, see
useExhaustiveDependencies > Options > Validating dependencies.
Type Parameter |
---|
|
|
Parameter | Type | Description |
---|---|---|
|
( |
The reducer function that specifies how the state gets updated |
|
|
The value to which the state is set when the component is mounted or dependencies change It can also be a function that returns a state value. If the state is reset
due to a change of dependencies, this function will be passed the previous
state as its argument (will be |
|
|
Dependencies that reset the state to |
[S
, ActionDispatch
<A
>]
function useStateWithDeps<S>(
initialState,
deps,
): [S, Dispatch<SetStateAction<S>>];
Defined in: hooks/useStateWithDeps.ts:62
useState
hook with an additional dependency array deps
that resets the
state to initialState
when dependencies change
Due to React's limitations, a change in dependencies always causes two renders when using this hook. The result of the first render is thrown away as described in useState > Storing information from previous renders.
For motivation and more examples, see facebook/react#33041.
type Activity = 'breakfast' | 'exercise' | 'swim' | 'board games' | 'dinner';
const timeOfDayOptions = ['morning', 'afternoon', 'evening'] as const;
type TimeOfDay = (typeof timeOfDayOptions)[number];
const activityOptionsByTimeOfDay: {
[K in TimeOfDay]: [Activity, ...Activity[]];
} = {
morning: ['breakfast', 'exercise', 'swim'],
afternoon: ['exercise', 'swim', 'board games'],
evening: ['board games', 'dinner'],
};
function Example() {
const [timeOfDay, setTimeOfDay] = useState<TimeOfDay>('morning');
const activityOptions = activityOptionsByTimeOfDay[timeOfDay];
const [activity, setActivity] = useStateWithDeps<Activity>(
(prev) => {
// Make sure activity is always valid for the current timeOfDay value,
// but also don't reset it unless necessary:
return prev && activityOptions.includes(prev) ? prev : activityOptions[0];
},
[activityOptions],
);
return '...';
}
Type Parameter |
---|
|
Parameter | Type | Description |
---|---|---|
|
|
The value to which the state is set when the component is mounted or dependencies change It can also be a function that returns a state value. If the state is reset
due to a change of dependencies, this function will be passed the previous
state as its argument (will be |
|
|
Dependencies that reset the state to |
[S
, Dispatch
<SetStateAction
<S
>>]
function contextualize<Children>(children): ContextualizePipe<Children>;
Defined in: misc/contextualize.tsx:79
An alternative way to provide context values to component trees that avoids ever-increasing indentation
A context-specific version of the more general wrapJSX
function.
// Before:
return (
<CourseIdContext.Provider value={courseId}>
<DeckIdContext.Provider value={deckId}>
<FlashcardsContext.Provider value={flashcards}>
<EventHandlersContext.Provider value={eventHandlers}>
<Header />
<Main />
<Footer />
</EventHandlersContext.Provider>
</FlashcardsContext.Provider>
</DeckIdContext.Provider>
</CourseIdContext.Provider>
);
// After:
const jsx = (
<>
<Header />
<Main />
<Footer />
</>
);
return contextualize(jsx)
.with(EventHandlersContext, eventHandlers)
.with(FlashcardsContext, flashcards)
.with(DeckIdContext, deckId)
.with(CourseIdContext, courseId)
.end();
Type Parameter |
---|
|
Parameter | Type | Description |
---|---|---|
|
|
The children to contextualize |
ContextualizePipe
<Children
>
An object with the following properties:
with
: a function that accepts a contextContext
and a valuevalue
for it as arguments and returnscontextualize(<Context.Provider value={value}>{children}</Context.Provider>)
end
: a function that returnschildren
function createSafeContext<T>(): <DisplayName>(displayName) => {
[K in `${string}Context`]: Context<T>;
} & {
[K in `use${string}`]: () => T;
};
Defined in: misc/createSafeContext.ts:62
For a given type T
, returns a function that produces both a context of that
type and a hook that returns the current context value if one was provided,
or throws an error otherwise
The advantages over vanilla createContext
are that no default value has to
be provided, and that a meaningful context name is displayed in dev tools
instead of generic Context.Provider
.
enum Direction {
Up,
Down,
Left,
Right,
}
// Before:
const DirectionContext = createContext<Direction | undefined>(undefined);
DirectionContext.displayName = 'DirectionContext';
const useDirection = () => {
const direction = useContext(DirectionContext);
if (direction === undefined) {
// Called outside of a <DirectionContext.Provider> boundary!
// Or maybe undefined was explicitly provided as the context value
// (ideally that shouldn't be allowed, but it is because we had to include
// undefined in the context type so as to provide a meaningful default)
throw new Error('No DirectionContext value was provided');
}
// Thanks to the undefined check, the type is now narrowed down to Direction
return direction;
};
// After:
const { DirectionContext, useDirection } =
createSafeContext<Direction>()('Direction'); // That's it :)
const Parent = () => (
// Providing undefined as the value is not allowed 👍
<Direction.Provider value={Direction.Up}>
<Child />
</Direction.Provider>
);
const Child = () => `Current direction: ${Direction[useDirection()]}`;
Type Parameter | Default type |
---|---|
|
|
A function that accepts a single string argument displayName
(e.g.
"Direction"
) and returns an object with the following properties:
`${displayName}Context`
(e.g.DirectionContext
): the context`use${displayName}`
(e.g.useDirection
): a hook that returns the current context value if one was provided, or throws an error otherwise
<DisplayName>(displayName): { [K in `${string}Context`]: Context<T> } & { [K in `use${string}`]: () => T };
Type Parameter |
---|
|
Parameter | Type |
---|---|
|
[ |
{ [K in `${string}Context`]: Context<T> }
& { [K in `use${string}`]: () => T }
function wrapJSX<Children>(children): JSXWrapPipe<Children>;
Defined in: misc/wrapJSX.tsx:99
An alternative way to compose JSX that avoids ever-increasing indentation
A more general version of the context-specific contextualize
function.
// Before:
createRoot(document.getElementById('root')!).render(
<StrictMode>
<I18nextProvider i18n={i18n}>
<QueryClientProvider client={queryClient}>
<NuqsAdapter>
<ThemeProvider theme={theme}>
<ToasterProvider>
<App />
</ToasterProvider>
</ThemeProvider>
</NuqsAdapter>
</QueryClientProvider>
</I18nextProvider>
</StrictMode>,
);
// After:
createRoot(document.getElementById('root')!).render(
wrapJSX(<App />)
.with(ToasterProvider)
.with(ThemeProvider, { theme })
.with(NuqsAdapter)
.with(QueryClientProvider, { client: queryClient })
.with(I18nextProvider, { i18n })
.with(StrictMode)
.end(),
);
Type Parameter |
---|
|
Parameter | Type | Description |
---|---|---|
|
|
The children to wrap |
JSXWrapPipe
<Children
>
An object with the following properties:
with
: a function that accepts a componentComponent
and propsprops
for it as arguments and returnswrapJSX(<Component {...props}>{children}</Component>)
end
: a function that returnschildren
type UseEventListener = UseEventListenerWithImplicitWindowTarget &
UseEventListenerWithExplicitGlobalTarget &
UseEventListenerWithAnyExplicitTarget;
Defined in: hooks/useEventListener.ts:12
The type of useEventListener
useEventListener
,
UseEventListenerWithImplicitWindowTarget
,
UseEventListenerWithExplicitGlobalTarget
,
UseEventListenerWithAnyExplicitTarget
type UseEventListenerWithImplicitWindowTarget = <K>(...args) => void;
Defined in: hooks/useEventListener.ts:21
Type Parameter |
---|
|
Parameter | Type |
---|---|
... |
void
useEventListener
,
UseEventListenerWithImplicitWindowTargetArgs
type UseEventListenerWithExplicitGlobalTarget =
UseEventListenerWithExplicitTarget<Window, WindowEventMap> &
UseEventListenerWithExplicitTarget<Document, DocumentEventMap> &
UseEventListenerWithExplicitTarget<HTMLElement, HTMLElementEventMap> &
UseEventListenerWithExplicitTarget<SVGElement, SVGElementEventMap> &
UseEventListenerWithExplicitTarget<MathMLElement, MathMLElementEventMap>;
Defined in: hooks/useEventListener.ts:32
useEventListener
,
UseEventListenerWithExplicitTarget
type UseEventListenerWithExplicitTarget<Target, EventMap> = <T, K>(
...args
) => void;
Defined in: hooks/useEventListener.ts:44
Type Parameter |
---|
|
|
Type Parameter |
---|
|
|
Parameter | Type |
---|---|
... |
|
void
useEventListener
,
UseEventListenerWithExplicitTargetArgs
type UseEventListenerWithAnyExplicitTarget = UseEventListenerWithExplicitTarget<
EventTarget,
Record<string, Event>
>;
Defined in: hooks/useEventListener.ts:56
useEventListener
,
UseEventListenerWithExplicitTarget
type UseEventListenerWithImplicitWindowTargetArgs<K> =
UseEventListenerWithExplicitTargetArgs<WindowEventMap, Window, K> extends [
unknown,
...infer Args,
]
? Args
: never;
Defined in: hooks/useEventListener.ts:64
Type Parameter |
---|
|
useEventListener
,
UseEventListenerWithExplicitTargetArgs
type UseEventListenerWithExplicitTargetArgs<EventMap, T, K> = [
(
| T
| (RefObject<T> & {
addEventListener?: never;
})
| null
),
K,
(this, event) => void,
AddEventListenerOptions | boolean | undefined,
];
Defined in: hooks/useEventListener.ts:78
Type Parameter |
---|
|
|
|
type ContextualizePipe<Children> = {
with: ContextualizeWith;
end: () => Children;
};
Defined in: misc/contextualize.tsx:13
The return type of contextualize
contextualize
,
ContextualizeWith
Type Parameter |
---|
|
Property | Type |
---|---|
() => |
type ContextualizeWith = <T>(Context, value) => ContextualizePipe<ReactElement>;
Defined in: misc/contextualize.tsx:23
Type Parameter |
---|
|
Parameter | Type |
---|---|
|
|
|
|
ContextualizePipe
<ReactElement
>
contextualize
,
ContextualizePipe
type JSXWrapPipe<Children> = {
with: WrapJSXWith<Children>;
end: () => Children;
};
Defined in: misc/wrapJSX.tsx:19
The return type of wrapJSX
Type Parameter |
---|
|
Property | Type |
---|---|
|
|
() => |
type WrapJSXWith<Children> = <C>(...args) => JSXWrapPipe<ReactElement>;
Defined in: misc/wrapJSX.tsx:29
Type Parameter |
---|
|
Type Parameter |
---|
|
Parameter | Type |
---|---|
... |
[ |
JSXWrapPipe
<ReactElement
>