linkmore-design
Version:
π πlmη»δ»ΆεΊγπ
78 lines (77 loc) β’ 2.42 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createContext = createContext;
exports.useContextSelector = useContextSelector;
var _useEvent = _interopRequireDefault(require("rc-util/lib/hooks/useEvent"));
var _useLayoutEffect = _interopRequireDefault(require("rc-util/lib/hooks/useLayoutEffect"));
var React = _interopRequireWildcard(require("react"));
var _reactDom = require("react-dom");
var _shallowequal = _interopRequireDefault(require("shallowequal"));
function createContext(defaultContext) {
const Context = /*#__PURE__*/React.createContext(defaultContext);
const Provider = ({
value,
children
}) => {
const valueRef = React.useRef(value);
valueRef.current = value;
const [context] = React.useState(() => ({
getValue: () => valueRef.current,
listeners: new Set()
}));
(0, _useLayoutEffect.default)(() => {
(0, _reactDom.unstable_batchedUpdates)(() => {
context.listeners.forEach(listener => {
listener(value);
});
});
}, [value]);
return /*#__PURE__*/React.createElement(Context.Provider, {
value: context
}, children);
};
return {
Context,
Provider
};
}
function useContextSelector(holder, selector) {
const eventSelector = (0, _useEvent.default)(typeof selector === 'function' ? selector : ctx => {
if (!Array.isArray(selector)) {
return ctx[selector];
}
const obj = {};
selector.forEach(key => {
obj[key] = ctx[key];
});
return obj;
});
const context = React.useContext(holder?.Context);
const {
listeners,
getValue
} = context || {};
const valueRef = React.useRef();
valueRef.current = eventSelector(context ? getValue() : null);
const [, forceUpdate] = React.useState({});
(0, _useLayoutEffect.default)(() => {
if (!context) {
return;
}
function trigger(nextValue) {
const nextSelectorValue = eventSelector(nextValue);
if (!(0, _shallowequal.default)(valueRef.current, nextSelectorValue)) {
forceUpdate({});
}
}
listeners.add(trigger);
return () => {
listeners.delete(trigger);
};
}, [context]);
return valueRef.current;
}