UNPKG

1.67 kBJavaScriptView Raw
1import { useRef, useEffect, useDebugValue } from 'react';
2import useMounted from './useMounted';
3
4/**
5 * a useEffect() hook with customized depedency comparision
6 *
7 * @param effect The effect callback
8 * @param dependencies A list of dependencies
9 * @param isEqual A function comparing the next and previous dependencyLists
10 */
11
12/**
13 * a useEffect() hook with customized depedency comparision
14 *
15 * @param effect The effect callback
16 * @param dependencies A list of dependencies
17 * @param options
18 * @param options.isEqual A function comparing the next and previous dependencyLists
19 * @param options.effectHook the underlying effect hook used, defaults to useEffect
20 */
21
22function useCustomEffect(effect, dependencies, isEqualOrOptions) {
23 const isMounted = useMounted();
24 const {
25 isEqual,
26 effectHook = useEffect
27 } = typeof isEqualOrOptions === 'function' ? {
28 isEqual: isEqualOrOptions
29 } : isEqualOrOptions;
30 const dependenciesRef = useRef();
31 dependenciesRef.current = dependencies;
32 const cleanupRef = useRef(null);
33 effectHook(() => {
34 // If the ref the is `null` it's either the first effect or the last effect
35 // ran and was cleared, meaning _this_ update should run, b/c the equality
36 // check failed on in the cleanup of the last effect.
37 if (cleanupRef.current === null) {
38 const cleanup = effect();
39 cleanupRef.current = () => {
40 if (isMounted() && isEqual(dependenciesRef.current, dependencies)) {
41 return;
42 }
43 cleanupRef.current = null;
44 if (cleanup) cleanup();
45 };
46 }
47 return cleanupRef.current;
48 });
49 useDebugValue(effect);
50}
51export default useCustomEffect;
\No newline at end of file