alian926 / daily

学习计划以及总结
0 stars 0 forks source link

21.9.1。人闲桂花落,夜静春山空。 月出惊山鸟,时鸣春涧中。 #10

Open alian926 opened 3 years ago

alian926 commented 3 years ago

Rocoil 仿写,并非官方实现

// 实现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]
        ),
    ];
}
alian926 commented 3 years ago

红尘

求之不得,其为何故