Open alian926 opened 3 years ago
// 实现atom和selector的基类 class Stateful { listeners = new Set(); constructor(value) {} _update(value) { this.value = value; this.emit(); } snapshot() { return this.value; } emit() { for (const listener of this.listeners) { listener(this.snapshot()); } } subscribe(callback) { this.listeners.add(callback); return { disconnect: () => { this.listeners.delete(callback); }, }; } } class Atom extends Stateful { update(value) { super._update(value); } } function generate(context) { const name = context.get(NameAtom); const age = context.get(AgeAtom); return `${name} is ${age} years old`; } class Selector extends Stateful { registeredDeps = new Set(); constructor(generate) { super(); const context = { get: (dep) => this.getDep(dep), }; this.generate = generate; this.value = generate(context); } getDep(dep) { if (!this.registeredDeps.has(dep)) { dep.subscribe(() => this.updateSelector()); this.registeredDeps.add(dep); } return dep.snapshot(); } updateSelector() { const context = { get: dep => this.getDep(dep) } this.update(this.generate(context)) } } // 通过辅助函数创建对象, 去掉类 function atom(payload) { return new Atom(payload.default) } function selector(payload) { return new Selector(payload.get) } // 连接Atom 和 react function useCoiledValue(stateful) { const [, updateState] = useState({}); useEffect(() => { const { disconnect } = stateful.subscribe(() => updateState({})); return () => disconnect(); }, [stateful]); return stateful.snapshot(); } // 类似useState function useCoiledState(stateful) { const value = useCoiledValue(stateful); return [ value, useCallback( (value) => { stateful.update(value); }, [stateful] ), ]; }
求之不得,其为何故
Rocoil 仿写,并非官方实现