useDelayState.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  2. import { useEvent, useMergedState } from 'rc-util';
  3. import raf from "rc-util/es/raf";
  4. import React from 'react';
  5. /**
  6. * Will be `true` immediately for next effect.
  7. * But will be `false` for a delay of effect.
  8. */
  9. export default function useDelayState(value, defaultValue, onChange) {
  10. var _useMergedState = useMergedState(defaultValue, {
  11. value: value
  12. }),
  13. _useMergedState2 = _slicedToArray(_useMergedState, 2),
  14. state = _useMergedState2[0],
  15. setState = _useMergedState2[1];
  16. var nextValueRef = React.useRef(value);
  17. // ============================= Update =============================
  18. var rafRef = React.useRef();
  19. var cancelRaf = function cancelRaf() {
  20. raf.cancel(rafRef.current);
  21. };
  22. var doUpdate = useEvent(function () {
  23. setState(nextValueRef.current);
  24. if (onChange && state !== nextValueRef.current) {
  25. onChange(nextValueRef.current);
  26. }
  27. });
  28. var updateValue = useEvent(function (next, immediately) {
  29. cancelRaf();
  30. nextValueRef.current = next;
  31. if (next || immediately) {
  32. doUpdate();
  33. } else {
  34. rafRef.current = raf(doUpdate);
  35. }
  36. });
  37. React.useEffect(function () {
  38. return cancelRaf;
  39. }, []);
  40. return [state, updateValue];
  41. }