useUpdate.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  2. import { useLayoutUpdateEffect } from "rc-util/es/hooks/useLayoutEffect";
  3. import { useRef, useState } from 'react';
  4. /**
  5. * Help to merge callback with `useLayoutEffect`.
  6. * One time will only trigger once.
  7. */
  8. export default function useUpdate(callback) {
  9. var _useState = useState(0),
  10. _useState2 = _slicedToArray(_useState, 2),
  11. count = _useState2[0],
  12. setCount = _useState2[1];
  13. var effectRef = useRef(0);
  14. var callbackRef = useRef();
  15. callbackRef.current = callback;
  16. // Trigger on `useLayoutEffect`
  17. useLayoutUpdateEffect(function () {
  18. var _callbackRef$current;
  19. (_callbackRef$current = callbackRef.current) === null || _callbackRef$current === void 0 || _callbackRef$current.call(callbackRef);
  20. }, [count]);
  21. // Trigger to update count
  22. return function () {
  23. if (effectRef.current !== count) {
  24. return;
  25. }
  26. effectRef.current += 1;
  27. setCount(effectRef.current);
  28. };
  29. }
  30. export function useUpdateState(defaultState) {
  31. var batchRef = useRef([]);
  32. var _useState3 = useState({}),
  33. _useState4 = _slicedToArray(_useState3, 2),
  34. forceUpdate = _useState4[1];
  35. var state = useRef(typeof defaultState === 'function' ? defaultState() : defaultState);
  36. var flushUpdate = useUpdate(function () {
  37. var current = state.current;
  38. batchRef.current.forEach(function (callback) {
  39. current = callback(current);
  40. });
  41. batchRef.current = [];
  42. state.current = current;
  43. forceUpdate({});
  44. });
  45. function updater(callback) {
  46. batchRef.current.push(callback);
  47. flushUpdate();
  48. }
  49. return [state.current, updater];
  50. }