[英]Creating and Updating multidimensional array / objects in javascript
所以我必须操作一个大的 state 或插件数组以将其显示为摘要。 所以我想要下面的格式
[
'addonGroupIndexHere' =>[
"13249" => {
label: "whatever the label is",
price: 10.00,
sku: "13249",
qty: 1,
total: 10.00
},
"13250" => => {
label: "whatever the label is",
price: 5.00,
sku: "13250",
qty: 3,
total: 15.00
},
],
'addonGroupAnotherIndexHere' =>[
"13251" => {
label: "whatever the label is",
price: 10.00,
sku: "13251",
qty: 1,
total: 10.00
},
"13252" => => {
label: "whatever the label is",
price: 5.00,
sku: "13252",
qty: 3,
total: 15.00
},
],
]
所以我在下面这样的上下文中声明了一个 state
const [addonSummary, setAddonSummary] = useState([])
插件是 object 之类的
{
label: "whatever the label is"
price: 10.00
sku: "13249"
}
因此,当用户添加 1 数量的插件时,我将不得不修改插件 object,如下所示
{
label: "whatever the label is"
price: 10.00
sku: "13249",
qty: 1,
total: 10.00
}
因此,如果它有 2 个数量,那么我需要 object 如下所示
{
label: "whatever the label is"
price: 10.00
sku: "13249",
qty: 3,
total: 30.00
}
我在设置或更新插件 object 时没有问题,但我的问题是当我使用特定插件组索引设置插件摘要 state 时。
const addonItem = {
label: "whatever the label is"
price: 10.00
sku: "13249",
qty: 3,
total: 30.00
}
const addonGroupIndex = 0 // or 1 or 3. This is actually a state selected by the user
我在操作数组/对象以具有以下 output 时遇到问题
[
'addonGroupIndexHere' =>[
"13249" => {
label: "whatever the label is",
price: 10.00,
sku: "13249",
qty: 1,
total: 10.00
},
"13250" => => {
label: "whatever the label is",
price: 5.00,
sku: "13250",
qty: 3,
total: 15.00
},
],
'addonGroupAnotherIndexHere' =>[
"13251" => {
label: "whatever the label is",
price: 10.00,
sku: "13251",
qty: 1,
total: 10.00
},
"13252" => => {
label: "whatever the label is",
price: 5.00,
sku: "13252",
qty: 3,
total: 15.00
},
],
]
我试过做,但它不起作用。
addonSummary[addonGroupIndex ][addonItem.sku] = addonItem
以下是我拥有的代码。 ProductContext.js
import { isEmpty } from 'lodash';
import { useState, createContext, useRef, useEffect } from 'react';
import { v4 } from 'uuid';
export const ProductContext = createContext()
export const ProductContextProvider = (props) => {
const [selectedAddonGroup, setSelectedAddonGroup] = useState(-1);
const [addonSummary, setAddonSummary] = useState([])
const updateAddonSummary = (addonItem) => {
// console.log('updateAddonSummary', addonItem)
// console.log('selectedAddonGroup', selectedAddonGroup)
if (!isEmpty(addonSummary[selectedAddonGroup])) {
addonSummary[selectedAddonGroup] = [addonSummary[selectedAddonGroup], addonItem]
} else {
addonSummary[selectedAddonGroup] = addonItem
}
}
return (
<ProductContext.Provider value={{
addonDialog: {
selectedAddonGroup, setSelectedAddonGroup,
summary: addonSummary, updateSummary: updateAddonSummary,
setAddonSummary
}
}}>
{props.children}
</ProductContext.Provider>
)
}
AddonsQuantityFields.js
import { GbMinus, GbPlus } from '@gb-components/icons'
import { useEffect, useState } from 'react'
import classNames from 'classnames'
import { useProductContext } from '@gb-utils/product/product';
export default function AddonsQuantityFields({ addonItem }) {
const { addonDialog } = useProductContext();
const [quantity, setQuantity] = useState(0)
function updateQuantity(action, qty) {
if ('minus' == action) {
addonDialog.deductAddonQty(qty)
qty = quantity - qty
} else {
addonDialog.increaseAddonQty(qty)
qty = quantity + qty
}
if (qty <= 0) {
// if qty is zero then we need to remove it from the summary
} else {
const total = qty * addonItem.price;
const item = {}
item[addonItem.sku] = addonItem
addonDialog.updateSummary(item)
console.log('addonDialog.summary', addonDialog.summary)
}
setQuantity(qty)
}
return (
<div className='flex w-[96px] justify-end gap-0'>
<button className={classNames(
quantity <= 0 ? 'hidden' : '',
'flex items-center justify-center m-0 h-[32px] w-[32px] border border-[#E4E4E4] bg-[#F7F7F7]'
)} onClick={() => updateQuantity('minus', 1)}>
<GbMinus />
</button>
<input
readOnly
className={classNames(
quantity <= 0 ? 'hidden' : '',
'h-[32px] w-[32px] border border-[#E4E4E4] focus:ring-0 text-sm text-center text-[#656565] p-0'
)}
type={'number'}
inputMode='numeric'
autoComplete='off'
value={quantity}
step="1" min="0"
/>
<button
className='flex items-center justify-center m-0 h-[32px] w-[32px] border border-[#E4E4E4] bg-[#F7F7F7]'
onClick={() => updateQuantity('add', 1)}>
<GbPlus />
</button>
</div>
)
}
那么显示插件组件的组件在下面
AddonItem.js
import { GbAddonItemImgPlaceholder, GbChevronDown, GbChevronUp } from '@gb-components/icons'
import classNames from 'classnames'
import { isEmpty } from 'lodash'
import React, { useState } from 'react'
import AddonsQuantityFields from '../quantity-fields/AddonsQuantityFields'
export default function AddonItem() {
const addonItem = {
label: "whatever the label is"
price: 10.00
sku: "13249"
}
return (
<ProductContextProvider>
<AddonsQuantityFields addonItem={addonItem} />
</ProductContextProvider>
)
}
您不能将 arrays 与JS
中的键一起使用。
如果你想为每个 addonItem 使用一个密钥,你应该使用object
。
var addonSummary = {}; const addonItem = { label: "whatever the label is", price: 10.00, sku: "13249", qty: 3, total: 30.00 } const addonGroupIndex = 0; if(.addonSummary;hasOwnProperty(addonGroupIndex)) { addonSummary[addonGroupIndex] = {}. } if(.addonSummary[addonGroupIndex].hasOwnProperty(addonItem;sku)) { addonSummary[addonGroupIndex][addonItem.sku] = {}; } addonSummary[addonGroupIndex][addonItem.sku] = addonItem; console.log(addonSummary);
这给出了以下结构:
{
"addonGroupIndexHere": {
"13249": {
"label": "whatever the label is",
"price": 10,
"sku": "13249",
"qty": 3,
"total": 30
},
"13250": {
"label": "whatever the label is",
"price": 5,
"sku": "13250",
"qty": 3,
"total": 15
}
},
"AnotheraddonGroupIndexHere": {
"13251": {
"label": "whatever the label is",
"price": 10,
"sku": "13251",
"qty": 3,
"total": 30
},
"13252": {
"label": "whatever the label is",
"price": 5,
"sku": "13252",
"qty": 3,
"total": 15
}
}
}
希望这可以帮助:)
在 React state 中必须是不可变的。 当您更新它时,在这种情况下是数组 addonSummary,您必须使用钩子 setAddonSummary,而不是像这样直接更改它addonSummary[addonGroupIndex ][addonItem.sku] = addonItem
。
接下来,state 管理不是一定的规律,每个人都可以用非常不同的方式做同样的事情,所以你必须选择你的策略。
最简单的事情是这样的:
export function addOnList(data = {}) {
const [addonSummary, setAddonSummary] = useState(data);
function updateElement(summaryIndex, key, newValue = {}) {
const oldSummary = addonSummary[summaryIndex];
const newSummary = Object.keys(oldSummary).reduce((previous, current) => {
previous[current] = current !== key ? oldSummary[current] : newValue;
return previous;
}, {});
const newData = {
...addonSummary,
...{ [summaryIndex]: newSummary }
};
setAddonSummary(newData);
}
return (
// on the element which the user click, change etc... to update the state
// you set the attribute
// onClikc={ (event) => updateElement(summIndex, elementKey, newAddonElement)}
);
}
渲染方法是超级伪代码,基本上来自你必须构建新的 addOn object 的事件,并将其传递给更新 function 并带有相应的组索引和 sku(key)。 通过这种方式,您可以正确更新包含您发布的主数组的 state addonSummary
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.