如何在类似Om的不可变应用状态中建模关系数据

时间:2015-02-17 03:07:07

标签: javascript reactjs immutability immutable.js

我试图决定是使用更传统的Flux实现还是使用类似Om的结构。我非常喜欢在javascript中使用带有游标的单个不可变app状态对象的想法,但我不确定如何为关系数据建模。我正在使用类似Morearty的内容。

我的问题是如何避免重复数据并处理从服务器发送的嵌套关系数据?假设我有REST端点,它为我提供库存,每个库存项目都有一个嵌套供应商。我也有供应商的端点。我想要一个处于我的应用状态的所有供应商的列表,但也在我的库存项目中引用这些供应商。当我对供应商进行更新时,我希望它能够更改引用该供应商的所有库存项目。

类似于Om的结构是否适用于此类应用,或者更传统的Flux风格的应用程序是否更好?

1 个答案:

答案 0 :(得分:2)

您可能希望将Redux之类的东西视为“通量”框架。它非常棒 - 我们在Docker上使用它。这就是为什么它很好以及它如何帮助你。

为什么要使用redux?

它使用单店模型。所有商店都将Redux中的状态保存在自己的密钥中。 Redux保存状态的一个示例是:

{
  vendors: [{...}, ...], // The "vendor" store updates this part of the state
  inventory: [...] // the "inventory" store updates this part of the state
}

Redux或redux提供程序是所有组件的父级。因此,所有组件都将状态视为道具。

单店模型如何改善事物?

  1. 响应Redux中的操作的每个“store”仅更新状态对象的一个​​部分。例如,“供应商”商店仅更新州的“供应商”密钥。每次动作发生时,单个商店都会获得当前状态。这使得商店完全是纯粹的。这非常适合测试,不可变数据,热重新加载,倒带等。

  2. 因为您的单个顶级Redux存储保存了所有状态,所以每个组件都可以将此状态作为props接收,并在此状态发生变化时自动重新呈现 - 即使是来自层次结构之外的不相关组件。

  3. 以下是单个商店的实例,您可以明白这个想法:

    import assign from 'object-assign';
    import consts, { metrics, loading, URLS } from 'consts';
    
    const actions = {
      // As you can see, each action within a store accepts the current "state" 
      // and can modify that state by returning new data.
      [metrics.FETCH_METRICS_PENDING]: (state, data) => {
        return assign({}, state, {status: loading.PENDING});
      },
    
      [metrics.FETCH_METRICS_SUCCESS]: (state, data) => {
        return assign({}, state, {status: loading.SUCCESS, metrics: data.payload});
      },
    
      [metrics.FETCH_METRICS_FAILURE]: (state, data) => {
        return assign({}, state, {status: loading.FAILURE});
      },
    
      [metrics.OBSERVE_METRICS_DATA]: (state, data) => {
        let metrics = state.metrics.slice().concat(data.payload);
        return assign({}, state, {metrics});
      }
    }
    
    // This is the single method that's exported and represents our store.
    // It accepts the current state as its primary argument, plus the action
    // data as a payload.
    //
    // This delegates to the methods above depending on `data.type`.
    export default function metricStore(state = {}, data) {
      if (typeof actions[data.type] === "function") {
        return actions[data.type](state, data);
      }
      return state;
    }
    

    这个模型关系数据怎么样?

    每次通过动作创建者请求数据时,它都可以分派多个动作,一起更新供应商和库存状态。这将在一个渲染中反映在您的应用中。