zp-bee
Version:
zp-bee,是一款基于 Dumi,由 React + TypeScript 开发的组件库 🎉。
260 lines (198 loc) • 7.85 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.atom = atom;
exports.selector = selector;
exports.useCoiledValue = useCoiledValue;
exports.useCoiledState = useCoiledState;
exports.setCoiledState = setCoiledState;
exports.Selector = exports.Atom = exports.Stateful = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _react = require("react");
// 判断是否为对象
function isObject(value) {
return Object.prototype.toString.call(value) === "[object Object]";
} // 浅比较
function shadowEqual(objA, objB) {
if (!isObject(objA)) return objA === objB;
var keysA = Object.keys(objA);
var keysB = Object.keys(objB);
if (keysA.length !== keysB.length) return false;
for (var i = 0, len = keysA.length; i < len; i++) {
if (objB[keysA[i]] !== objA[keysA[i]]) return false;
}
return true;
} // `Stateful`是管理状态和订阅的基类。
// 原子和选择器都是从它派生出来的。
var Stateful = /*#__PURE__*/function () {
// 值属性受保护,因为需要手动
// 在构造函数中赋值(因为继承的特殊性)
function Stateful(value) {
(0, _classCallCheck2.default)(this, Stateful);
this.value = value; // 这是一组独特的回调
this.listeners = new Set();
this.queue = 0;
} // 返回状态的简单方法。这可能会导致严重后果
// 如果你想格外小心的话,就抄吧。
(0, _createClass2.default)(Stateful, [{
key: "snapshot",
value: function snapshot() {
return this.value;
} // emit方法是用新状态更新所有侦听器的方法
// 更新值后,让所有侦听器都知道新值
}, {
key: "emit",
value: function emit() {
for (var _i = 0, _Array$from = Array.from(this.listeners); _i < _Array$from.length; _i++) {
var listener = _Array$from[_i];
listener(this.snapshot());
}
}
}, {
key: "flush",
value: function flush() {
var _this = this;
var cb = function cb() {
_this.queue = 0;
_this.emit();
};
if ((typeof MessageChannel === "undefined" ? "undefined" : (0, _typeof2.default)(MessageChannel)) !== undefined) {
var _MessageChannel = new MessageChannel(),
port1 = _MessageChannel.port1,
port2 = _MessageChannel.port2;
port1.onmessage = cb;
port2.postMessage(null);
} else {
setTimeout(cb);
}
} // update方法是设置state的规范方法。它使用对象
// 平等,以防止不必要的渲染。一个深刻的比较可能是
// 为经常重新创建但相同的复杂对象执行
}, {
key: "update",
value: function update(value) {
if (!shadowEqual(this.value, value)) {
this.value = value;
this.queue += 1; // 批量更新值,防止同时进行多个更新
this.queue === 1 && this.flush();
}
} // subscribe方法允许使用者监听状态更新。调用“disconnect”方法将阻止将来调用回调
}, {
key: "subscribe",
value: function subscribe(callback) {
var _this2 = this;
this.listeners.add(callback);
return {
disconnect: function disconnect() {
_this2.listeners.delete(callback);
}
};
}
}]);
return Stateful;
}(); // atom是围绕“Stateful”基类的薄包装。它有一个更新状态的单一方法。
exports.Stateful = Stateful;
var Atom = /*#__PURE__*/function (_Stateful) {
(0, _inherits2.default)(Atom, _Stateful);
var _super = (0, _createSuper2.default)(Atom);
function Atom() {
(0, _classCallCheck2.default)(this, Atom);
return _super.apply(this, arguments);
}
(0, _createClass2.default)(Atom, [{
key: "setState",
value: function setState(value) {
(0, _get2.default)((0, _getPrototypeOf2.default)(Atom.prototype), "update", this).call(this, value);
}
}]);
return Atom;
}(Stateful); // 它扩展了“Stateful”,以便可以像atoms一样用作值
exports.Atom = Atom;
var Selector = /*#__PURE__*/function (_Stateful2) {
(0, _inherits2.default)(Selector, _Stateful2);
var _super2 = (0, _createSuper2.default)(Selector);
function Selector(generate) {
var _this3;
(0, _classCallCheck2.default)(this, Selector);
// 由于Typescript的继承规则,最初需要对其进行未定义
// 它实际上是“初始化记忆”
_this3 = _super2.call(this, undefined);
_this3.generate = generate; // 跟踪所有已注册的依赖项。我们要确保在它们更改时只重新渲染一次。
_this3.registeredDeps = new Set();
_this3.value = generate({
get: function get(dep) {
return _this3.addDep(dep);
}
});
return _this3;
} // 当调用get函数时,它允许使用者订阅状态更改。此方法订阅依赖项(如果尚未订阅)
(0, _createClass2.default)(Selector, [{
key: "addDep",
value: function addDep(dep) {
var _this4 = this;
if (!this.registeredDeps.has(dep)) {
dep.subscribe(function () {
return _this4.updateSelector();
});
this.registeredDeps.add(dep);
}
return dep.snapshot();
} // 一个助手方法,用于运行内部生成器方法、更新依赖项、返回计算状态和更新所有侦听器。
}, {
key: "updateSelector",
value: function updateSelector() {
var _this5 = this;
this.update(this.generate({
get: function get(dep) {
return _this5.addDep(dep);
}
}));
}
}]);
return Selector;
}(Stateful); // 用于创建新原子的辅助函数
// "key"成员当前未使用。我只是把它放在身边,以保持一个类似的API来Recoil。
exports.Selector = Selector;
function atom(value) {
return new Atom(value.default);
} // 用于创建新选择器的助手方法
// 同样,“key”方法只是为了看起来像Recoil
function selector(value) {
return new Selector(value.get);
} // 每当提供的“Stateful”值更改时,此钩子将重新呈现
// 它可以与“Selector”或“Atom”一起使用。
function useCoiledValue(value) {
var _useState = (0, _react.useState)({}),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
updateState = _useState2[1];
(0, _react.useEffect)(function () {
var _value$subscribe = value.subscribe(function () {
return updateState({});
}),
disconnect = _value$subscribe.disconnect;
return function () {
return disconnect();
};
}, [value]);
return value.snapshot();
} // 与"useCoiledValue"类似,但它也允许您在hooks中设置状态。
function useCoiledState(atom) {
var value = useCoiledValue(atom);
return [value, (0, _react.useCallback)(function (value) {
return atom.setState(value);
}, [atom])];
} // 与"useCoiledState"类似,但它也允许您在全局设置状态。
function setCoiledState(atom) {
return function (value) {
return atom.setState(Object.assign(Object.assign({}, atom.snapshot()), value));
};
}