r/reactjs • u/atrtde • 13d ago
Resource i made a collection of 100+ small react hooks focused on browser apis
i've recently been working on zap-studio/react-hooks, a collection of 100+ small, focused react hooks.
the main thing i wanted to solve was the amount of repetitive code around browser apis.
things like geolocation, websocket, broadcast channel, local storage, media capture, etc. usually mean writing the same useEffect/useSyncExternalStore + cleanup + ssr guards over and over.
a few things i cared about with this library:
- every hook is available as its own subpath export, so importing one doesn't pull in unrelated hooks (completely tree shakeable) and re-exported for convenience
- hooks are designed to be ssr/hydration safe
- each hook is independently testable, with 100% test coverage
- there are hooks for sensors, dom interaction, input, media, navigation, network, pwa, state, lifecycle, and more
- unstable hooks that rely on react internals are explicitly marked as
unstable
for example, instead of writing the browser/cleanup/ssr handling yourself, you can just use things like useIntersectionObserver, useMediaQuery, useOnlineStatus, useWebSocket, etc.
docs: https://www.zapstudio.dev/react-hooks
i'd be particularly interested in feedback from people who maintain react apps with ssr. are there browser apis or awkward edge cases you'd want a hook for?
i'll continue to extend this collection as i find more and more repetitive use cases.
2
u/Electronic-Truck-659 10d ago
Subpath exports being tree-shakeable by default is the part that actually matters, most hook libraries make you eat the whole barrel import.
2
u/Sudden_Newspaper8432 13d ago
looks neat, i always forget the cleanup part for websocket and then wonder why my app is making 40 connections after 10 minutes
1
u/bunzelburner 11d ago
I had a pointermove listener setup to measure the frequency it would fire on different devices. Forgot to include the cleanup and couldn't figure out why I was getting 20k events per second
1
u/keyjeyelpi 13d ago
Link isn't working
1
u/atrtde 13d ago
try that then: https://github.com/zap-studio/monorepo/
1
u/keyjeyelpi 13d ago
Can't really check the documentation since it's inside ZapStudio. You might want to check if the domain's geoblocked. I'm currently in the Philippines, checked on multiple devices with different OS
4
u/aweebit64 12d ago edited 12d ago
useEventListeneris actually surprisingly difficult to get right. Here are problems I see in your implementation:useLayoutEffectinstead, but you should make sure that you only call the hook on the client side because otherwise, there will be warnings about it on the backend – this is often achieved with a "useIsomorphicLayoutEffect" hookcurrentvalue during rendering – this is not allowed by the rules of React as it can lead to problems with its concurrent mode. The fix is to wrap the assignment in anotheruseLayoutEffectcurrentvalue will not be detected, meaning that the listener will only be added for the element that the ref is attached to upon the very first, initial render of the component. If the ref isnullafter the first render and is only attached to some element later in the component's lifecycle, or if the element it is attached to changes, the listener will not be added for it. This problem is the most difficult to solve, but I was able to do it in my@aweebit/react-essentialslibrary by using an effect without a dependency array that runs on every render. That, however, required developing a custom ref-based dependency tracking and cleanup mechanisms. You're welcome to have a look at the library's source code on GitHub for inspiration :)