flitbit / diff

Javascript utility for calculating deep difference, capturing changes, and applying changes across objects; for nodejs and the browser.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Completely crash/freeze Chrome browser with "Error code 6" (network) - DOMException: Blocked a frame with origin "http://localhost:8890" from accessing a cross-origin frame.

Vadorequest opened this issue · comments

This lib seems to run an infinite loop under a particular condition.

The loops completely freezes the browser.

image

Here's the code. I've commented the use of diff, which fixes the infinite loop issue.

I tried to run diff only if isObjectLike is true, but that doesn't work because it's one of the object properties that causes the infinite loop.

import { diff } from 'deep-diff';
import isObjectLike from 'lodash.isobjectlike';
import {
  useEffect,
  useRef,
} from 'react';

/**
 * Helps tracking the props changes made in a react functional component.
 *
 * Prints the name and old/new values of the properties/states variables causing a render (or re-render).
 * For debugging purposes only.
 *
 * @usage You can simply track the props of the components like this:
 *  useRenderingTrace('MyComponent', props);
 *
 * @usage You can also track additional state like this:
 *  const [someState] = useState(null);
 *  useRenderingTrace('MyComponent', { ...props, someState });
 *
 * @param componentName Name of the component to display
 * @param propsAndStates
 * @param level
 *
 * @see https://stackoverflow.com/a/51082563/2391795
 */
const useRenderingTrace = (componentName: string, propsAndStates: any, level: 'debug' | 'info' | 'log' = 'debug') => {
  const prev = useRef(propsAndStates);

  useEffect(() => {
    console.log('useRenderingTrace', propsAndStates);
    const changedProps: { [key: string]: { old: any, new: any } } = Object.entries(propsAndStates).reduce((property: any, [key, value]: [string, any]) => {
      console.log('useRenderingTrace property', property, key, value);
      if (prev.current[key] !== value) {
        let diffValue = undefined;
        // try {
        //   if (isObjectLike(prev.current[key]) && isObjectLike(value)) {
        //     diffValue = diff(prev.current[key], value);
        //   } else {
        //     console.log('Ignoring ', property, 'not an object/array')
        //   }
        // } catch (e) {
        //   // Not an object/array, cannot make a diff
        //   console.error(e);
        // }
        property[key] = {
          old: prev.current[key],
          new: value,
        };

        if (typeof diffValue !== 'undefined') {
          property[key].diff = diffValue;
        }
      }
      return property;
    }, {});

    if (Object.keys(changedProps).length > 0) {
      console[level](`[${componentName}] Changed props:`, changedProps);
    }

    prev.current = propsAndStates;
    console.log('end of useRenderingTrace', propsAndStates);
  });
};

export default useRenderingTrace;