A set of extraordinarily common React hooks.
We recommend installing using yarn
:
$ yarn add react-hook-utilities
Or, if you prefer npm
:
$ npm -S react-hook-utilities
Run asynchronous effects:
useAsyncEffect(async () => {
await promise;
}, []);
Run asynchronous layout effects:
useAsyncLayoutEffect(async () => {
await promise;
}, []);
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],
)
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],
)
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.
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
);
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.
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.
Creates a mutable reference object from a factory function.
const ref = useLazyRef(() => new SomeObject());
...
ref.current = newObject;
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);
}
}, []);
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.