Skip to content

aweebit/react-essentials

Repository files navigation

@aweebit/react-essentials

NPM Version

Requirements

  • React ≥ 18
  • TypeScript ≥ 5.4

useEventListener

const useEventListener: UseEventListener;

Defined in: hooks/useEventListener.ts:136

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.

Example

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'));

See

UseEventListener


useIsomorphicLayoutEffect

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

Parameters

Parameter Type

effect

EffectCallback

deps?

DependencyList

Returns

void


useReducerWithDeps()

function useReducerWithDeps<S, A>(
  reducer,
  initialState,
  deps,
): [S, ActionDispatch<A>];

Defined in: hooks/useReducerWithDeps.ts:64

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.

On linter support

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 Parameters

Type Parameter

S

A extends AnyActionArg

Parameters

Parameter Type Description

reducer

(prevState, ...args) => S

The reducer function that specifies how the state gets updated

initialState

S | ((previousState?) => S)

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 undefined in the first call upon mount).

deps

DependencyList

Dependencies that reset the state to initialState

Returns

[S, ActionDispatch<A>]


useStateWithDeps()

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.

Example

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 Parameters

Type Parameter

S

Parameters

Parameter Type Description

initialState

S | ((previousState?) => S)

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 undefined in the first call upon mount).

deps

DependencyList

Dependencies that reset the state to initialState

Returns

[S, Dispatch<SetStateAction<S>>]


contextualize()

function contextualize<Children>(children): ContextualizePipe<Children>;

Defined in: misc/contextualize.tsx:68

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.

Example

// Before:
return (
  <CourseIdContext.Provider value={courseId}>
    <DeckIdContext.Provider value={deckId}>
      <FlashcardsContext.Provider value={flashcards}>
        <EventHandlersContext.Provider value={eventHandlers}>
          {children}
        </EventHandlersContext.Provider>
      </FlashcardsContext.Provider>
    </DeckIdContext.Provider>
  </CourseIdContext.Provider>
);

// After:
return contextualize(children)
  .with(EventHandlersContext, eventHandlers)
  .with(FlashcardsContext, flashcards)
  .with(DeckIdContext, deckId)
  .with(CourseIdContext, courseId)
  .end();

Type Parameters

Type Parameter

Children extends ReactNode

Parameters

Parameter Type Description

children

Children

The children to contextualize

Returns

ContextualizePipe<Children>

An object with the following properties:

  • with: a function that accepts a context provider Provider (or the context it belongs to) and a value value for that context as arguments and returns contextualize(<Provider value={value}>{children}</Provider>)
  • end: a function that returns children

See

ContextualizePipe


createGranularContext()

function createGranularContext<Name, PartNames, Value, Props>(
  name,
  partNames,
  providerHook,
): {
  [K in `${Capitalize<string>}Provider`]: FunctionComponent<
    Props & { children?: ReactNode }
  >;
} & { [K in string as `use${Capitalize<K>}`]: () => Value[K] };

Defined in: misc/createGranularContext.ts:73

Generates multiple related contexts using createRequiredContext and returns hooks for each of them as well as a provider component for all of them that incorporates user-defined logic for populating context values supplied in the providerHook argument

This function facilitates the application of the provider pattern in cases where the provider component provides values for multiple related contexts.

Example

const { SearchProvider, useSearchQuery, useSetSearchQuery } =
  createGranularContext(
    'Search',
    ['searchQuery', 'setSearchQuery'],
    ({ initialQuery }: { initialQuery?: string }) => {
      const [searchQuery, setSearchQuery] = useState(initialQuery ?? '');
      return { searchQuery, setSearchQuery };
    },
  );

const App = () => (
  <SearchProvider>
    <Toolbar />
    <Data />
  </SearchProvider>
);

// Won't re-render when query changes because it only uses the query setter 🥳
const Toolbar = () => {
  const setSearchQuery = useSetSearchQuery();
  return (
    <input onChange={(event) => setSearchQuery(event.currentTarget.value)} />
  );
};

// Will re-render when query changes because it uses it 👍
const Data = () => {
  const searchQuery = useSearchQuery();
  // Fetch data and use searchQuery to filter it...
};

Type Parameters

Type Parameter Default type

Name extends string

PartNames extends string[]

Value extends Record<PartNames[number], unknown>

Props extends object

{ }

Parameters

Parameter Type Description

name

string extends Name ? never : Name

A string that the provider component's display name is derived from

partNames

string extends PartNames[number] ? never : PartNames

An array of strings from which the underlying contexts' display names are derived from

providerHook

(props) => Value

A function that receives props passed to the provider component and is used to populate the underlying contexts' values which it returns in an object mapping names from partNames to their respective contexts' values

Returns

{ [K in `${Capitalize<string>}Provider`]: FunctionComponent<Props & { children?: ReactNode }> } & { [K in string as `use${Capitalize<K>}`]: () => Value[K] }

An object with the following properties:

  • `${capitalize(name)}Provider` (e.g. SearchProvider): the provider component
  • `use${capitalize(partName)}` for each element partName of partNames (e.g. useSearchQuery, useSetSearchQuery): a hook that returns the current context value if one was provided, or throws an error otherwise

See

createRequiredContext


createRequiredContext()

function createRequiredContext<T>(): <Name>(name) => {
  [K in `${Capitalize<string>}Provider`]: Provider<T>;
} & {
  [K in `use${Capitalize<string>}`]: () => T;
};

Defined in: misc/createRequiredContext.ts:75

For a given type T, returns a function that generates a context of that type, and returns both a provider component and a hook for that context where the hook will throw if no context value has been provided

The advantages over vanilla createContext are that no default value has to be specified, and that a meaningful context name is displayed in dev tools instead of generic Context.Provider.

createGranularContext is a more high-level API built on top of this function. Using it should be preferred to using createRequiredContext directly in cases where the context value is part of the UI state.

Example

enum Direction {
  Up,
  Down,
  Left,
  Right,
}

// Before:
const DirectionContext = createContext<Direction | undefined>(undefined);
DirectionContext.displayName = 'DirectionContext';

const DirectionProvider = DirectionContext.Provider;
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 { DirectionProvider, useDirection } =
  createRequiredContext<Direction>()('Direction'); // That's it :)

const Parent = () => (
  // Providing undefined as the value is not allowed 👍
  <DirectionProvider value={Direction.Up}>
    <Child />
  </DirectionProvider>
);

const Child = () => `Provided direction: ${Direction[useDirection()]}`;

Type Parameters

Type Parameter Default type

T

never

Returns

A function that accepts a single string argument name (e.g. "Direction") and returns an object with the following properties:

  • `${capitalize(name)}Provider` (e.g. DirectionProvider): the context provider
  • `use${capitalize(name)}` (e.g. useDirection): a hook that returns the current context value if one was provided, or throws an error otherwise

<Name>(name) => { [K in `${Capitalize<string>}Provider`]: Provider<T> } & { [K in `use${Capitalize<string>}`]: () => T }

See

createGranularContext


wrapJSX()

function wrapJSX<Children>(children): JSXWrapPipe<Children>;

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.

Example

// 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 Parameters

Type Parameter

Children extends ReactNode

Parameters

Parameter Type Description

children

Children

The children to wrap

Returns

JSXWrapPipe<Children>

An object with the following properties:

  • with: a function that accepts a component Component and props props for it as arguments and returns wrapJSX(<Component {...props}>{children}</Component>)
  • end: a function that returns children

See

JSXWrapPipe


UseEventListener

type UseEventListener = UseEventListenerWithImplicitWindowTarget &
  UseEventListenerWithExplicitGlobalTarget &
  UseEventListenerWithAnyExplicitTarget;

Defined in: hooks/useEventListener.ts:13

The type of useEventListener

See

useEventListener, UseEventListenerWithImplicitWindowTarget, UseEventListenerWithExplicitGlobalTarget, UseEventListenerWithAnyExplicitTarget


UseEventListenerWithImplicitWindowTarget

type UseEventListenerWithImplicitWindowTarget = <K>(...args) => void;

Defined in: hooks/useEventListener.ts:22

Type Parameters

Type Parameter

K extends keyof WindowEventMap

Parameters

Parameter Type

...args

UseEventListenerWithImplicitWindowTargetArgs<K>

Returns

void

See

useEventListener, UseEventListenerWithImplicitWindowTargetArgs


UseEventListenerWithExplicitGlobalTarget

type UseEventListenerWithExplicitGlobalTarget =
  UseEventListenerWithExplicitTarget<Window, WindowEventMap> &
    UseEventListenerWithExplicitTarget<Document, DocumentEventMap> &
    UseEventListenerWithExplicitTarget<HTMLElement, HTMLElementEventMap> &
    UseEventListenerWithExplicitTarget<SVGElement, SVGElementEventMap> &
    UseEventListenerWithExplicitTarget<MathMLElement, MathMLElementEventMap>;

Defined in: hooks/useEventListener.ts:33

See

useEventListener, UseEventListenerWithExplicitTarget


UseEventListenerWithExplicitTarget

type UseEventListenerWithExplicitTarget<Target, EventMap> = <T, K>(
  ...args
) => void;

Defined in: hooks/useEventListener.ts:45

Type Parameters

Type Parameter

Target extends EventTarget

EventMap

Type Parameters

Type Parameter

T extends Target

K extends keyof EventMap

Parameters

Parameter Type

...args

UseEventListenerWithExplicitTargetArgs<EventMap, T, K>

Returns

void

See

useEventListener, UseEventListenerWithExplicitTargetArgs


UseEventListenerWithAnyExplicitTarget

type UseEventListenerWithAnyExplicitTarget = UseEventListenerWithExplicitTarget<
  EventTarget,
  Record<string, Event>
>;

Defined in: hooks/useEventListener.ts:57

See

useEventListener, UseEventListenerWithExplicitTarget


UseEventListenerWithImplicitWindowTargetArgs

type UseEventListenerWithImplicitWindowTargetArgs<K> =
  UseEventListenerWithExplicitTargetArgs<WindowEventMap, Window, K> extends [
    unknown,
    ...infer Args,
  ]
    ? Args
    : never;

Defined in: hooks/useEventListener.ts:65

Type Parameters

Type Parameter

K extends keyof WindowEventMap

See

useEventListener, UseEventListenerWithExplicitTargetArgs


UseEventListenerWithExplicitTargetArgs

type UseEventListenerWithExplicitTargetArgs<EventMap, T, K> = [
  (
    | T
    | (RefObject<T> & {
        addEventListener?: never;
      })
    | null
  ),
  K,
  (this, event) => void,
  AddEventListenerOptions | boolean | undefined,
];

Defined in: hooks/useEventListener.ts:79

Type Parameters

Type Parameter

EventMap

T extends EventTarget

K extends keyof EventMap

See

useEventListener


ContextualizePipe

type ContextualizePipe<Children> = {
  with: ContextualizeWith;
  end: () => Children;
};

Defined in: misc/contextualize.tsx:12

The return type of contextualize

See

contextualize, ContextualizeWith

Type Parameters

Type Parameter

Children extends ReactNode

Properties

Property Type

with

ContextualizeWith

end

() => Children


ContextualizeWith

type ContextualizeWith = <T>(
  Provider,
  value,
) => ContextualizePipe<ReactElement>;

Defined in: misc/contextualize.tsx:22

Type Parameters

Type Parameter

T

Parameters

Parameter Type

Provider

Provider<T> | Context<T>

value

NoInfer<T>

Returns

ContextualizePipe<ReactElement>

See

contextualize, ContextualizePipe


JSXWrapPipe

type JSXWrapPipe<Children> = {
  with: WrapJSXWith<Children>;
  end: () => Children;
};

Defined in: misc/wrapJSX.tsx:18

The return type of wrapJSX

See

wrapJSX, WrapJSXWith

Type Parameters

Type Parameter

Children extends ReactNode

Properties

Property Type

with

WrapJSXWith<Children>

end

() => Children


WrapJSXWith

type WrapJSXWith<Children> = <C>(...args) => JSXWrapPipe<ReactElement>;

Defined in: misc/wrapJSX.tsx:28

Type Parameters

Type Parameter

Children extends ReactNode

Type Parameters

Type Parameter

C extends keyof JSX.IntrinsicElements | JSXElementConstructor<any>

Parameters

Parameter Type

...args

["children" extends keyof ComponentProps<C> ? [Children] extends [ComponentProps<C>["children"]] ? C : never : never, ...(Record<never, unknown> extends Omit<ComponentProps<C>, "children"> ? [props?: JSX.IntrinsicAttributes & Omit<ComponentProps<C>, "children">] : [props: JSX.IntrinsicAttributes & Omit<ComponentProps<C>, "children">])]

Returns

JSXWrapPipe<ReactElement>

See

wrapJSX, JSXWrapPipe

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors