Open
Description
This lib seems to run an infinite loop under a particular condition.
The loops completely freezes the browser.
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;
Metadata
Metadata
Assignees
Labels
No labels
Activity