zp-bee
Version:
zp-bee,是一款基于 Dumi,由 React + TypeScript 开发的组件库 🎉。
230 lines (183 loc) • 7.02 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _get from "@babel/runtime/helpers/esm/get";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
import _typeof from "@babel/runtime/helpers/esm/typeof";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import { useCallback, useEffect, useState } from '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`是管理状态和订阅的基类。
// 原子和选择器都是从它派生出来的。
export var Stateful = /*#__PURE__*/function () {
// 值属性受保护,因为需要手动
// 在构造函数中赋值(因为继承的特殊性)
function Stateful(value) {
_classCallCheck(this, Stateful);
this.value = value; // 这是一组独特的回调
this.listeners = new Set();
this.queue = 0;
} // 返回状态的简单方法。这可能会导致严重后果
// 如果你想格外小心的话,就抄吧。
_createClass(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" : _typeof(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”基类的薄包装。它有一个更新状态的单一方法。
export var Atom = /*#__PURE__*/function (_Stateful) {
_inherits(Atom, _Stateful);
var _super = _createSuper(Atom);
function Atom() {
_classCallCheck(this, Atom);
return _super.apply(this, arguments);
}
_createClass(Atom, [{
key: "setState",
value: function setState(value) {
_get(_getPrototypeOf(Atom.prototype), "update", this).call(this, value);
}
}]);
return Atom;
}(Stateful); // 它扩展了“Stateful”,以便可以像atoms一样用作值
export var Selector = /*#__PURE__*/function (_Stateful2) {
_inherits(Selector, _Stateful2);
var _super2 = _createSuper(Selector);
function Selector(generate) {
var _this3;
_classCallCheck(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函数时,它允许使用者订阅状态更改。此方法订阅依赖项(如果尚未订阅)
_createClass(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。
export function atom(value) {
return new Atom(value.default);
} // 用于创建新选择器的助手方法
// 同样,“key”方法只是为了看起来像Recoil
export function selector(value) {
return new Selector(value.get);
} // 每当提供的“Stateful”值更改时,此钩子将重新呈现
// 它可以与“Selector”或“Atom”一起使用。
export function useCoiledValue(value) {
var _useState = useState({}),
_useState2 = _slicedToArray(_useState, 2),
updateState = _useState2[1];
useEffect(function () {
var _value$subscribe = value.subscribe(function () {
return updateState({});
}),
disconnect = _value$subscribe.disconnect;
return function () {
return disconnect();
};
}, [value]);
return value.snapshot();
} // 与"useCoiledValue"类似,但它也允许您在hooks中设置状态。
export function useCoiledState(atom) {
var value = useCoiledValue(atom);
return [value, useCallback(function (value) {
return atom.setState(value);
}, [atom])];
} // 与"useCoiledState"类似,但它也允许您在全局设置状态。
export function setCoiledState(atom) {
return function (value) {
return atom.setState(Object.assign(Object.assign({}, atom.snapshot()), value));
};
}