【问题标题】:How to manage (async) cascading data in Redux?如何在 Redux 中管理(异步)级联数据?
【发布时间】:2015-11-27 00:46:10
【问题描述】:

想象一下汽车配置应用。这是一个示例状态树:

{
  // selections
  modelYear,
  modelId,
  transmissionId,

  // options
  modelYears: [],
  models: [],
  transmissions: [],
  accessories: []
}

应用启动时会加载一些初始数据。然后,您将首先选择车型年份以填充车型列表,然后选择车型,然后选择变速箱、配件等。每条数据都以分层方式依赖于先前的选择。页面加载的示例事件序列如下:

  1. 检索所有年份并填充下拉列表。
  2. 默认选择第一年
  3. 根据所选年份检索模型
  4. 默认选择第一个模型
  5. 根据所选模型检索传输
  6. 默认选择传输方式
  7. 根据所选型号检索附件 等等……

当用户更改任何数据的选择时,必须检索层次结构中较低的新数据,并且必须重新填充 UI。

这里是我写的一些sn-ps:

行动

export function getModelYears() {
  return dispatch => {
    vehiclesApi.getModelYears(years => {
      dispatch(receiveModelYears(years))
    })
  }
}

export function getModels(year) {
  return dispatch => {
    vehiclesApi.getModels(year, models => {
      dispatch(receiveModels(models))
    })
  }
}

function receiveModelYears(years) {
  return {
    type: types.RECEIVE_MODEL_YEARS,
    years: years
  }
}

function receiveModels(models) {
  return {
    type: types.RECEIVE_MODELS,
    models: models
  }
}

export function selectModelYear(year) {
  return {
    type: types.SELECT_MODEL_YEAR,
    year
  }
}

减速器

function vehicle(state = {}, action) {
  switch (action.type) {
    case SELECT_MODEL_YEAR:
      return Object.assign({}, state, {
        modelYear: action.year
      })
    case SELECT_MODEL:
      return Object.assign({}, state, {
        modelId: action.modelId
      })
    default:
      return state
  }
}  

function modelYears(state = [], action) {
  switch (action.type) {
    case RECEIVE_MODEL_YEARS:
      return state.concat(action.years)
    default:
      return state
  }
}

function models(state = [], action) {
  switch (action.type) {
    case RECEIVE_MODELS:
      return state.concat(action.models)
    default:
      return state
  }
}

我不确定如何构建我的减速器和操作来处理默认选择并在做出选择后请求新数据。手动操作很简单(用户点击、调度操作)。但是默认选择第一年之后如何手动调度getModels(year)呢?

这是我用伪代码描述流程的最佳方式:

store.dispatch(getModelYears())

store.subscribe(() => {
  // if model years received
  store.dispatch(selectModelYear(store.getState().modelYears[0]))

  // if modelYear selected
  store.dispatch(getModels(store.getState().modelYear))

  // if models received
  store.dispatch(selectModel(store.getState().models[0].id))

  // if model selected
  store.dispatch(getTransmissions(store.getState().modelId))
  store.dispatch(getAccessories(store.getState().modelId))

  // ...etc
})

我想测试这个与任何 UI 框架无关的系统,因为我将其构建为用于管理我的客户端状态的概念证明,并且可能无法使用 React。

【问题讨论】:

    标签: javascript redux


    【解决方案1】:

    如果我正确理解了您的要求,那么您正在寻找一种通过触发另一个操作来响应状态更改的方法。例如,每当store.modelYear 发生变化时,您都需要触发RECEIVE_MODELS 操作。

    subscribe 方法看起来很适合这项工作。如果您想要更结构化的设计,可以在 subscribe 之上构建模式,例如演员:http://jamesknelson.com/join-the-dark-side-of-the-flux-responding-to-actions-with-actors/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-10
      • 2017-06-23
      • 1970-01-01
      • 2018-09-29
      • 2016-08-10
      • 1970-01-01
      • 2021-03-14
      • 2018-10-31
      相关资源
      最近更新 更多