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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 5x 7x 2x 2x 2x 5x 1x 1x 1x 1x 1x 1x 2x 2x 1x 1x 1x 2x 2x 2x 2x 1x 1x 1x 5x 5x 1x 4x 1x 3x 1x 2x 1x 1x | import isEqual from 'react-fast-compare';
/**
* Utility functions for deep comparison and memoization
* to improve React rendering performance
*/
/**
* Creates a memoization-friendly comparison function for React.memo
* Uses react-fast-compare for deep equality checks
* @returns A function that can be used in React.memo to determine if props are equal
*/
export const createDeepEqualityFn = <T>() => {
return (prevProps: T, nextProps: T): boolean => {
const areEqual = isEqual(prevProps, nextProps);
console.log('🔍 Deep equality check:', {
areEqual,
prevProps,
nextProps,
differences: areEqual ? 'None' : detectDifferences(prevProps, nextProps),
timestamp: new Date().toISOString(),
});
return areEqual;
};
};
/**
* Helper function to detect and log specific differences between objects
*/
const detectDifferences = <T>(prev: T, next: T): string[] => {
const differences: string[] = [];
Iif (typeof prev !== typeof next) {
differences.push(`Type changed: ${typeof prev} → ${typeof next}`);
return differences;
}
Iif (prev === null || next === null) {
differences.push(`Null check: ${prev} → ${next}`);
return differences;
}
if (typeof prev === 'object' && typeof next === 'object') {
const prevKeys = Object.keys(prev as any);
const nextKeys = Object.keys(next as any);
// Check for added/removed keys
const addedKeys = nextKeys.filter(key => !prevKeys.includes(key));
const removedKeys = prevKeys.filter(key => !nextKeys.includes(key));
addedKeys.forEach(key => differences.push(`Added key: ${key}`));
removedKeys.forEach(key => differences.push(`Removed key: ${key}`));
// Check for changed values
prevKeys.forEach(key => {
Eif (nextKeys.includes(key)) {
const prevVal = (prev as any)[key];
const nextVal = (next as any)[key];
if (!isEqual(prevVal, nextVal)) {
Iif (typeof prevVal === 'function' && typeof nextVal === 'function') {
differences.push(
`Function changed: ${key} (${prevVal.toString().slice(0, 50)}... → ${nextVal.toString().slice(0, 50)}...)`
);
} else {
differences.push(
`Value changed: ${key} (${JSON.stringify(prevVal)} → ${JSON.stringify(nextVal)})`
);
}
}
}
});
} else E{
differences.push(`Value changed: ${prev} → ${next}`);
}
return differences;
};
/**
* Determines if an array has meaningfully changed by checking:
* 1. If array length has changed
* 2. If first item has changed (using deep equality)
* 3. If last item has changed (using deep equality)
*
* This is a more efficient approach than checking every item
* when dealing with large arrays where most operations occur at the beginning/end
*/
export const hasArrayChanged = <T>(prevArray: T[], nextArray: T[]): boolean => {
// Length check
if (prevArray.length !== nextArray.length) {
return true;
}
// Empty array check
if (prevArray.length === 0) {
return false;
}
// Check first item
if (!isEqual(prevArray[0], nextArray[0])) {
return true;
}
// Check last item for arrays with more than one item
if (
prevArray.length > 1 &&
!isEqual(prevArray[prevArray.length - 1], nextArray[nextArray.length - 1])
) {
return true;
}
return false;
};
/**
* Re-export isEqual from react-fast-compare for consistent usage across the app
* Use this for deep equality checks when you need to compare complex objects
*/
export { isEqual };
|