首页 > 解决方案 > 在 mobX 中,一个 store 可以“监听”另一个 store,并在另一个 store 发生变化时执行查询?

问题描述

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

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;
    }
}

另一家商店也存在

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);
        }


    }
}

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

标签: javascriptreactjsstoremobx

解决方案


我想你可能正在寻找反应

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

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()
        );
    }

    // ...
}

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

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

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


推荐阅读