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.
61 lines
1.5 KiB
61 lines
1.5 KiB
5 years ago
|
import * as React from 'react';
|
||
|
|
||
|
/**
|
||
|
* We will remove light way shake like:
|
||
|
* errors -> none -> errors (in 100 ms)
|
||
|
* to
|
||
|
* errors (in 100 ms)
|
||
|
*/
|
||
|
function useDebounce<T>(content: T[], delay: number = 10): T[] {
|
||
|
const [cache, setCache] = React.useState(content);
|
||
|
|
||
|
// React hooks still have bug with unmount setState
|
||
|
// https://github.com/facebook/react/issues/15057
|
||
|
React.useEffect(() => {
|
||
|
if (content.length) {
|
||
|
setCache(content);
|
||
|
} else {
|
||
|
const timeout = setTimeout(() => {
|
||
|
setCache(content);
|
||
|
}, delay);
|
||
|
|
||
|
return () => {
|
||
|
clearTimeout(timeout);
|
||
|
};
|
||
|
}
|
||
|
}, [content]);
|
||
|
|
||
|
return cache;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Cache latest errors and trigger change event if visible change
|
||
|
*/
|
||
|
export function useCacheErrors(
|
||
|
errors: React.ReactNode[],
|
||
|
changeTrigger: (visible: boolean) => void,
|
||
|
) {
|
||
|
const debounceErrors = useDebounce(errors);
|
||
|
const [cacheErrors, setCacheErrors] = React.useState(debounceErrors);
|
||
|
const [visible, setVisible] = React.useState(false);
|
||
|
|
||
|
React.useEffect(() => {
|
||
|
const newVisible = !!debounceErrors.length;
|
||
|
if (debounceErrors.length) {
|
||
|
setCacheErrors(debounceErrors);
|
||
|
}
|
||
|
if (newVisible !== visible) {
|
||
|
changeTrigger(newVisible);
|
||
|
}
|
||
|
setVisible(newVisible);
|
||
|
}, [debounceErrors]);
|
||
|
|
||
|
return [visible, cacheErrors];
|
||
|
}
|
||
|
|
||
|
export function toArray<T>(candidate?: T | T[] | false): T[] {
|
||
|
if (candidate === undefined || candidate === false) return [];
|
||
|
|
||
|
return Array.isArray(candidate) ? candidate : [candidate];
|
||
|
}
|