import { Meta } from '@storybook/addon-docs';
One of @react-hookz/web
's primary goals is to replace
react-use, the no longer maintained project
@react-hookz/web
grew out of.
The most common react-use
hooks have already been ported to @react-hookz/web
. You can track our
progress porting the rest of react-use
's hooks in
this issue.
If there is a react-use
hook you need that isn't ported yet, please comment there - or even
better, make a PR!
In the meantime, feel free to use both @react-hookz/web
and react-use
in tandem.
See our README.
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Location-related hooks will not be implemented. Instead, consider using one of the various routing libraries available.
Not implemented yet
Implemented as useIntersectionObserver
OLD in react-use
:
const intersection = useIntersection(elementRef, {
root: rootRef,
rootMargin: '0px',
threshold: 1,
});
NEW in @react-hookz/web
:
const intersection = useIntersectionObserver(elementRef, {
root: rootRef,
rootMargin: '0px',
threshold: [0, 0.5],
});
See useKeyboardEvent
See useKeyboardEvent
See useKeyboardEvent
See useKeyboardEvent
Location-related hooks will not be implemented. Instead, consider using one of the various routing libraries available.
Location-related hooks will not be implemented. Instead, consider using one of the various routing libraries available.
Not implemented yet
Implemented as useMediaQuery
No API changes, besides name change.
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Implemented as useNetworkState
No API changes, besides name change.
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Implemented as useWindowSize
Implemented as useMeasure
No API changes.
Use useMeasure instead.
No plans to implement
Not implemented yet
Not implemented yet
Implemented as useClickOutside)
No API changes, besides name change.
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Not implemented yet
Implemented as useIntervalEffect
No API changes, besides name change.
Not implemented yet
No plans to implement, rather use useTimeoutEffect and useRerender like this:
const rerender = useRerender();
const [cancel, reset] = useTimeoutEffect(rerender, 123);
Implemented as useTimeoutEffect
API is backwards-compatible, minus the first isReady
return value.
In order to replicate the old functionality, you can do the following:
const isReady = (React.useRef < boolean) | (null > false);
const [cancel, reset] = useTimeoutEffect(() => {
isReady.current = true;
console.log('Hello world');
}, 123);
const clear = () => {
isReady.current = null;
cancel();
};
const set = () => {
isReady.current = false;
reset();
};
// Use set and clear, same as in `react-use`.
Not implemented yet
Implemented as useRerender
No API changes, besides name change.
Implemented as useAsync
OLD in react-use
:
const { loading, value, error } = useAsync(async () => {
const response = await fetch(url);
const result = await response.text();
return result;
}, [url]);
console.log(loading);
console.log(value);
console.log(error.message);
NEW in @react-hookz/web
:
const [{ status, result, error }, { execute }] = useAsync(async () => {
const response = await fetch(url);
const result = await response.text();
return result;
});
useMountEffect(execute);
console.log(status === 'loading');
console.log(result);
console.log(error.message);
Implemented as part of useAsync
OLD in react-use
:
const [{ loading, value, error }, doFetch] = useAsync(async () => {
const response = await fetch(url);
const result = await response.text();
return result;
}, [url]);
doFetch();
NEW in @react-hookz/web
:
const [{ status, result, error }, { execute }] = useAsync(async () => {
const response = await fetch(url);
const result = await response.text();
return result;
});
execute();
Implemented as part of useAsync
OLD in react-use
:
const { loading, value, error, retry } = useAsync(async () => {
const response = await fetch(url);
const result = await response.text();
return result;
}, [url]);
retry();
NEW in @react-hookz/web
:
const [{ status, result, error }, { execute }] = useAsync(async () => {
const response = await fetch(url);
const result = await response.text();
return result;
});
execute();
No plans to implement. Use useEventListener instead:
useEventListener(window, 'beforeunload', () => {
/* do your stuff here */
});
Implemented as useCookieValue
OLD in react-use
:
const [value, set, remove] = useCookie('my-cookie');
console.log(value);
set('Hello world!', options);
remove();
NEW in @react-hookz/web
:
const [value, set, remove] = useCookieValue('react-hookz', options);
console.log(value);
set('Hello world!');
remove();
NOTES:
js-cookies
needs installed separately from@react-hookz/web
to useuseCookie
useCookie
instances with the same key on the same page are synchronised. This synchronisation does not work across tabs or on changes that are triggered by third-party code.
Not implemented yet
@react-hookz/web
has three options for debouncing, which we feel are both more ergonomic and
flexible than react-use
's implementation.
Depending on your use case, useDebouncedEffect, useDebounceCallback, or useDebouncedState may be more appropriate.
Not implemented yet
Hooks that modify contents of the <head>
element will not be implemented. Instead, consider using
libraries such as react-helmet and react-helmet-async.
Implemented as useLocalStorageValue
Backwards compatible API, minus the raw
option.
NOTE: useLocalStorage
instances with the same key on the same page are synchronised. This
synchronisation does not work across tabs or on changes that are triggered by third-party code.
Not implemented yet
Not implemented yet
Implemented as useSessionStorageValue
Backwards compatible API, minus the raw
option.
NOTE: useSessionStorage
instances with the same key on the same page are synchronised. This
synchronisation does not work across tabs or on changes that are triggered by third-party code.
@react-hookz/web
has three options for throttling, which we feel are both more ergonomic and
flexible than react-use
's implementations.
Depending on your use case, useThrottledEffect, useThrottledCallback, or useThrottledState may be more appropriate.
Hooks that modify contents of the <head>
element will not be implemented. Instead, consider using
libraries such as react-helmet and react-helmet-async.
Backwards compatiable API.
Implemented as usePermission
No API changes.
Was just an alias for useMountEffect - use that directly instead.
Implemented as useEventListener
OLD in react-use
:
useEvent(
'mousemove',
() => {
setState(new Date());
},
window,
{ passive: true }
);
NEW in @react-hookz/web
:
useEventListener(
window,
'mousemove',
() => {
setState(new Date());
},
{ passive: true }
);
No plans to implement
Implemented as useIsMounted
No API change, besides name change.
Not implemented yet
Not implemented yet
Implemented as useLifecycleLogger
Implemented as useMountEffect
No API change, besides name change.
Implemented as useUnmountEffect
No API change, besides name change.
Implemented as useUpdateEffect
No API changes.
Implemented as useIsomorphicLayoutEffect
No API changes.
Not implemented yet
Not implemented yet
Not implemented yet
No plans to implement
No plans to implement
No plans to implement
No plans to implement
No plans to implement, rather use useMediatedState like so:
const initialValue = 'world';
const defaultValue = 'you';
const [greeting, setGreeting] = useMediatedState(
initialValue,
(newValue) => newValue ?? defaultValue
);
console.log(`Hello ${greeting}`);
Not implemented yet
Not implemented yet
Implemented as useSyncedRef
No API changes, besides name change.
Implemented as usePrevious
No API changes.
Not implemented yet
Not implemented yet
Not implemented yet
React.useState
maybe used to achieve the same with minimal changes.
OLD in react-use
:
const [state, setState] = useSetState({});
setState({ hello: 'world' });
setState({ foo: 'bar' });
NEW in @react-hookz/web
:
const [state, setState] = useState({});
setState((current) => { ...current, hello: 'world' });
setState((current) => { ...current, foo: 'bar' });
Not implemented yet
Implemented as useToggle
No API changes.
Use useToggle instead
Implemented as useCounter
Use useCounter instead.
Implemented as useList.
Use useList instead.
Implemented as useMap
OLD in react-use
:
const [map, { set, remove, reset, setAll }] = useMap({
hello: 'there',
});
console.log(JSON.stringify(map, null, 2));
set('some', 'thing');
remove('hello');
reset();
setAll({ hello: 'there', some: 'thing' });
NEW in @react-hookz/web
:
const map = useMap(new Map([['hello', 'there']]););
console.log(JSON.stringify(Array.from(map), null, 2));
map.set("some", "thing");
map.delete("hello");
map.clear();
// There is no native `setAll` method on `Map`s, but we can create our own easily
const setAll = (values) => {
map.clear();
valuePairs.forEach((valuePair) => map.set(valuePair[0], valuePair[1]));
}
setAll([['hello', 'there']]);
NOTES: @react-hookz/web
's implementation is the same signature as the native Map
object, but its
methods are wrapped to cause components to rerender with changes.
Implemented as useSet
OLD in react-use
:
const [set, { add, reset, remove, has, toggle }] = useSet(new Set(['hello', 'world']));
console.log(JSON.stringify(Array.from(set), null, 2));
add(String(Date.now()));
reset();
remove('hello');
has('hello');
toggle('hello');
NEW in @react-hookz/web
:
const set = useSet(['hello', 'world']);
console.log(JSON.stringify(Array.from(set), null, 2));
set.add(String(Date.now()));
set.clear();
set.delete('hello');
set.has('hello');
// There is no native `toggle` method on `Set`s, but we can create our own easily
const toggle = (value) => (set.has(value) ? set.delete(value) : set.add(value));
toggle('hello');
NOTES: @react-hookz/web
's implementation is the same signature as the native Set
object, but its
methods are wrapped to cause components to rerender with changes.
Not implemented yet
Implemented as useValidator
OLD in react-use
:
// outside of React component
const validator = (s) => {
const isValid = !text.length || text.length % 2 === 1;
const error = !isValid ? new Error("text length should be an odd length") : undefined,
return [isValid, error]
};
-----
// inside of React component
const [text, setText] = useState("");
const [[isValid, error], revalidate] = useStateValidator(text, validator);
console.log(isValid);
console.log(error?.message);
revalidate();
NEW in @react-hookz/web
:
const [text, setText] = useState("");
const validator =
(d) => {
const isValid = !text.length || text.length % 2 === 1;
const error = !isValid ? new Error("text length should be an odd length") : undefined,
d({
isValid,
error
});
}
const [validity] = useValidator(validator, [text]);
console.log(validity.isValid);
console.log(validity.error?.message);
// no manual revalidation needed
Not implemented yet
See useValidator
Implemented as useMediatedState
OLD in react-use
:
const [state, setState] = useMediatedState((value) => value, '');
console.log(state);
setState('Hello world!');
NEW in @react-hookz/web
:
const [state, setState] = useMediatedState('', (value) => value);
console.log(state);
setState('Hello world!');
Implemented as useFirstMountState
No API changes.
Implemented as useRenderCount
No API changes.
No plans to implement
Not implemented yet
Not implemented yet
Not implemented yet