Redux在状态之间共享数据的最佳实践

时间:2016-01-21 19:20:27

标签: redux

我正在使用redux开发webapp,我正在尝试找出在两个子状态之间共享数据的最佳方法。

假设我有一个类似的数据结构,对于一个用户可以从意大利餐厅订购食物的应用程序:

{
    "entrees": [{ "type": "pizza", "sauce": "alfredo", "topping": "meat" }],
    "options": {
        "entreeTypes": ["pizza", "calzone"],
        "sauceTypes": {
            "pizza": ["marinara", "white"],
            "calzone": ["marinara", "alfredo"]
        },
        "toppingTypes": {
            "marinara": ["meat", "veggies", "cheese"],
            "white": ["meat", "veggies"],
            "alfredo": ["meat"] 
        }
    }
}

因此,如果用户想要在其订单中添加主菜,则新主菜应填充类型,酱料和浇头的所有默认选项,这里将是“披萨”,“marinara”和“肉”。

理想情况下,我希望在主菜减速器中添加一个主菜。但是,主菜 reducer需要访问 options 状态的各个部分才能实现其目标。

我目前的实现看起来像这样(使用 redux-thunk ):

function addEntree(){

    return (dispatch, getState) => {

        const options = getState().options;
        const type = options.entreeTypes[0];
        const sauce = options.sauceTypes[type][0];
        const topping = options.toppingTypes[sauce][0];
        const action = { type: 'ADD_ENTREE', type, sauce, topping };
        dispatch(action);

    };
}

主动减速器会采取行动。

所以我的问题是,这看起来好吗?是否有其他人使用他们认为优越的模式?

1 个答案:

答案 0 :(得分:0)

这个例子很奇怪,因为通常选项不是应用程序状态的一部分。而且,似乎你想要一个选择层次,你不能用你的alfredo蔬菜。所以有两件事:

  1. 如果选项可以是应用程序状态之外的常量,因为它们是动态的,请执行此操作。因此,基本上将您当前的options缩减器存储为某个const,您只需将其导入即可。

  2. 如果成分列表和组合是动态的,我认为您不应该在行动中强制执行成分组合限制。例如,如果您有订单页面,请加载道具中的所有选项。 Voilá,您可以同时使用多个减速器。在用户选择了“比萨饼”而不是酱汁或浇头的情况下,您可以选择props.options.sauceTypes[selectedEntree]中的第一个酱汁,然后选择props.options.toppingTypes[selectedSauce]

    class OrderPage extends React.Component {
      ...
      function onSelectEntree (entree) {
        const { options: { sauceTypes, toppingTypes }, addEntree } = this.props;
        const sauce = sauceTypes[entree][0];
        const topping = toppingTypes[sauce][0];
    
        addEntree(entree, sauce, topping):
        // Or if you don't want to persist it globally yet:
        // this.setState({ entree, sauce, topping });
      }
      ...
    }
    

    然后在视图中,仅显示给定用户当前选择所允许的选项(即,如果他们选择了alfredo,则隐藏蔬菜)。在组件中进行验证。