JAVASCRIPT

React `useDeepCompareEffect` for Complex Dependency Arrays

Enhance `useEffect` by using `useDeepCompareEffect` to trigger effects only when deeply nested objects or arrays in the dependency array truly change, avoiding unnecessary re-renders.

import { useRef, useEffect } from 'react';
import isEqual from 'lodash.isequal'; // or a custom deep comparison function

function useDeepCompareEffect(callback, dependencies) {
  const currentDependenciesRef = useRef(dependencies);

  if (!isEqual(currentDependenciesRef.current, dependencies)) {
    currentDependenciesRef.current = dependencies;
  }

  useEffect(callback, currentDependenciesRef.current);
}

// Example of a custom isEqual if lodash is not desired:
/*
function deepCompare(a, b) {
  if (a === b) return true;
  if (a == null || typeof a != 'object' || b == null || typeof b != 'object') return false;

  const keysA = Object.keys(a);
  const keysB = Object.keys(b);

  if (keysA.length !== keysB.length) return false;

  for (let i = 0; i < keysA.length; i++) {
    const key = keysA[i];
    if (!keysB.includes(key) || !deepCompare(a[key], b[key])) {
      return false;
    }
  }
  return true;
}
*/
How it works: The standard `useEffect` hook performs a shallow comparison of its dependency array. When dependencies are complex objects or arrays, this can lead to effects firing too often (if a new object reference is created on every render, even if its content is the same) or not often enough (if the object content changes but its reference doesn't). `useDeepCompareEffect` addresses this by using a deep comparison (here, `lodash.isequal` is suggested) to determine if dependencies have truly changed, thereby optimizing effect execution.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs