gpt4 book ai didi

javascript - 在 React.js 中推送唯一对象

转载 作者:行者123 更新时间:2023-11-29 17:44:43 24 4
gpt4 key购买 nike

我正在使用 React 构建一个有严重缺陷的电子商务应用程序,只是为了好玩,我试图弄清楚如何在某个对象被插入数组后设置状态。

我有一个 cart 数组,我将我从包含我所有产品的初始 items 数组中添加的项目推送到其中。

问题是我有产品库存。假设我的 chocolate 产品有 5 个库存,每次我推送 chocolate 对象时,它都会堆积并在购物车中添加相同的商品,如下所示:

enter image description here

我想将 chocolates 对象推送到购物车数组,但如果它已经存在,我不想呈现副本。相反,我想实现一些东西,其中添加了 chocolate 对象,但每次添加时它的数量都会相应地改变。它看起来像这样:

enter image description here

我怎样才能实现这样的目标?也许检查一下该对象是否已经添加到 cart 数组中,如果是,那么不是渲染副本,而是推送值并更新该项目的数量?

被困了几个小时,非常感谢一些提示。

class App extends Component {
state = {
cart: [],
items: [
{ id: uuid(), name: 'chocolate', price: 10, remaining: 5 },
{ id: uuid(), name: 'strawberry', price: 50, remaining: 10 },
{ id: uuid(), name: 'banana', price: 43, remaining: 20 }
],
total: 0,
addToCartMessage: false,
removeFromCartMessage: false,
searchTerm: ''
}

addItem = item => {
const { cart, items, total } = this.state

cart.push({ id: item.id, name: item.name, price: item.price })

const remaining = item.remaining--

const totalPrice = cart.reduce((a, b) => a + b.price, 0)

this.setState({
total: totalPrice,
cart,
addToCartMessage: true,
...items, remaining
})
}

removeItem = cartItems => {
const { items, cart, total } = this.state

const removeItem = cart.filter(item => item.id !== cartItems.id)

const itemId = items.find(item => item.name === cartItems.name).remaining++

this.setState({
removeFromCartMessage: true,
total: total - cartItems.price,
cart: removeItem,
...items, remaining: itemId
})
}

render() {
const { cart, items, total, addToCartMessage, removeFromCartMessage } =
this.state

if (addToCartMessage || removeFromCartMessage) {
setTimeout(() => {
this.setState({
addToCartMessage: false,
removeFromCartMessage: false
})
}, 1000)
}

const filteredItems = items.filter(item =>
item.name.includes(this.state.searchTerm))

return (
<div className="App">
{cart.length === 0 ? <h3>No items in cart</h3> : (
<div>
<h1>Cart:</h1>
{cart.map(items => (
<div key={items.id}>
<h1>{items.name} x 3</h1>
<p>${items.price}</p>
<button onClick={() => this.removeItem(items)}>Remove From Cart</button>
</div>
))}
</div>
)}

<hr />

<input
type="text"
placeholder="Search for an item..."
onChange={e => this.setState({ searchTerm: e.target.value })}
value={this.state.searchTerm}
/>

{filteredItems.map(item => (
<div key={item.id}>
<h1>{item.name}</h1>
<p>Price: ${item.price}</p>
{item.remaining === 0 ? <p>Sold Out</p> : (
<div>
<p>Remaining: {item.remaining}</p>
<button onClick={() => this.addItem(item)}>Add To Cart</button>
</div>
)}
</div>
))}

{ total !== 0 ? <h1>Total ${total}</h1> : <h1>Total $0</h1> }
{ addToCartMessage && <h1>Item successfully added!</h1> }
{ removeFromCartMessage && <h1>Item successfully removed!</h1> }
</div>
)
}
}

export default App

最佳答案

按 ID 将您的产品存储在常规对象中。

1: {
id: 1,
name: 'chocolate'
}

将您的购物车存储为 ID 数组。

[1, 1, 1]

在您的组件中,按 ID 对购物车数组 ID 进行分组以获取计数,并按 ID 查找购物车对象以获取其数据。

计算数据应该被计算,而不是存储。

下面是一些完全未经测试、未修改的代码,显示了在渲染函数中完成的计算:

class App extends Component {
state = {
cart: [],
items: [
{ id: uuid(), name: 'chocolate', price: 10, available: 5 },
{ id: uuid(), name: 'strawberry', price: 50, available: 10 },
{ id: uuid(), name: 'banana', price: 43, available: 20 }
// Convert to an object of { id: { id, name, price } }
].reduce((memo, item) => ({
...memo,
[item.id]: item
}), {}),
}

addItem = id => {
const { cart, } = this.state

this.setState({
cart: [ ...cart, id ]
})
}

removeItem = removeId => {
const { cart, } = this.state
this.setState({
cart: cart.filter(({ id }) => id !== removeId)
})
}

render() {
const { cart, items, total, addToCartMessage, removeFromCartMessage } = this.state

// Given an array of item IDs in our cart, group them into an object
// with the total count and price for each item, and overall count
const accumulatedItems = items.reduce((memo, item) => {
const { id, price } = item;
const { count, price, } = memo[id] || {};
return {
...memo,
cartTotal: memo.cartTotal + price,
[id]: {
count: (count || 0) + 1,
total: (price || 0) + price,
}
};
// Starting object to reduce
}, {
cartTotal: 0,
});

return (
<div className="App">
{cart.length === 0 ? <h3>No items in cart</h3> : (
<div>
<h1>Cart:</h1>
{Object.keys(accumulatedItems).sort().map(id => (
<div key={id}>
<h1>{items[id].name} x {accumulatedItems[id].total}</h1>
<p>${accumulatedItems[id].total}</p>
<button onClick={() => this.removeItem(id)}>Remove From Cart</button>
</div>
))}
</div>
)}
</div>
);
}
}

处理计算数据和改变状态(如 remaining)会显着增加您应用的逻辑复杂性。一旦出现性能问题,您应该只开始担心尝试存储/缓存/内存计算状态。在渲染函数中计算总数是很好的第一步。

在 React in the wild 中,有像 reselect 这样的解决方案。 ,这在技术上不需要 redux。它们只是缓存接受给定状态并产生计算输出的函数,并且仅在输入发生变化时才重新计算输出。

关于javascript - 在 React.js 中推送唯一对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50652485/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com