Skip to content

Instantly share code, notes, and snippets.

@ngbrown
Created October 29, 2020 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ngbrown/1538c9998eab628d3daca84a61e0f957 to your computer and use it in GitHub Desktop.
Save ngbrown/1538c9998eab628d3daca84a61e0f957 to your computer and use it in GitHub Desktop.
React hooks
import {useEffect, useRef, useState} from 'react';
import {debounce} from 'lodash';
export function useDebouncedValue<V>(value: V, wait: number) {
const [debouncedValue, setDebouncedValue] = useState(value);
const debounceRef = useRef<typeof setDebouncedValue>();
useEffect(() => {
const debounceFn = debounce(setDebouncedValue, wait);
debounceRef.current = debounceFn;
return function cleanup() {
debounceFn.cancel();
};
}, [wait]);
debounceRef.current?.(value);
return debouncedValue;
}
import {useEffect, useState} from 'react';
export function useImports<T extends readonly unknown[]>(
initializeImports: () => T
) {
const [imports, setImports] = useState<
{
-readonly [P in keyof T]:
| (T[P] extends PromiseLike<infer U> ? U : T[P])
| undefined;
}
>([] as any);
useMountEffect(() => {
const importsArray = initializeImports();
Promise.allSettled(importsArray).then((res) => {
setImports(
res.map((x) => (x.status === 'fulfilled' ? x.value : undefined)) as any
);
});
});
return imports;
}
function useMountEffect(fun: () => void) {
useEffect(fun, []);
}
import {useEffect, useRef, useState} from 'react';
type Props = {root: Element | null; rootMargin: string; threshold: number};
// from https://medium.com/the-non-traditional-developer/how-to-use-an-intersectionobserver-in-a-react-hook-9fb061ac6cb5
// https://codesandbox.io/s/04vvrxj79p
export function useIntersect(
root: Element | null,
rootMargin: string,
threshold = 0
) {
const [entry, updateEntry] = useState({} as IntersectionObserverEntry);
const [node, setNode] = useState<Element | null>(null);
const observer = useRef(
new window.IntersectionObserver(([entry]) => updateEntry(entry), {
root,
rootMargin,
threshold,
})
);
useEffect(() => {
const {current: currentObserver} = observer;
currentObserver.disconnect();
if (node) currentObserver.observe(node);
return () => currentObserver.disconnect();
}, [node]);
return [setNode, entry];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment