在ReactJs中更新数组中的嵌套对象

我无法在React状态下更新数组中的嵌套对象。

我正在尝试根据某个项目的名称来比较该项目是否已经存在于状态中。

这就是我想要发生的事情:

  1. 将项目添加到购物车。如果产品名称相同,则将数量增加一。 (有效)

  2. 如果名称不同,则将该新项添加到状态中。 (这也可以)

  3. 如果我返回已经已经添加的上一个项目,并且想要再次添加它,那么我想找到该项目处于状态,将其与当前对象进行比较传入,并将数量更新一。 (这不起作用)

我决定实施immutability-helper来简化更新状态。

我应该注意,我正在使用NextJs,并且仅在我重新加载新的动态页面之后才会出现此问题。

希望这是足够的信息...如果需要更多信息以帮助您,请告诉我。

谢谢!

更新2:这是我遇到的另一个问题……也许答案很明显,但是我认为我只是把它放在那里,以便引起人们的关注。 (如果这是一个新问题,请告诉我)。

每个项目都有一些可选参数。参数是数组内部的嵌套对象。我的解决方案是使用以下代码比较数据。

import React,{ createContext,useState,useEffect } from 'react';
import update from 'immutability-helper';
export const CartContext = createContext();

export function CartProvider(props) {
    const [ cart,setCart ] = useState([]);

//**********Start of the code to check the parameters of each item********

    const checkArr = (obj1,obj2) => {
        let newArr = [];
        function onlyInFirst(first,second) {
            for (let i = 0; i < first.length; i++) {
                if (second.indexOf(first[i]) === -1) {
                    newArr.push(first[i]);
                }
            }

        }

        onlyInFirst(obj1,obj2);
        onlyInFirst(obj2,obj1);

        if (newArr.length === 0) {
            return false;
        } else {
            return true;
        }
    };

//*******End of the code to check the parameters of each item**********

    const addItem = (obj) => {
        let dataCheck = true;
        if (cart.length != 0) {
            cart.map((e,i) => {
                if (e.productName === obj.productName) {
                    const prevVal = Object.values(e.productParams);
                    const currentVal = Object.values(obj.productParams);
                    dataCheck = checkArr(prevVal,currentVal);
                }
                if (dataCheck === false) {
                    const object = e;
                    const cartCopy = cart;
                    const newObj = update(object,{ quantity: { $set: object.quantity + 1 } });
                    const newState = update(cartCopy,{ [i]: { $set: newObj } });
                    setCart(newState);
                }
            });
        } else {
            setCart([ ...cart,obj ]);
        }
        if (dataCheck === true) {
            setCart([ ...cart,obj ]);
        }
    };

    return <CartContext.Provider value={{ cart,addItem }}>{props.children}</CartContext.Provider>;
}

但是,无论我将什么参数添加到productParams中,我仍将获得如下所示的示例输出。

有人在这里发现我的逻辑有问题吗?我不知所措...

更新1:我正在添加对象结构和示例输出。

对象结构:

const obj = {
    productName: product.name,// product.name comes from api
    productParams: {},// this is dynamically added elsewhere
    quantity: 1,productPrice: price 
}

Chrome开发工具的示例输出:

3) [{…},{…},{…}]
0: {productName: "Item 1",productParams: {…},quantity: 4,productPrice: 60}
1: {productName: "Item 2",quantity: 3,productPrice: 3000}
2: {productName: "Item 1",productPrice: 60}
length: 3
__proto__: Array(0)
import React,setCart ] = useState([]);

    const addItem = (obj) => {
        if (cart.length != 0) {
            cart.map((e,i) => {
                if (e.productName === obj.productName) {
                    const object = e;
                    const cartCopy = cart;
                    const newObj = update(object,{ [i]: { $set: newObj } });
                    setCart(newState);
                } else {
                    setCart([ ...cart,obj ]);
                }
            });
        } else {
            setCart([ ...cart,addItem }}>{props.children}</CartContext.Provider>;
}

cfclx 回答:在ReactJs中更新数组中的嵌套对象

您的代码中有一个小错误。当数组中没有匹配的对象时,应在地图函数外部而不是内部更新购物车。

import React,{ createContext,useState,useEffect } from 'react';
import update from 'immutability-helper';
export const CartContext = createContext();

export function CartProvider(props) {
    const [ cart,setCart ] = useState([]);

const addItem = (obj) => {
    if (cart.length != 0) {
        let dataExist = false;
        cart.map((e,i) => {
            if (e.productName === obj.productName) {
                const object = e;
                const cartCopy = cart;
                const newObj = update(object,{ quantity: { $set: object.quantity + 1 } });
                const newState = update(cartCopy,{ [i]: { $set: newObj } });
                setCart(newState);
                dataExist=true
            }
        });
        if(dataExist) {
            setCart([ ...cart,obj ]);
        }
    } else {
        setCart([ ...cart,obj ]);
    }
};

return <CartContext.Provider value={{ cart,addItem }}>{props.children}   </CartContext.Provider>;

}

您的代码正在执行的操作是,如果购物车数组中的当前项目与obj不匹配,则它将该obj添加到数组中。只有在迭代数组并确认数组中没有与obj相同的数据之后,才应执行此操作。

如果该更新不能解决您的问题,我可能需要您提供一些示例数据(即对象结构,示例输出等)来正确测试。

,

请用此代码更新您的代码,如果您可以共享obj数据和购物车数据会更好:

const addItem = (obj) => {
    if (cart.length !== 0) {
      for (let i = 0; i <= cart.length; i += 1) {
        if (undefined !== cart[i]) {
          if (obj.productName === cart[i].productName) {
            const tempArr = [...cart];
            tempArr.quantity += 1;
            setCart(tempArr);
          } else {
            setCart([...cart,obj]);
          }
        }
      }
    } else {
      setCart([...cart,obj]);
    }
  };

,

我解决了! InsomniacSabbir的想法正确。我只需要稍微修改一下代码即可获得想要的结果。

这是解决方案

import React,setCart ] = useState([]);

    const addItem = (obj) => {
        let dataCheck = true;
        if (cart.length != 0) {
            cart.map((e,i) => {
                if (e.productName === obj.productName) {
                    const object = e;
                    const cartCopy = cart;
                    const newObj = update(object,{ quantity: { $set: object.quantity + 1 } });
                    const newState = update(cartCopy,{ [i]: { $set: newObj } });
                    setCart(newState);
                    dataCheck = false;
                }
            });
        } else {
            setCart([ ...cart,obj ]);
        }
        if (dataCheck === true) {
            setCart([ ...cart,obj ]);
        }
    };

    return <CartContext.Provider value={{ cart,addItem }}>{props.children}</CartContext.Provider>;
}

我在map中有一个if / else语句,这导致了问题。我从地图中取出了else语句,并在函数中添加了另一个if语句,该函数检查 dataCheck 是/否。仅在执行map中的if语句时, dataCheck 才会设置为false。

希望这个答案有帮助!

感谢大家的帮助!

本文链接:https://www.f2er.com/3096798.html

大家都在问