Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

useThrottledEventHandler.js 2.8 KiB

há 3 anos
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. "use strict";
  2. exports.__esModule = true;
  3. exports.default = useThrottledEventHandler;
  4. var _react = require("react");
  5. var _useMounted = _interopRequireDefault(require("./useMounted"));
  6. var _useEventCallback = _interopRequireDefault(require("./useEventCallback"));
  7. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8. function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  9. var isSyntheticEvent = function isSyntheticEvent(event) {
  10. return typeof event.persist === 'function';
  11. };
  12. /**
  13. * Creates a event handler function throttled by `requestAnimationFrame` that
  14. * returns the **most recent** event. Useful for noisy events that update react state.
  15. *
  16. * ```tsx
  17. * function Component() {
  18. * const [position, setPosition] = useState();
  19. * const handleMove = useThrottledEventHandler<React.PointerEvent>(
  20. * (event) => {
  21. * setPosition({
  22. * top: event.clientX,
  23. * left: event.clientY,
  24. * })
  25. * }
  26. * )
  27. *
  28. * return (
  29. * <div onPointerMove={handleMove}>
  30. * <div style={position} />
  31. * </div>
  32. * );
  33. * }
  34. * ```
  35. *
  36. * @param handler An event handler function
  37. * @typeParam TEvent The event object passed to the handler function
  38. * @returns The event handler with a `clear` method attached for clearing any in-flight handler calls
  39. *
  40. */
  41. function useThrottledEventHandler(handler) {
  42. var isMounted = (0, _useMounted.default)();
  43. var eventHandler = (0, _useEventCallback.default)(handler);
  44. var nextEventInfoRef = (0, _react.useRef)({
  45. event: null,
  46. handle: null
  47. });
  48. var clear = function clear() {
  49. cancelAnimationFrame(nextEventInfoRef.current.handle);
  50. nextEventInfoRef.current.handle = null;
  51. };
  52. var handlePointerMoveAnimation = function handlePointerMoveAnimation() {
  53. var next = nextEventInfoRef.current;
  54. if (next.handle && next.event) {
  55. if (isMounted()) {
  56. next.handle = null;
  57. eventHandler(next.event);
  58. }
  59. }
  60. next.event = null;
  61. };
  62. var throttledHandler = function throttledHandler(event) {
  63. if (!isMounted()) return;
  64. if (isSyntheticEvent(event)) {
  65. event.persist();
  66. } // Special handling for a React.Konva event which reuses the
  67. // event object as it bubbles, setting target
  68. else if ('evt' in event) {
  69. event = _extends({}, event);
  70. }
  71. nextEventInfoRef.current.event = event;
  72. if (!nextEventInfoRef.current.handle) {
  73. nextEventInfoRef.current.handle = requestAnimationFrame(handlePointerMoveAnimation);
  74. }
  75. };
  76. throttledHandler.clear = clear;
  77. return throttledHandler;
  78. }