Skip to content

fjcaetano/react-hook-utilities

Repository files navigation

react-hook-utilities Build Status codecov PRs welcome npm

A set of extraordinarily common React hooks.

Installation

We recommend installing using yarn:

$ yarn add react-hook-utilities

Or, if you prefer npm:

$ npm -S react-hook-utilities

Usage

Async effects

Run asynchronous effects:

useAsyncEffect(async () => {
  await promise;
}, []);

Async layout effects

Run asynchronous layout effects:

useAsyncLayoutEffect(async () => {
  await promise;
}, []);

Effect update

Executes an effect and get its dependencies previous state:

let name: string | undefined;

useEffectUpdate(
  ([oldName]) => {
    if (!oldName && !!name) {
      // name now has a valid value
    }
  },
  [name],
)

Conditional effect

Conditionally executes an effect. The previous state is sent to the condition evaluation:

let error: Error | undefined;

useConditionalEffect(
  ([prevError]) => !prevError && !!error,
  () => {
    // an error was introduced
    showToast(error);
  },
  [error],
)

Worker

Wraps a promise with loading and error states:

const { isLoading, error, result, callback } = useWorker(
  async param => {
    if (!param) {
      throw new Error('invalid arguments');
    }

    const result = await doSomething(param)
    return result
  },
  [doSomething],
)

isLoading is set to true as soon as the callback is loaded and only returns to false when it ends or when an error happens. If an exception is thrown or a promise fails, error will be updated.

Worker State

This is a worker that starts loading immediately and stores the result in a state. Useful for loading data when you render a component:

const { isLoading, error, data, callback } = useWorkerState(
  async () => {
    return await getUserName(userId);
  },
  [userId],
  'no-name', // data's initial value
);

Did Mount

Runs an effect when the component mounts:

useDidMount(() => {
  console.log("I'm up!");
});

The effect may be an asynchronous function, in which case, it shouldn't return a cleanup function since it won't be executed.

Did Unmount

Executes an effect when the component unmounts. The effect may also be asynchronous:

useDidUnmount(async () => {
  await busyWork(someState);
  console.log('heading out');
}, [someState]);

Any dependencies used inside the effect must be declared, however, the effect is not called when the dependencies change. The effect is only called when the component is being unmounted.

Use Lazy Ref

Creates a mutable reference object from a factory function.

const ref = useLazyRef(() => new SomeObject());
...
ref.current = newObject;

Use Promised State

A state that only resolves after setting truthy values.

If you need to use the promise as a dependency of another hook, use its ValuablePromise.value attribute as the dependency:

const [name, setName, rejectName] = usePromisedState();
useAsyncEffect(async () => {
  await name;
  ...
}, [name.value]); // use the promise's `value` as dependency

const someCallback = useCallback(async () => {
  try {
   const name = await fetch(API.getName);
   setName(name);
  } catch(e) {
    rejectName(e);
  }
}, []);

Typescript

react-hook-utilities sees Typescript is a first-class citizen. The library is built for and around Typescript and you'll get bonus points for using it. Nonetheless, pure JavaScript files are also available if you're that guy.