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

标签 javascript reactjs next.js immutability-helper

我在更新处于 react 状态的数组中的嵌套对象时遇到问题。

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

这是我想要发生的事情:

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

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

  3. 如果我返回到我已经添加的上一个项目,并想再次添加它,那么我想找到该项目的状态,将其与当前对象进行比较正在传递的那个,并将数量更新为 1。 (这行不通)

我决定实现 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", productParams: {…}, quantity: 3, productPrice: 3000}
2: {productName: "Item 1", productParams: {…}, quantity: 3, productPrice: 60}
length: 3
__proto__: Array(0)
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) {
            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);
                } else {
                    setCart([ ...cart, obj ]);
                }
            });
        } else {
            setCart([ ...cart, obj ]);
        }
    };

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

最佳答案

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

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>;

}

您的代码所做的是这样的,如果购物车数组中的当前项目 (e) 与 obj 不匹配,它会将该 obj 添加到数组中。只有在迭代数组并确认数组中不存在与 obj 相同的数据后,才应执行此操作。

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

关于javascript - 在 ReactJs 中更新数组中的嵌套对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58873441/

相关文章:

Javascript:获取 SharePoint Web 部件 - 要在页面上显示的对象

javascript - 想要使用 react cra 使动态页面可索引

javascript - 类型错误 : Cannot read property 'categories' of null

reactjs - 通过高阶组件注入(inject) props 会导致编译器错误

javascript - react router redux 不会在 props 更改时呈现

reactjs - 配置多个下一个插件 : withMDX, withBundleAnalyzer

c# - Ajax AutoCompleteExtender - 为什么此代码不起作用?

javascript - 使用javascript选中复选框时播放音频

javascript - 使用 Jquery 从纯 HTML 中删除 &lt;style&gt; 标签和 &lt;script&gt; 标签

javascript - 按类别名称过滤数组