在 mobX 中,一个存储可以“监听”其他存储,并在其他存储发生变化时执行查询吗?

pau*_*l23 5 javascript store reactjs mobx

假设我有一个商店,其中有一个组织列表,用户可以“选择”组织,然后将其存储在“filter”数组中。

export class OrganizationStore extends ArrayStore {
    //organizations = new Map();

    constructor( ...args) {
        super(args);
        this.organizations = new Map();
        this.filter = [];
        this.getter_url = '/organization/get-organizations';
    }

    async getData() {
        const full_url = new URL(this.getter_url);
        const options = {};
        options.method = 'GET';
        options.credentials = process.env.NODE_ENV === 'production' ? 'same-origin' : 'include';

        const response = await fetch(full_url, options);
        if (response.ok) {
            const d = await response.json();
            this.buildStore(d);
        }

    }

    buildStore(values) {
        this.organizations.clear();
        for (const {id, name} of values) {
            this.organizations.set(id, new Organization(id, name));
        }
    }

    get count() {
        return this.organizations.size;
    }
}

decorate(OrganizationStore, {
    organizations: observable,
    filter: observable,
    count: computed,
});



export class Organization {
    constructor(id, name) {
        this.id = id;
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

还有另一家商店

export class UserStore extends ArrayStore {
    constructor(organizationStore, ...args) {
        super(args);
        this.users = [];
        this.getter_url = '/users/get-users';
        this.organizationStore = organizationStore;
    }

    async getData() {
        const full_url = new URL(this.getter_url);
        const options = {};
        options.method = 'GET';
        options.credentials = process.env.NODE_ENV === 'production' ? 'same-origin' : 'include';

        query = {filter: this.organizationStore.filter()};
        //how to make this line "observe" the original store

        Object.keys(query).forEach(key => full_url.searchParams.append(key, options.query[key]));


        const response = await fetch(full_url, options);
        if (response.ok) {
            const d = await response.json();
            this.buildStore(d);
        }


    }
}
Run Code Online (Sandbox Code Playgroud)

现在(如何)我可以使商店自动刷新(让 getData 在organizationStore.filter[]更改后重新运行)?

Wol*_*fie 3

我想您可能正在寻找反应

反应 - 自动运行的一种变体,可以对跟踪的可观察量进行更细粒度的控制。它需要两个函数,第一个函数(数据函数)被跟踪并返回用作第二个函数(效果函数)的输入的数据。

export class UserStore extends ArrayStore {
    constructor(organizationStore, ...args) {
        super(args);
        this.users = [];
        this.getter_url = '/users/get-users';
        this.organizationStore = organizationStore;

        // Dispose of this when done with it
        const disposer = reaction(
            () => this.organizationStore.filter.length,
            () => this.getData()
        );
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果您想要对事件进行更多控制,另一种选择是使用观察

const disposer = observe(this.organizationStore.filter, (change) => {
    // Change is an object with a couple properties that describe what has changed and how
});
Run Code Online (Sandbox Code Playgroud)

但我认为反应对你来说很好。