All files / modules/10-common/hooks useDeepCompareEffect.ts

100% Statements 12/12
100% Branches 6/6
100% Functions 4/4
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53                    1077x 1077x           16723x   72433x 1057x       71376x         16723x   16723x 5732x     16723x                         1077x   16723x    
/*
 * Copyright 2021 Harness Inc. All rights reserved.
 * Use of this source code is governed by the PolyForm Shield 1.0.0 license
 * that can be found in the licenses directory at the root of this repository, also available at
 * https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
 */
 
/**
 * Based on https://github.com/contiamo/restful-react/blob/7aa3d75694f919d0317981a128b139abe163e08e/src/util/useDeepCompareEffect.ts
 */
import React, { useEffect, useRef } from 'react'
import { isEqualWith } from 'lodash-es'
 
/**
 * Custom version of isEqual to handle function comparison
 */
function isEqual(a: unknown, b: unknown): boolean {
  return isEqualWith(a, b, (x: unknown, y: unknown): boolean | undefined => {
    // Deal with the function comparison case
    if (typeof x === 'function' && typeof y === 'function') {
      return x.toString() === y.toString()
    }
 
    // Fallback on the method
    return undefined
  })
}
 
function useDeepCompareMemoize(value: React.DependencyList): React.DependencyList | undefined {
  const ref = useRef<React.DependencyList>()
 
  if (!isEqual(value, ref.current)) {
    ref.current = value
  }
 
  return ref.current
}
 
/**
 * Accepts a function that contains imperative, possibly effectful code.
 *
 * This is the deepCompare version of the `React.useEffect` hooks (that is shallowed compare)
 *
 * @param effect Imperative function that can return a cleanup function
 * @param deps If present, effect will only activate if the values in the list change.
 *
 * @see https://gist.github.com/kentcdodds/fb8540a05c43faf636dd68647747b074#gistcomment-2830503
 */
export function useDeepCompareEffect(effect: React.EffectCallback, deps: React.DependencyList): void {
  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(effect, useDeepCompareMemoize(deps))
}