@supunlakmal/hooks
Version:
A collection of reusable React hooks
68 lines • 3.05 kB
JavaScript
import { useEffect, useRef } from 'react';
/**
* Hook for debugging component re-renders in React.
* Logs the props that changed between renders, helping identify performance bottlenecks.
*
* Usage: Call this hook within your component, passing the component name and its props.
* useWhyDidYouUpdate('MyComponent', props);
*
* @param componentName The name of the component being debugged (for logging purposes).
* @param props The current props object of the component.
*/
export const useWhyDidYouUpdate = (componentName, props) => {
// Use a ref to store the previous props
const previousProps = useRef(undefined);
useEffect(() => {
if (previousProps.current) {
// Get keys of all current and previous props
const allKeys = Object.keys(Object.assign(Object.assign({}, previousProps.current), props));
// Object to store changes
const changesObj = {};
// Iterate through keys
allKeys.forEach((key) => {
var _a;
// Check if prop exists in previous props
const hasPrevProp = (_a = previousProps.current) === null || _a === void 0 ? void 0 : _a.hasOwnProperty(key);
// Check if prop exists in current props
const hasCurrentProp = props.hasOwnProperty(key);
// Compare values if the prop exists in both
if (hasPrevProp && hasCurrentProp) {
if (previousProps.current &&
previousProps.current[key] !== props[key]) {
changesObj[key] = {
from: previousProps.current[key],
to: props[key],
};
}
}
else if (hasPrevProp && !hasCurrentProp) {
// Prop removed
changesObj[key] = {
from: previousProps.current
? previousProps.current[key]
: undefined,
to: undefined,
};
}
else if (!hasPrevProp && hasCurrentProp) {
// Prop added
changesObj[key] = {
from: undefined,
to: props[key],
};
}
});
// If changes were detected, log them
if (Object.keys(changesObj).length) {
console.log(`[why-did-you-update] ${componentName}:`, changesObj);
}
// Optional: Log if no props changed but component still re-rendered
// else {
// console.log(`[why-did-you-update] ${componentName}: Re-rendered without prop changes.`);
// }
}
// Update the ref with the current props for the next render
previousProps.current = props;
}); // Runs after every render
};
//# sourceMappingURL=useWhyDidYouUpdate.js.map