react-singleton-hook
Version:
Share custom hook state across all components
65 lines (63 loc) • 2.03 kB
JavaScript
;
exports.__esModule = true;
exports.singletonHook = void 0;
var _react = require("react");
var _SingletonHooksContainer = require("./components/SingletonHooksContainer");
var _env = require("./utils/env");
var singletonHook = function singletonHook(initValue, useHookBody, options) {
if (options === void 0) {
options = {};
}
var mounted = false;
var removeHook = undefined;
var initStateCalculated = false;
var lastKnownState = undefined;
var consumers = [];
var _options = options,
_options$unmountIfNoC = _options.unmountIfNoConsumers,
unmountIfNoConsumers = _options$unmountIfNoC === void 0 ? false : _options$unmountIfNoC;
var applyStateChange = function applyStateChange(newState) {
lastKnownState = newState;
(0, _env.batch)(function () {
return consumers.forEach(function (c) {
return c(newState);
});
});
};
var stateInitializer = function stateInitializer() {
if (!initStateCalculated) {
lastKnownState = typeof initValue === 'function' ? initValue() : initValue;
initStateCalculated = true;
}
return lastKnownState;
};
return function () {
var _useState = (0, _react.useState)(stateInitializer),
state = _useState[0],
setState = _useState[1];
(0, _react.useEffect)(function () {
if (!mounted) {
mounted = true;
removeHook = (0, _SingletonHooksContainer.addHook)({
initValue: initValue,
useHookBody: useHookBody,
applyStateChange: applyStateChange
});
}
consumers.push(setState);
if (lastKnownState !== state) {
setState(lastKnownState);
}
return function () {
consumers.splice(consumers.indexOf(setState), 1);
if (consumers.length === 0 && unmountIfNoConsumers) {
removeHook();
mounted = false;
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return state;
};
};
exports.singletonHook = singletonHook;