useGlobalCache.js 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  2. import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
  3. import * as React from 'react';
  4. import { pathKey } from "../Cache";
  5. import StyleContext from "../StyleContext";
  6. import useCompatibleInsertionEffect from "./useCompatibleInsertionEffect";
  7. import useEffectCleanupRegister from "./useEffectCleanupRegister";
  8. import useHMR from "./useHMR";
  9. export default function useGlobalCache(prefix, keyPath, cacheFn, onCacheRemove,
  10. // Add additional effect trigger by `useInsertionEffect`
  11. onCacheEffect) {
  12. var _React$useContext = React.useContext(StyleContext),
  13. globalCache = _React$useContext.cache;
  14. var fullPath = [prefix].concat(_toConsumableArray(keyPath));
  15. var fullPathStr = pathKey(fullPath);
  16. var register = useEffectCleanupRegister([fullPathStr]);
  17. var HMRUpdate = useHMR();
  18. var buildCache = function buildCache(updater) {
  19. globalCache.opUpdate(fullPathStr, function (prevCache) {
  20. var _ref = prevCache || [undefined, undefined],
  21. _ref2 = _slicedToArray(_ref, 2),
  22. _ref2$ = _ref2[0],
  23. times = _ref2$ === void 0 ? 0 : _ref2$,
  24. cache = _ref2[1];
  25. // HMR should always ignore cache since developer may change it
  26. var tmpCache = cache;
  27. if (process.env.NODE_ENV !== 'production' && cache && HMRUpdate) {
  28. onCacheRemove === null || onCacheRemove === void 0 || onCacheRemove(tmpCache, HMRUpdate);
  29. tmpCache = null;
  30. }
  31. var mergedCache = tmpCache || cacheFn();
  32. var data = [times, mergedCache];
  33. // Call updater if need additional logic
  34. return updater ? updater(data) : data;
  35. });
  36. };
  37. // Create cache
  38. React.useMemo(function () {
  39. buildCache();
  40. }, /* eslint-disable react-hooks/exhaustive-deps */
  41. [fullPathStr]
  42. /* eslint-enable */);
  43. var cacheEntity = globalCache.opGet(fullPathStr);
  44. // HMR clean the cache but not trigger `useMemo` again
  45. // Let's fallback of this
  46. // ref https://github.com/ant-design/cssinjs/issues/127
  47. if (process.env.NODE_ENV !== 'production' && !cacheEntity) {
  48. buildCache();
  49. cacheEntity = globalCache.opGet(fullPathStr);
  50. }
  51. var cacheContent = cacheEntity[1];
  52. // Remove if no need anymore
  53. useCompatibleInsertionEffect(function () {
  54. onCacheEffect === null || onCacheEffect === void 0 || onCacheEffect(cacheContent);
  55. }, function (polyfill) {
  56. // It's bad to call build again in effect.
  57. // But we have to do this since StrictMode will call effect twice
  58. // which will clear cache on the first time.
  59. buildCache(function (_ref3) {
  60. var _ref4 = _slicedToArray(_ref3, 2),
  61. times = _ref4[0],
  62. cache = _ref4[1];
  63. if (polyfill && times === 0) {
  64. onCacheEffect === null || onCacheEffect === void 0 || onCacheEffect(cacheContent);
  65. }
  66. return [times + 1, cache];
  67. });
  68. return function () {
  69. globalCache.opUpdate(fullPathStr, function (prevCache) {
  70. var _ref5 = prevCache || [],
  71. _ref6 = _slicedToArray(_ref5, 2),
  72. _ref6$ = _ref6[0],
  73. times = _ref6$ === void 0 ? 0 : _ref6$,
  74. cache = _ref6[1];
  75. var nextCount = times - 1;
  76. if (nextCount === 0) {
  77. // Always remove styles in useEffect callback
  78. register(function () {
  79. // With polyfill, registered callback will always be called synchronously
  80. // But without polyfill, it will be called in effect clean up,
  81. // And by that time this cache is cleaned up.
  82. if (polyfill || !globalCache.opGet(fullPathStr)) {
  83. onCacheRemove === null || onCacheRemove === void 0 || onCacheRemove(cache, false);
  84. }
  85. });
  86. return null;
  87. }
  88. return [times - 1, cache];
  89. });
  90. };
  91. }, [fullPathStr]);
  92. return cacheContent;
  93. }