reactUtils.ts 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /**
  2. * @param func handler taking at most single parameter (event).
  3. */
  4. import { version as ReactVersion } from "react";
  5. import { unstable_batchedUpdates } from "react-dom";
  6. import { throttleRAF } from "@excalidraw/common";
  7. export const withBatchedUpdates = <
  8. TFunction extends ((event: any) => void) | (() => void),
  9. >(
  10. func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never,
  11. ) =>
  12. ((event) => {
  13. unstable_batchedUpdates(func as TFunction, event);
  14. }) as TFunction;
  15. /**
  16. * barches React state updates and throttles the calls to a single call per
  17. * animation frame
  18. */
  19. export const withBatchedUpdatesThrottled = <
  20. TFunction extends ((event: any) => void) | (() => void),
  21. >(
  22. func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never,
  23. ) => {
  24. // @ts-ignore
  25. return throttleRAF<Parameters<TFunction>>(((event) => {
  26. unstable_batchedUpdates(func, event);
  27. }) as TFunction);
  28. };
  29. export const isRenderThrottlingEnabled = (() => {
  30. // we don't want to throttle in react < 18 because of #5439 and it was
  31. // getting more complex to maintain the fix
  32. let IS_REACT_18_AND_UP: boolean;
  33. try {
  34. const version = ReactVersion.split(".");
  35. IS_REACT_18_AND_UP = Number(version[0]) > 17;
  36. } catch {
  37. IS_REACT_18_AND_UP = false;
  38. }
  39. let hasWarned = false;
  40. return () => {
  41. if (window.EXCALIDRAW_THROTTLE_RENDER === true) {
  42. if (!IS_REACT_18_AND_UP) {
  43. if (!hasWarned) {
  44. hasWarned = true;
  45. console.warn(
  46. "Excalidraw: render throttling is disabled on React versions < 18.",
  47. );
  48. }
  49. return false;
  50. }
  51. return true;
  52. }
  53. return false;
  54. };
  55. })();