useFrameState.js 1003 B

123456789101112131415161718192021222324252627282930313233343536
  1. import * as React from 'react';
  2. import raf from "rc-util/es/raf";
  3. export default function useFrameState(defaultValue) {
  4. const [value, setValue] = React.useState(defaultValue);
  5. const frameRef = React.useRef(null);
  6. const batchRef = React.useRef([]);
  7. const destroyRef = React.useRef(false);
  8. React.useEffect(() => {
  9. destroyRef.current = false;
  10. return () => {
  11. destroyRef.current = true;
  12. raf.cancel(frameRef.current);
  13. frameRef.current = null;
  14. };
  15. }, []);
  16. function setFrameValue(updater) {
  17. if (destroyRef.current) {
  18. return;
  19. }
  20. if (frameRef.current === null) {
  21. batchRef.current = [];
  22. frameRef.current = raf(() => {
  23. frameRef.current = null;
  24. setValue(prevValue => {
  25. let current = prevValue;
  26. batchRef.current.forEach(func => {
  27. current = func(current);
  28. });
  29. return current;
  30. });
  31. });
  32. }
  33. batchRef.current.push(updater);
  34. }
  35. return [value, setFrameValue];
  36. }