如何更改状态而不必通过API重新加载整个json对象

时间:2018-08-07 04:17:44

标签: reactjs redux redux-thunk

我正在使用带有redux的reactjs,并在UI上显示类别以及与之相关的产品。

当用户将产品移动到另一个类别时,由于JSON确实很大,我不想像现在那样重新加载整个JSON文件。

如何通过仅从一个类别的catProducts集合中删除productId并将productId添加到另一类别catProducts集合中来对该JSON文件进行变异。

{
  "shop" : {

    "categories": [
      {
        id: 1,
        name: "category1",
        "catProducts" : [
          {
            productId: 123
          }          
        ]
      },
      {
        id: 2,
        name: "category2",
        "catProducts" : [
          {
            productId: 456
          }          
        ]
      },
      {
        id: 3,
        name: "category3",
        "catProducts" : [
          {
            productId: 789
          }          
        ]
      }
    ]

  }

}

下面是我的动作和减速器,您可以看到每次移动产品时,我都会在整个类别中重新加载产品。 我要做的就是在调用API之后,通过从一个catProducts中删除productId并将其添加到另一个catProducts中来改变我的状态。我该怎么做?

动作:

moveProduct: (data) => {
  return dispatch => {
  var url = '....'; // api to move the product in db
  axios.post(url, reqArgs)
    .then(function(resp) {
      dispatch(Actions.fetchCategoriesAndProducts(data.shopId));
    });
  };
},

减速器:

case Constants.FETCH_CATEGORIES_AND_PRODUCTS:
  return {...state, fetching: false, shop: action.data };

1 个答案:

答案 0 :(得分:1)

假设您有一个索引fromIndex表示将产品从其中移出的categories数组索引,toIndex代表了将产品移到其中的categories数组索引,并且productId的产品要移动,您可以这样做:

const data = {
  shop: {
    categories: [
      {
        id: 1,
        name: "category1",
        catProducts: [
          {
            productId: 123
          }
        ]
      },
      {
        id: 2,
        name: "category2",
        catProducts: [
          {
            productId: 456
          }
        ]
      },
      {
        id: 3,
        name: "category3",
        catProducts: [
          {
            productId: 789
          }
        ]
      }
    ]
  }
};

const fromCategoryIndex = 0;
const toCategoryIndex = 1;
const productId = 123;

const categories = [...data.shop.categories];

categories[fromCategoryIndex] = {
  ...categories[fromCategoryIndex],
  catProducts: categories[fromCategoryIndex].catProducts.filter(
    product => product.productId !== productId
  )
};

categories[toCategoryIndex] = {
  ...categories[toCategoryIndex],
  catProducts: [...categories[toCategoryIndex].catProducts, { productId }]
};

console.log(categories);