UNPKG

1.58 kBJavaScriptView Raw
1import * as React from 'react';
2import { dequal } from 'dequal';
3
4function checkDeps(deps) {
5 if (!deps || !deps.length) {
6 throw new Error('useDeepCompareEffect should not be used with no dependencies. Use React.useEffect instead.');
7 }
8
9 if (deps.every(isPrimitive)) {
10 throw new Error('useDeepCompareEffect should not be used with dependencies that are all primitive values. Use React.useEffect instead.');
11 }
12}
13
14function isPrimitive(val) {
15 return val == null || /^[sbn]/.test(typeof val);
16}
17/**
18 * @param value the value to be memoized (usually a dependency list)
19 * @returns a momoized version of the value as long as it remains deeply equal
20 */
21
22
23function useDeepCompareMemoize(value) {
24 var ref = React.useRef(value);
25 var signalRef = React.useRef(0);
26
27 if (!dequal(value, ref.current)) {
28 ref.current = value;
29 signalRef.current += 1;
30 } // eslint-disable-next-line react-hooks/exhaustive-deps
31
32
33 return React.useMemo(function () {
34 return ref.current;
35 }, [signalRef.current]);
36}
37
38function useDeepCompareEffect(callback, dependencies) {
39 if (process.env.NODE_ENV !== 'production') {
40 checkDeps(dependencies);
41 } // eslint-disable-next-line react-hooks/exhaustive-deps
42
43
44 return React.useEffect(callback, useDeepCompareMemoize(dependencies));
45}
46
47function useDeepCompareEffectNoCheck(callback, dependencies) {
48 // eslint-disable-next-line react-hooks/exhaustive-deps
49 return React.useEffect(callback, useDeepCompareMemoize(dependencies));
50}
51
52export { useDeepCompareEffect as default, useDeepCompareEffectNoCheck, useDeepCompareMemoize };