You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
1.1 KiB

import * as React from 'react';
/**
* Always debounce error to avoid [error -> null -> error] blink
*/
export default function useCacheErrors(
errors: React.ReactNode[],
changeTrigger: (visible: boolean) => void,
directly: boolean,
): [boolean, React.ReactNode[]] {
const cacheRef = React.useRef({
errors,
visible: !!errors.length,
});
const [, forceUpdate] = React.useState({});
const update = () => {
const prevVisible = cacheRef.current.visible;
const newVisible = !!errors.length;
const prevErrors = cacheRef.current.errors;
cacheRef.current.errors = errors;
cacheRef.current.visible = newVisible;
if (prevVisible !== newVisible) {
changeTrigger(newVisible);
} else if (
prevErrors.length !== errors.length ||
prevErrors.some((prevErr, index) => prevErr !== errors[index])
) {
forceUpdate({});
}
};
React.useEffect(() => {
if (!directly) {
const timeout = setTimeout(update, 10);
return () => clearTimeout(timeout);
}
}, [errors]);
if (directly) {
update();
}
return [cacheRef.current.visible, cacheRef.current.errors];
}