feat: add useWhyDidYouUpdate

pull/81/head
moonrailgun 3 years ago
parent 1503ca8db1
commit dc85fede9d

@ -0,0 +1,102 @@
/**
* ()
* Fork from: https://github.com/devhubapp/devhub/blob/master/packages/components/src/hooks/use-why-did-you-update.ts
*/
import { parse, stringify } from 'flatted';
import _get from 'lodash/get';
import _isEqual from 'lodash/isEqual';
import { useEffect, useRef } from 'react';
interface UseWhyDidYouUpdateCallback<T> {
onChangeFound?: (data: {
changesObj: Record<
string,
{
from: T;
to: T;
isDeepEqual: boolean;
changedKeys?: string[];
}
>;
}) => void;
onNoChangeFound?: () => void;
}
/**
* Quickly see which prop changed
* and caused a re-render by adding a single line to the component.
*
* USAGE:
* function MyComponent(props) {
* useWhyDidYouUpdate('MyComponent', props)
*
* return <div ... />
* }
*
* OUTPUT:
* [why-did-you-update] MyComponent { myProp: { from 'oldvalue', to: 'newvalue' } }
*
* SHARE:
* This tip on Twitter: https://twitter.com/brunolemos/status/1090377532845801473
* Also follow @brunolemos: https://twitter.com/brunolemos
*/
export function useWhyDidYouUpdate<T>(
name: string,
props: Record<string, T>,
{ onChangeFound, onNoChangeFound }: UseWhyDidYouUpdateCallback<T> = {}
) {
const latestProps = useRef(props);
useEffect(() => {
if (!__DEV__) return;
const allKeys = Object.keys({ ...latestProps.current, ...props });
const changesObj: Record<
string,
{
from: T;
to: T;
isDeepEqual: boolean;
changedKeys?: string[];
}
> = {};
allKeys.forEach((key) => {
if (latestProps.current[key] !== props[key]) {
changesObj[key] = {
from: latestProps.current[key],
to: props[key],
changedKeys:
props[key] && typeof props[key] === 'object'
? Object.keys(latestProps.current[key])
.map((k) =>
_get(latestProps.current, [key, k]) ===
_get(props, [key, k])
? ''
: k
)
.filter(Boolean)
: undefined,
isDeepEqual: _isEqual(latestProps.current[key], props[key]),
};
}
});
if (Object.keys(changesObj).length) {
if (onChangeFound) {
onChangeFound({ changesObj });
} else {
// eslint-disable-next-line no-console
console.log('[why-did-you-update]', name, {
changes: parse(stringify(changesObj)),
props: { from: latestProps.current, to: props },
});
}
} else if (onNoChangeFound) {
onNoChangeFound();
}
latestProps.current = props;
});
}

@ -64,6 +64,7 @@ export { useMountedState } from './hooks/useMountedState';
export { usePrevious } from './hooks/usePrevious';
export { useRafState } from './hooks/useRafState';
export { useUpdateRef } from './hooks/useUpdateRef';
export { useWhyDidYouUpdate } from './hooks/useWhyDidYouUpdate';
// manager
export { buildRegFn } from './manager/buildRegFn';

@ -12,6 +12,7 @@
"crc": "^3.8.0",
"dayjs": "^1.10.6",
"events": "^3.3.0",
"flatted": "^3.2.4",
"formik": "^2.2.9",
"i18next": "^20.3.2",
"i18next-http-backend": "^1.2.6",

@ -5243,6 +5243,11 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.0.tgz#da07fb8808050aba6fdeac2294542e5043583f05"
integrity sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==
flatted@^3.2.4:
version "3.2.4"
resolved "https://registry.npmmirror.com/flatted/download/flatted-3.2.4.tgz?cache=0&sync_timestamp=1636473890680&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fflatted%2Fdownload%2Fflatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2"
integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==
flush-write-stream@^1.0.2:
version "1.1.1"
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8"

Loading…
Cancel
Save