如何避免商店更新中的操作

时间:2017-02-27 10:39:27

标签: redux

就我的理解而言,从商店更新处理程序中调度操作是一种反模式。正确的吗?

如何处理以下工作流程呢?

  • 我的页面标题上有一些公司切换器
  • 点击公司会发送一些SELECTEDCOMPANY_UPDATE操作
  • 活动视图通过强制重新加载数据来响应状态存储中的相应更改。例如。致电companyDataService.fetchOrders(companyName)
  • 我想在提取数据期间显示一些加载动画,因此有FETCHINGDATA_UPDATE之类的专用操作可更新我的应用状态存储中的fetchingData部分,所有感兴趣的视图都可以通过显示/隐藏负载掩码做出反应

我在哪里实际发送FETCHINGDATA_UPDATE行动?如果我在companyDataService.fetchOrders(companyName)内直接执行此操作,则会在商店更新处理程序中调用它(请参阅下面示例代码中的OrdersView.onStoreUpdate)...

修改

为了澄清我的最后一句话,我正在添加一些示例代码,以显示我的实现将如何:

ActionCreator.js

// ...
export function setSelectedCompany(company) {
  return { type: SELECTEDCOMPANY_UPDATE, company: company };
}

export function setFetchingData(isFetching) {
  return { type: FETCHINGDATA_UPDATE, isFetching: isFetching };
}
// ...

CompanyDataService.js

// ...
export fetchOrders(companyName) {
  this.stateStore.dispatch(actionCreator.setFetchingData(true));
  fetchData(companyName)
    .then((data) => {
      this.stateStore.dispatch(actionCreator.setFetchingData(false));
      // Apply the data...
    })
    .catch((err) => {
      this.stateStore.dispatch(actionCreator.setFetchingData(false));
      this.stateStore.dispatch(actionCreator.setFetchError(err));
    })
}
// ...

CompanySwitcher.js

// ...
onCompanyClicked(company) {
  this.stateStore.dispatch(actionCreator.setSelectedCompany(company));
}
// ...

OrdersView.js

// ...
constructor() {
  this._curCompany = '';
  this.stateStore.subscribe(this.onStoreUpdate);
}
// ...
onStoreUpdate() {
  const stateCompany = this.stateStore.getState().company;
  if (this._curCompany !== stateCompany) {
    // We're inside a store update handler and `fetchOrders` dispatches another state change which is considered bad...
    companyDataService.fetchOrders(stateCompany);
    this._curCompany = stateComapny;
  }
}
// ...

1 个答案:

答案 0 :(得分:1)

我同意Davin,在动作创建者中可以做到这一点,例如:

export function fetchOrders (company) {
  return (dispatch) => {
    dispatch ({ type: FETCHINGDATA_UPDATE });
    return fetchOrderFunction ().then(
      (result) => dispatch ({ type: FETCHING_COMPLETED, result }),
      (error) => dispatch ({ type: FETCHING_FAILED, error })
    );
  };
}

然后在reducer中,FETCHINGDATA_UPDATE可以将你的加载指示器设置为true,你可以将它设置为false我是SUCCESS还是FAILED