useFrame.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  2. import { useRef, useState, useEffect } from 'react';
  3. /**
  4. * Execute code before next frame but async
  5. */
  6. export function useLayoutState(defaultState) {
  7. var stateRef = useRef(defaultState);
  8. var _useState = useState({}),
  9. _useState2 = _slicedToArray(_useState, 2),
  10. forceUpdate = _useState2[1];
  11. var lastPromiseRef = useRef(null);
  12. var updateBatchRef = useRef([]);
  13. function setFrameState(updater) {
  14. updateBatchRef.current.push(updater);
  15. var promise = Promise.resolve();
  16. lastPromiseRef.current = promise;
  17. promise.then(function () {
  18. if (lastPromiseRef.current === promise) {
  19. var prevBatch = updateBatchRef.current;
  20. var prevState = stateRef.current;
  21. updateBatchRef.current = [];
  22. prevBatch.forEach(function (batchUpdater) {
  23. stateRef.current = batchUpdater(stateRef.current);
  24. });
  25. lastPromiseRef.current = null;
  26. if (prevState !== stateRef.current) {
  27. forceUpdate({});
  28. }
  29. }
  30. });
  31. }
  32. useEffect(function () {
  33. return function () {
  34. lastPromiseRef.current = null;
  35. };
  36. }, []);
  37. return [stateRef.current, setFrameState];
  38. }
  39. /** Lock frame, when frame pass reset the lock. */
  40. export function useTimeoutLock(defaultState) {
  41. var frameRef = useRef(defaultState || null);
  42. var timeoutRef = useRef();
  43. function cleanUp() {
  44. window.clearTimeout(timeoutRef.current);
  45. }
  46. function setState(newState) {
  47. frameRef.current = newState;
  48. cleanUp();
  49. timeoutRef.current = window.setTimeout(function () {
  50. frameRef.current = null;
  51. timeoutRef.current = undefined;
  52. }, 100);
  53. }
  54. function getState() {
  55. return frameRef.current;
  56. }
  57. useEffect(function () {
  58. return cleanUp;
  59. }, []);
  60. return [setState, getState];
  61. }