ant-design/components/form/hooks/useFrameState.ts
二货机器人 b8eaecb898
fix: Form in React 18 StrictMode (#35096)
* test: fix with react 18

* fix: Form in StrictMode

* test: clean up

* test: clean up

* chore: bump rc-motion version

* chore: fix test case logic

* test: back of it

* test: back missing test case
2022-04-19 20:06:32 +08:00

50 lines
1.2 KiB
TypeScript

import * as React from 'react';
import { useRef } from 'react';
import raf from 'rc-util/lib/raf';
type Updater<ValueType> = (prev?: ValueType) => ValueType;
export default function useFrameState<ValueType>(
defaultValue: ValueType,
): [ValueType, (updater: Updater<ValueType>) => void] {
const [value, setValue] = React.useState(defaultValue);
const frameRef = useRef<number | null>(null);
const batchRef = useRef<Updater<ValueType>[]>([]);
const destroyRef = useRef(false);
React.useEffect(() => {
destroyRef.current = false;
return () => {
destroyRef.current = true;
raf.cancel(frameRef.current!);
frameRef.current = null;
};
}, []);
function setFrameValue(updater: Updater<ValueType>) {
if (destroyRef.current) {
return;
}
if (frameRef.current === null) {
batchRef.current = [];
frameRef.current = raf(() => {
frameRef.current = null;
setValue(prevValue => {
let current = prevValue;
batchRef.current.forEach(func => {
current = func(current);
});
return current;
});
});
}
batchRef.current.push(updater);
}
return [value, setFrameValue];
}