如何保留本地组件数据,例如微调器/错误,在 Flux 商店之外?
Posted
技术标签:
【中文标题】如何保留本地组件数据,例如微调器/错误,在 Flux 商店之外?【英文标题】:How to keep local component data , e.g. spinners/errors, outside of Flux stores? 【发布时间】:2015-09-03 08:00:19 【问题描述】:注意:我使用 Reflux 作为我的 Flux 库,因此示例将使用它的语法。然而,这个问题一般适用于 Flux。
在我的 Flux 示例应用程序中,我有一个 productStore.js
文件,它保存系统中产品的状态并监听各种产品管理操作,例如 REMOVE_PRODUCT
、ADD_PRODUCT
。
这是商店中的示例数据:
products: [
productName: "A"
,
productName: "B"
]
现在我想向组件添加一个REFRESH_PRODUCTS
操作。
调用看起来像这样:
component.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);
);
然后我可以保持 store 的代码干净。但是,我没有明显的方法来做到这一点 - 根据设计,操作创建了一个不允许从操作返回数据的分隔。
正确的方法是什么?如何在将相关数据保持在全局状态之外的同时执行私有微调器/错误/等?
【问题讨论】:
为什么不把它设置在组件的状态上,而不是在商店里呢?像往常一样使用 setState()。如果我正确理解您的问题 - 对于页面范围的状态,我使用商店 - 对于特定于组件的状态,我只是将其存储在那里。 因为商品数据应该在商店中。所以我确实想更新商店。我只想将进程的进度/错误处理保留在组件内。 【参考方案1】:这是我在写这个问题时想到的一个解决方案:
在商店中创建一个允许通过参数更新产品数据的新操作,例如:refreshProductFromData
直接从组件调用 API
在组件中操作微调器/错误处理
通过新操作将从 API 检索到的数据传递到商店
像这样:
component.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);
);
不确定这是否是正确/最佳的解决方案。
【讨论】:
【参考方案2】:我找到了你的帖子,因为我有同样的问题。我想我会像这样构建我的结构,保持一切解耦并通过行动进行交流。我喜欢保持组件和存储对 API 的无知。
产品操作知道如何与 API 交互以完成请求的操作。 Product Store 侦听 Completed 操作以更新其内部状态。 LoadingAction 管理微调器状态,并在启动 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();
【讨论】:
以上是关于如何保留本地组件数据,例如微调器/错误,在 Flux 商店之外?的主要内容,如果未能解决你的问题,请参考以下文章