useFrame.js 2.1 KB

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