Redux - 跨实体状态管理

时间:2016-07-30 10:29:27

标签: redux state react-redux immutable.js reselect

我正在使用Redux和ImmutableJS来管理我的应用程序的状态。我创建了以下两个记录:

export const OrderRecord = Record({
    id: null,
    productId: null,
    amount: 1,
});

export const ProductRecord = Record({
    id: null,
    name: '',
    price: 0,
});

我的全局状态根据这样的normalizr方法进行了标准化:

const state = {
    entities: {
        orders: new OrderedMap(new Map({
            1: new OrderRecord(createOrderItem(1, 1)),
        })),
        products: new OrderedMap(new Map({
            1: new ProductRecord(createProductItem(1)),
        })),
    },
};
  • 我正在使用此规范进行测试。

现在我正在尝试使用Reselect对计算字段进行一些选择。

export const getVisibleOrders = createSelector(
    [getProducts, getOrders],
    (products, orders) => {
        orders.map(order => {
            const product = products.get(order.productId.toString());
            if (!product) {
                return order;
            }
            const totalPrice = order.amount * product.price;
            order.set('productName', product.name);
            order.set('totalPrice', totalPrice);
            return order;
        });
    }
); 

,但是我收到以下错误消息:

  

错误:无法在记录

上设置未知密钥“productName”

我知道原因 - 记录不能包含任何未定义的键,但我的问题是:有没有任何建议的方法如何优雅地解决这个问题?

  • 我不想扩展我的记录以支持这种计算参数(product.name和totalPrice)。
  • 我不想将静态和计算参数保存在一个地方,因为例如'productName'参数来自“Product”实体而不是来自“Order”实体。

谢谢。

1 个答案:

答案 0 :(得分:1)

使用Immutable.Record的重点是不允许您为记录添加新密钥,因此会收到错误消息。而选择者的全部意义在于揭示这样的"计算"属性,如果你想在外面消费它们。在您的情况下,如果需要使用虚线语法,则只需返回新的Map()对象或新记录类型:

return Map({
  productName: 'foobar'
}).merge(order)