【问题标题】:Push into an Array inside an Object in redux?在redux中推入对象内的数组?
【发布时间】:2021-07-09 12:28:14
【问题描述】:

我有一个包含一些列表对象的化简器。

const list = [
  {
    name: 'A',
    products: { items: [] },
  },
  {
    name: 'B',
    products: { items: [{ qty: 1 }] },
  },
]

我想向产品密钥添加新项目。 减速器

export const addProductToSubscription = (state, { name, products }) => ({
  ...state,
  list: state.list.map((v) =>
    name === v.subscriptionName ? [...v.products, { ...v.products, items: products }] : v
  ),
})

这样发送,

dispatch("A",[{qty:2}])

预期输出

const list = [
  {
    name: 'A',
    products: { items: [{ qty: 2 }] },
  },
  {
    name: 'B',
    products: { items: [{ qty: 1 }] },
  },
]

什么 reducer 没有更新状态。

谢谢!!

【问题讨论】:

  • state 是否有list 键或liststate
  • arr.map 不会改变数组,它会返回一个新数组。这可能会改变您在第二个代码块中尝试执行的操作。
  • 是状态有列表键
  • 为什么不更新状态

标签: javascript reactjs react-native redux


【解决方案1】:

我重新创建了你的环境,结果就像-

const state = {
    list: [
        {
            name: "A",
            products: { items: [] },
        },
        {
            name: "B",
            products: { items: [{ qty: 1 }] },
        },
    ],
};

const updateState = (state, { name, products }) => {
    return {
        ...state,
        list: state.list.map(v => {
          return {
            ...v,
            products: {
              ...v.products,
              items: [
                ...v.products.items,
                ...products
              ]
            }
          }
        }),
    };
};

const res = updateState(state, { name: "A", products: [{ qty: 2 }, {qty: 4}] });

console.log(JSON.stringify(res));
.as-console-wrapper{min-height: 100%!important; top: 0}

【讨论】:

    【解决方案2】:

    Object.assign 和扩展运算符(...) - immutability-helper 更先进的解决方案

    const update = require('immutability-helper');
    const assert = require('assert');
    
    const list = [
      {
        name: 'A',
        products: { items: [] },
      },
      {
        name: 'B',
        products: { items: [{ qty: 1 }] },
      },
    ];
    
    function addProductToSubscription(state = list, { name, products }) {
      return update(state, {
        $apply: (self) => {
          return self.map((v) => {
            if (v.name === name) {
              return update(v, { products: { items: { $push: products } } });
            }
            return v;
          });
        },
      });
    }
    
    const actual = addProductToSubscription(undefined, { name: 'A', products: [{ qty: 2 }] });
    
    console.log(JSON.stringify(actual, null, 2));
    
    assert(actual !== list, 'new copy');
    assert(actual[0] !== list[0], 'new copy for A object');
    assert(actual[0].products !== list[0].products, 'new copy for A object products');
    assert(actual[0].products.items !== list[0].products.items, 'new copy for A object products items');
    

    输出:

    [
      {
        "name": "A",
        "products": {
          "items": [
            {
              "qty": 2
            }
          ]
        }
      },
      {
        "name": "B",
        "products": {
          "items": [
            {
              "qty": 1
            }
          ]
        }
      }
    ]
    

    【讨论】:

      【解决方案3】:

      使用扩展运算符获取新副本并更新到状态

      export const addProductToSubscription = (state, { name, products }) => ({
        ...state,
        list: state.list.map((v) =>
          v.name === name
            ? {
                ...v,
                products: { items: [...v.products.items, ...products] },
              }
            : v
        ),
      });
      

      【讨论】:

        猜你喜欢
        • 2014-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-14
        • 1970-01-01
        • 2023-03-29
        • 2014-11-12
        • 2016-05-09
        相关资源
        最近更新 更多