[](https://www.npmjs.com/package/@aweebit/react-essentials)
npm install @aweebit/react-essentials
- useEventListener()
- useIsomorphicLayoutEffect()
- useReducerWithDeps()
- useStateWithDeps()
- contextualize()
- createSafeContext()
- wrapJSX()
- React ≥ 18
- TypeScript ≥ 5.4
``ts`
const useEventListener: UseEventListener;
Defined in: hooks/useEventListener.ts:136
Adds handler as a listener for the event eventName of target with theoptions
provided applied
The following call signatures are available:
`ts`
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.
`tsx
useEventListener('resize', () => {
console.log(window.innerWidth, window.innerHeight);
});
useEventListener(document, 'visibilitychange', () => {
console.log(document.visibilityState);
});
const buttonRef = useRef
useEventListener(buttonRef, 'click', () => console.log('click'));
`
---
`ts`
const useIsomorphicLayoutEffect: (effect, deps?) => void;
Defined in: hooks/useIsomorphicLayoutEffect.ts:12
Identical to useLayoutEffect, except it does not result in
warnings when used on the server
| Parameter | Type |
|---|---|
effect | EffectCallback |
deps? | DependencyList |
void
---
`ts`
function useReducerWithDeps(
reducer,
initialState,
deps,
): [S, ActionDispatch];
Defined in: hooks/useReducerWithDeps.ts:64
useReducer hook with an additional dependency array deps thatinitialState
resets the state to 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
https://github.com/facebook/react/issues/33041.
The react-hooks/exhaustive-deps ESLint rule doesn't support hooks whereuseReducer
the dependency array parameter is at any other position than the second.
However, as we would like to keep the hook as compatible with asdeps
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 array.
Related issue: https://github.com/facebook/react/issues/25443.
Unlike eslint-plugin-react-hooks maintained by React's team, the unofficialuseExhaustiveDependencies 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 |
|---|
S |
A |
| Parameter | Type | Description |
|---|---|---|
reducer | (prevState | The reducer function that specifies how the state gets updated |
initialState | S | The value to which the state is set when the component is It can also be a function that returns a state value. If the state is reset |
deps | DependencyList | Dependencies that reset the state to initialState |
\[S, ActionDispatch\<A\>\]
---
`ts`
function useStateWithDeps(
initialState,
deps,
): [S, Dispatch
Defined in: hooks/useStateWithDeps.ts:62
useState hook with an additional dependency array deps thatinitialState
resets the state to 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
https://github.com/facebook/react/issues/33041.
`tsx
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
const activityOptions = activityOptionsByTimeOfDay[timeOfDay];
const [activity, setActivity] = useStateWithDeps
(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 |
|---|
S |
| Parameter | Type | Description |
|---|---|---|
initialState | S | The value to which the state is set when the component is It can also be a function that returns a state value. If the state is reset |
deps | DependencyList | Dependencies that reset the state to initialState |
\[S, Dispatch\<SetStateAction\<S\>\>\]
---
`ts`
function contextualize
Defined in: misc/contextualize.tsx:78
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.
`tsx
// Before:
return (
);
// After:
const jsx = (
<>
>
);
return contextualize(jsx)
.with(EventHandlersContext, eventHandlers)
.with(FlashcardsContext, flashcards)
.with(DeckIdContext, deckId)
.with(CourseIdContext, courseId)
.end();
`
| Type Parameter |
|---|
Children |
| Parameter | Type | Description |
|---|---|---|
children | Children | The children to contextualize |
ContextualizePipe\<Children\>
An object with the following properties:
- with: a function that accepts a context Context and a value value forcontextualize(
it as arguments and returns
end
- : a function that returns children
---
`ts${string}Context
function createSafeContext
[K in ]: Contextuse${string}
} & {
[K in ]: () => T;`
};
Defined in: misc/createSafeContext.ts:61
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 toContext.Provider
be provided, and that a meaningful context name is displayed in dev tools
instead of generic .
`tsx
enum Direction {
Up,
Down,
Left,
Right,
}
// Before:
const DirectionContext = createContext
DirectionContext.displayName = 'DirectionContext';
const useDirection = () => {
const direction = useContext(DirectionContext);
if (direction === undefined) {
// Called outside of a
// 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
const Parent = () => (
// Providing undefined as the value is not allowed 👍
);
const Child = () => Current direction: ${Direction[useDirection()]};`
| Type Parameter | Default type |
|---|---|
T | never |
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
`ts${string}Context]: Contextuse${string}]: () => T };`
#### Type Parameters
| Type Parameter |
|---|
DisplayName |
#### Parameters
| Parameter | Type |
|---|---|
displayName | \[T |
#### Returns
{ [K in ${string}Context]: Context & { [K in use${string}]: () => T }
---
`ts`
function wrapJSX
Defined in: misc/wrapJSX.tsx:98
An alternative way to compose JSX that avoids ever-increasing indentation
A more general version of the context-specific contextualize
function.
`tsx
// Before:
createRoot(document.getElementById('root')!).render(
);
// After:
createRoot(document.getElementById('root')!).render(
wrapJSX(
.with(ToasterProvider)
.with(ThemeProvider, { theme })
.with(NuqsAdapter)
.with(QueryClientProvider, { client: queryClient })
.with(I18nextProvider, { i18n })
.with(StrictMode)
.end(),
);
`
| Type Parameter |
|---|
Children |
| Parameter | Type | Description |
|---|---|---|
children | Children | The children to wrap |
JSXWrapPipe\<Children\>
An object with the following properties:
- with: a function that accepts a component Component and props propswrapJSX(
for it as arguments and returns
end
- : a function that returns children
---
`ts`
type UseEventListener = UseEventListenerWithImplicitWindowTarget &
UseEventListenerWithExplicitGlobalTarget &
UseEventListenerWithAnyExplicitTarget;
Defined in: hooks/useEventListener.ts:13
The type of useEventListener
useEventListener,
UseEventListenerWithImplicitWindowTarget,
UseEventListenerWithExplicitGlobalTarget,
UseEventListenerWithAnyExplicitTarget
---
`ts`
type UseEventListenerWithImplicitWindowTarget =
Defined in: hooks/useEventListener.ts:22
| Type Parameter |
|---|
K |
| Parameter | Type |
|---|---|
...args |
void
useEventListener,
UseEventListenerWithImplicitWindowTargetArgs
---
`ts`
type UseEventListenerWithExplicitGlobalTarget =
UseEventListenerWithExplicitTarget
UseEventListenerWithExplicitTarget
UseEventListenerWithExplicitTarget
UseEventListenerWithExplicitTarget
UseEventListenerWithExplicitTarget
Defined in: hooks/useEventListener.ts:33
useEventListener,
UseEventListenerWithExplicitTarget
---
`ts`
type UseEventListenerWithExplicitTarget
...args
) => void;
Defined in: hooks/useEventListener.ts:45
| Type Parameter |
|---|
Target |
EventMap |
| Type Parameter |
|---|
T |
K |
| Parameter | Type |
|---|---|
...args | UseEventListenerWithExplicitTargetArgs |
void
useEventListener,
UseEventListenerWithExplicitTargetArgs
---
`ts`
type UseEventListenerWithAnyExplicitTarget = UseEventListenerWithExplicitTarget<
EventTarget,
Record
>;
Defined in: hooks/useEventListener.ts:57
useEventListener,
UseEventListenerWithExplicitTarget
---
`ts`
type UseEventListenerWithImplicitWindowTargetArgs
UseEventListenerWithExplicitTargetArgs
unknown,
...infer Args,
]
? Args
: never;
Defined in: hooks/useEventListener.ts:65
| Type Parameter |
|---|
K |
useEventListener,
UseEventListenerWithExplicitTargetArgs
---
`ts`
type UseEventListenerWithExplicitTargetArgs
(
| T
| (RefObject
addEventListener?: never;
})
| null
),
K,
(this, event) => void,
AddEventListenerOptions | boolean | undefined,
];
Defined in: hooks/useEventListener.ts:79
| Type Parameter |
|---|
EventMap |
T |
K |
---
`ts`
type ContextualizePipe
with: ContextualizeWith;
end: () => Children;
};
Defined in: misc/contextualize.tsx:12
The return type of contextualize
contextualize,
ContextualizeWith
| Type Parameter |
|---|
Children |
| Property | Type |
|---|---|
() => Children |
---
`ts`
type ContextualizeWith =
Defined in: misc/contextualize.tsx:22
| Type Parameter |
|---|
T |
| Parameter | Type |
|---|---|
Context | Context |
value | NoInfer |
ContextualizePipe\<ReactElement\>
contextualize,
ContextualizePipe
---
`ts`
type JSXWrapPipe
with: WrapJSXWith
end: () => Children;
};
Defined in: misc/wrapJSX.tsx:18
The return type of wrapJSX
| Type Parameter |
|---|
Children |
| Property | Type |
|---|---|
WrapJSXWith | |
() => Children |
---
`ts`
type WrapJSXWith
Defined in: misc/wrapJSX.tsx:28
| Type Parameter |
|---|
Children |
| Type Parameter |
|---|
C |
| Parameter | Type |
|---|---|
...args | \["children" |
JSXWrapPipe\<ReactElement\>