【问题标题】:React Redux : update an item in an array of objectsReact Redux:更新对象数组中的项目
【发布时间】:2020-09-23 08:27:58
【问题描述】:

我需要一些帮助。我尝试了很多方法来解决我的问题,但我就是不能,没有任何效果。 我想在单击单个“水果”时更改水果和蔬菜数组中的 buyQuantity,我从操作中获得了 id..它可以工作,但是当我在下面尝试这个减速器时,当我点击水果项目时,我的状态完全改变了。我只有一个水果数组我说,像这样:

state= [
        {id: 1, name:"apples", price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 2,name:"pears", price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 3,name:"bananas", price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 4,name:"oranges", price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 5,name:"plums", price: 2.50, avaibleProducts: 20, buyQuantity: 0},
      ],

我的代码是:

const initialState = {
loadingState: {},
productsCategories: [],
products: {
   fruits: [
        {id: 1, name:"apples", price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 2,name:"pears", price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 3,name:"bananas", price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 4,name:"oranges", price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 5,name:"plums", price: 2.50, avaibleProducts: 20, buyQuantity: 0},
      ],
vegetables: [
        {id: 1,name:"potatos",price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 2,name:"tomatos",price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 3,name:"onions",price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 4,name:"carrots",price: 2.50, avaibleProducts: 20, buyQuantity: 0},
        {id: 5,name:"pepper",price: 2.50, avaibleProducts: 20, buyQuantity: 0},
}
}

const productsCategoriesAndProducts = (state = initialState, action) => {



switch (action.type) {

case "ADD_PRODUCT":`enter code here`

  return state.products.fruits.map(fruit => {
    if (fruit.id === action.id) {
      return { ...fruit, buyQuantity: fruit.quantity + 1 }

    };

    return fruit;

  });

default:
  return state;
  }
}
export default productsCategoriesAndProducts;

请帮忙。 感谢您的帮助。

【问题讨论】:

  • 我建议尝试使用immer,它大大简化了reducer代码:immerjs.github.io/immer/docs/introduction
  • 好吧,理论上,你不应该改变你的状态。在 Redux 中,您需要保持不变性。其次,如果 id 匹配,则返回 ``` ...fruit 当您应该返回已更改为所需更新的整个状态时返回 true。如果可能的话,我建议跳过“产品”级别,直接进入水果/蔬菜。在您的情况下,您可以执行以下操作: ``` 在您的情况下: const fruits = [...state.products.fruits] // 映射水果并做您的更改 return { ...state, products: { 。 ..state.products, 水果 } } ```

标签: reactjs redux react-redux


【解决方案1】:

您应该在要更新的每个级别复制整个状态对象。

case "ADD_PRODUCT":`enter code here`

  return {
    ...state,
    products: {
      ...state.products,
      fruits: state.products.fruits.map(fruit => {
        if (fruit.id === action.id) {
          return { ...fruit, buyQuantity: fruit.quantity + 1 }
        };
        return fruit;
      })
    },
  };

【讨论】:

    【解决方案2】:

    Sandbox

    尝试扁平化您的数据模型。这里没有必要将蔬菜和水果分开。如果您只需要水果,请使用filter。通过使用复合 id(category_product,例如fruit_apple),还可以非常高效地选择单个产品。

    这更像是个人偏好而不是严格的规则,但请尝试将逻辑函数从减速器函数中分离出来。在这个例子中,我将 incBuyQuantity 从减速器中分离出来:

    // Flattened Data Model
    const initState = {
      loadingState: {},
      productsCategories: [],
      products: [
        {
          id: "fruit_apples",
          name: "apples",
          price: 2.5,
          avaibleProducts: 20,
          buyQuantity: 0,
          category: "fruit"
        },
        {
          id: "fruit_pears",
          name: "pears",
          price: 2.5,
          avaibleProducts: 20,
          buyQuantity: 0,
          category: "fruit"
        },
        {
          id: "vegetable_potatos",
          name: "potatos",
          price: 2.5,
          avaibleProducts: 20,
          buyQuantity: 0,
          category: "vegetable"
        },
        {
          id: "vegetable_tomatos",
          name: "tomatos",
          price: 2.5,
          avaibleProducts: 20,
          buyQuantity: 0,
          category: "vegetable"
        }
      ]
    };
    
    // Logic
    function incBuyQuantity(state, action) {
      return {
        ...state,
        products: state.products.map((product) =>
          action.id === product.id
            ? { ...product, buyQuantity: product.buyQuantity + 1 }
            : product
        )
      };
    }
    
    // Reducer
    function reducer(state = initState, action) {
      switch (action.type) {
        case "INC_PRODUCT":
          return incBuyQuantity(state, action);
        default:
          return state;
      }
    };
    
    // Example
    const action = { type: "INC_PRODUCT", id: "fruit_apples" };
    const nextState = reducer(initState, action)
    console.log(nextState.products[0].buyQuantity); // => 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-10
      • 1970-01-01
      • 2019-09-08
      • 1970-01-01
      • 2020-10-05
      • 2019-01-27
      相关资源
      最近更新 更多