Shareable React Hooks
As we've discussed, I have a bunch of hooks that keep coming with me from a bunch of projects. I want to make them shareable and testable and hopefully in TS so we can move in that direction.
Here's a list of hooks and a brief explanation.
I have these hooks already done
useCurrentBreakpoint
Idea is to get this with a provider so it can be configured per project's need (with sensible defaults). This is helpful to trigger state changes on resizes that would need libraries updated settings (normally libraries that aren't React friendly)
useDebounce
Hook that debounces a value so it only causes re-render after it settled the debounce.
(Leverages useDebouncedCallback
)
useDebouncedCallback
A hook that runs a callback debounced by a delay parameter so it will only run once within that time no matter the amount of times it's called.
(Leveraged by useDebounce
)
useEffectAfterRender
Convenient helper hook to only run effect changes after the component has been rendered.
useEffectOnce
A hook that wraps useEffect to avoid needing to pass any dependency. The main reason is to ensure the intention of the developer is clear since these usages get flagged by eslint.
useEffectRef
A hook that's a safe wrapper around a ref. useEffect
cant have useRef
current as a watcher, and refs can be undefined
and then set later, change to a different element or unmount and become undefined
.
This is mostly a hook leveraged by other hooks when a ref is needed for a given element.
useEvent
A hook that listens to an event and deals with removing the listener when unmounted.
useExternalScript
Creates script tag for provided script to run. Uses cache to not allow multiple instances of script.
useFocusTrap
A hook that traps focus onto a given element upon receiving true and will return focus upon receiving false.
The hook will be pretty naive as there are lots of edge cases not covered given that they won't be likely run into. Those cases are for example (but not limited) handling disabled elements, non-normative tab-index, etc.
useIsMounted
A hook that gets a mounted property to true once it's mounted. This will only happen on the browser since servers don't mount components but merely renders. This hook is intended to be used with problematic effects that might happen due to differences between browser and server.
useIsTransitioning
Next specific hook that will provide a context and provides info for routeChangeStart
and such events. Intended to mount/unmount elements on these events or show a loading indicator.
useKey
Convenient wrapper around useEvent to handle key presses allowing to send either the key being watched, a function
to evaluate or any truthy/falsy value
- If it's a string it will be compared against the event's key property to see if it maches.
- If it's a function it will be run with the event for the hook's usage to decide.
- If it's any other type it'll evaluate falsy / truthy to decide.
useLazyContent
A hook that ties a value to the visibility of an element. If the browser doesn't support IntersectionObserver, it will just act as if it's intersecting.
useOnClickOutside
A hook that acts once you click outside of the given element. Useful to close modals
useOnScreenCallback
A hook that calls a callback once intersects with the intersection observer.
useOnWindowResize
Hook to be called when the window is resized.
usePrefersReducedMotion
A hook that checks whether the user has a system setting that prefer things to not have motion to avoid vestibular disorder related issues. Safe for SSR.
usePrevious
Holds a value onto a reference that gets updated after a new render happens. This can be used in combination with useState to store the previous value as well.
useSafeLayoutEffect
A hook that can be used when useLayoutEffect is wanted but avoid crashing on SSR.
useScroll
Custom hook to run an effect once the user scrolls through the page. Provides { prevPos, currPos }
so it can be used to determine scroll direction.
useScrollLock
Custom hook that will lock the body's overflow to prevent scrolling if the given value is true or truthy.