Created
October 6, 2021 11:22
-
-
Save segunadebayo/1a36e0f1df1029a1017cb519f61d5afd to your computer and use it in GitHub Desktop.
use-effect-ref
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {useRef, useCallback} from 'react'; | |
export type EffectRef<E extends HTMLElement = HTMLElement> = (element: E | null) => void; | |
export type RefCallback<E extends HTMLElement = HTMLElement> = (element: E) => (() => void) | void; | |
// eslint-disable-next-line @typescript-eslint/no-empty-function | |
const noop = () => {}; | |
export function useEffectRef<E extends HTMLElement = HTMLElement>(callback: RefCallback<E>): EffectRef<E> { | |
const disposeRef = useRef<(() => void)>(noop); | |
const effect = useCallback( | |
(element: E | null) => { | |
disposeRef.current(); | |
// To ensure every dispose function is called only once. | |
disposeRef.current = noop; | |
if (element) { | |
const dispose = callback(element); | |
if (typeof dispose === 'function') { | |
disposeRef.current = dispose; | |
} | |
// Have an extra type check to work with javascript. | |
else if (dispose !== undefined) { | |
// eslint-disable-next-line no-console | |
console.warn('Effect ref callback must return undefined or a dispose function'); | |
} | |
} | |
}, | |
[callback] | |
); | |
return effect; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment