3

注意:我使用 Reflux 作为我的 Flux 库,因此示例将使用它的语法。然而,这个问题通常适用于 Flux。

在我的示例 Flux 应用程序中,我有一个productStore.js文件保存系统中产品的状态并监听各种产品管理操作,REMOVE_PRODUCT例如ADD_PRODUCT.

这是商店中的示例数据:

{
    products: [
        {
            productName: "A"
        },
        {
            productName: "B"
        }
    ]
}

现在我想向REFRESH_PRODUCTS组件添加一个动作。

调用如下所示:

组件.jsx

onRefresh(e) {
    actions.refreshProducts();
}

由于刷新产品是一个异步操作,我想在它继续时显示微调器,如果它失败则显示错误。显而易见的 Flux 方式是将加载状态和结果错误(如果发生这种情况)添加到存储中,如下所示:

productStore.js

onRefreshProducts() {

    logger.info("Logging in:", email);
    this.storeData.inProgress = true;
    this.storeData.error = null;
    this.trigger(this.data);

    api.getProducts()
        .then((response) => {
            this.storeData.products = response.data.products;
        })
        .catch((response) => {
            this.storeData.error = error;
        })
        .then(() => {
            this.storeData.inProgress = false;
            this.trigger(this.data);
        });
}

现在数据的存储因各种标志而变得肮脏:

{
    inProgress: false,
    error: null,

    products: [
        {
            productName: "A"
        },
        {
            productName: "B"
        }
    ]
}

如果多个组件需要查看产品加载进度或刷新失败,这种状态对我来说非常好,但以防万一,没有其他组件需要这种信息。所以感觉我在没有充分理由的情况下将私有数据置于全局状态。

我希望能够做这样的事情:

component.jsx - 错误代码

onRefresh(e) {

    this.setState({error: false, inProgress: true});
    actions.refreshProducts()
        .catch(function(err) {
            this.setState({error: err});
        })
        .then(function() {
            this.setState({inProgress: false});
        });
}

然后我可以保持商店的代码干净。但是,我没有明显的方法来做到这一点 - 根据设计,动作创建了一个不允许从动作返回数据的分离。

正确的方法是什么?如何在将相关数据保持在全局状态之外的同时执行私有微调器/错误/等?

4

2 回答 2

1

这是我在写这个问题时想到的一个解决方案:

  • 在商店上创建一个允许通过参数更新产品数据的新操作,例如:refreshProductFromData
  • 直接从组件调用 API
  • 操作组件中的微调器/错误处理
  • 通过新操作将从 API 检索到的数据传递到存储区

像这样:

组件.jsx

onRefresh(e) {

    this.setState({error: false, inProgress: true});
    api.getProducts()
        .then(function(data) {
            actions.refreshProductFromData(response.data.products);
        });
        .catch(function(err) {
            this.setState({error: err});
        })
        .then(function() {
            this.setState({inProgress: false});
        });
}

但是不确定它是否是正确/最佳的解决方案。

于 2015-06-17T21:32:39.567 回答
0

我找到了你的帖子,因为我有同样的问题。我想我会像这样构建我的结构,保持一切解耦并通过行动进行交流。我喜欢保持组件和存储对 API 的无知。

  • 产品操作知道如何与 API 交互以完成请求的操作。
  • Product Store 侦听 Completed 操作以更新其内部状态。
  • LoadingActions 管理微调器状态,并在启动 API 调用时被要求显示/隐藏微调器。
  • 我有一个 Spinner 组件,它侦听 LoadingActions 并更新其状态以显示/隐藏微调器。

零件:

actions.refresh();

(产品)行动:

onRefresh: function () {
    LoadingActions.showSpinner();
    api.loadProducts().then(this.completed, this.failed).finally(LoadingActions.hideSpinner);
}

加载动作:

onShowSpinner: function () { ... }
onHideSpinner: function () { ... }

店铺:

onRefreshCompleted: function (data) {
    this.products = data;
    this.trigger();
}
于 2015-11-03T15:17:41.387 回答