Immutable.js 4.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. var _typeof = require("@babel/runtime/helpers/typeof");
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.default = createImmutable;
  8. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  9. var _ref = require("rc-util/lib/ref");
  10. var React = _interopRequireWildcard(require("react"));
  11. function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
  12. function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  13. /**
  14. * Create Immutable pair for `makeImmutable` and `responseImmutable`.
  15. */
  16. function createImmutable() {
  17. var ImmutableContext = /*#__PURE__*/React.createContext(null);
  18. /**
  19. * Get render update mark by `makeImmutable` root.
  20. * Do not deps on the return value as render times
  21. * but only use for `useMemo` or `useCallback` deps.
  22. */
  23. function useImmutableMark() {
  24. return React.useContext(ImmutableContext);
  25. }
  26. /**
  27. * Wrapped Component will be marked as Immutable.
  28. * When Component parent trigger render,
  29. * it will notice children component (use with `responseImmutable`) node that parent has updated.
  30. * @param Component Passed Component
  31. * @param triggerRender Customize trigger `responseImmutable` children re-render logic. Default will always trigger re-render when this component re-render.
  32. */
  33. function makeImmutable(Component, shouldTriggerRender) {
  34. var refAble = (0, _ref.supportRef)(Component);
  35. var ImmutableComponent = function ImmutableComponent(props, ref) {
  36. var refProps = refAble ? {
  37. ref: ref
  38. } : {};
  39. var renderTimesRef = React.useRef(0);
  40. var prevProps = React.useRef(props);
  41. // If parent has the context, we do not wrap it
  42. var mark = useImmutableMark();
  43. if (mark !== null) {
  44. return /*#__PURE__*/React.createElement(Component, (0, _extends2.default)({}, props, refProps));
  45. }
  46. if (
  47. // Always trigger re-render if not provide `notTriggerRender`
  48. !shouldTriggerRender || shouldTriggerRender(prevProps.current, props)) {
  49. renderTimesRef.current += 1;
  50. }
  51. prevProps.current = props;
  52. return /*#__PURE__*/React.createElement(ImmutableContext.Provider, {
  53. value: renderTimesRef.current
  54. }, /*#__PURE__*/React.createElement(Component, (0, _extends2.default)({}, props, refProps)));
  55. };
  56. if (process.env.NODE_ENV !== 'production') {
  57. ImmutableComponent.displayName = "ImmutableRoot(".concat(Component.displayName || Component.name, ")");
  58. }
  59. return refAble ? /*#__PURE__*/React.forwardRef(ImmutableComponent) : ImmutableComponent;
  60. }
  61. /**
  62. * Wrapped Component with `React.memo`.
  63. * But will rerender when parent with `makeImmutable` rerender.
  64. */
  65. function responseImmutable(Component, propsAreEqual) {
  66. var refAble = (0, _ref.supportRef)(Component);
  67. var ImmutableComponent = function ImmutableComponent(props, ref) {
  68. var refProps = refAble ? {
  69. ref: ref
  70. } : {};
  71. useImmutableMark();
  72. return /*#__PURE__*/React.createElement(Component, (0, _extends2.default)({}, props, refProps));
  73. };
  74. if (process.env.NODE_ENV !== 'production') {
  75. ImmutableComponent.displayName = "ImmutableResponse(".concat(Component.displayName || Component.name, ")");
  76. }
  77. return refAble ? /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef(ImmutableComponent), propsAreEqual) : /*#__PURE__*/React.memo(ImmutableComponent, propsAreEqual);
  78. }
  79. return {
  80. makeImmutable: makeImmutable,
  81. responseImmutable: responseImmutable,
  82. useImmutableMark: useImmutableMark
  83. };
  84. }