我使用setState更新特定对象但由于某种原因,即使我还没有在setState函数中添加它,另一个对象也会发生变异。
基本上我有一个'添加到购物车'如果项目已经存在于购物车状态对象中,则只需将其数量增加1.如果不是,请使用包含所述项目的副本更新购物车状态。
this.state = {
items: {
0: { name: 'Red shirt', price: 10 },
1: { name: 'Blue shirt', price: 11 },
2: { name: 'Green shirt', price: 12 },
3: { name: 'Yellow shirt', price: 13 }
},
cart: {},
user: {}
}
addToCart = (key, item) => {
let newCart;
newCart = this.state.cart;
// item already exists in cart
if (newCart[key]) {
// increment qty of added item
newCart[key].qty++;
// does not exist, need to add to cart
} else {
newCart[key] = item;
newCart[key].qty = 1;
}
this.setState({ cart: newCart });
}
render() {
const { cart, items } = this.state;
return (
<div className="App">
<h1>Streat</h1>
<Checkout cart={cart} />
<Items
items={items}
addToCart={this.addToCart}
/>
</div>
);
}
}
// Items component which holds Item component
class Items extends Component {
constructor(props) {
super(props)
}
render() {
const { items, addToCart } = this.props;
return (
<div>
{
map(items, function renderItems(item, key) {
return <Item
item={item}
itemRef={key}
key={key}
addToCart={addToCart} />
})
}
</div>
)
}
}
// Item functional component which has the add to cart button
const Item = (props) => {
const { item, itemRef, addToCart } = props;
return (
<div>
<p>{item.name}</p>
<p>{item.price}</p>
<p>{item.qty || ""}</p>
<button onClick={() => addToCart(itemRef, item)}>Add</button>
</div>
)
}
当检查反应开发者工具中我的项目对象的状态时,我看到每次单击按钮将项目添加到购物车时,它都会正确地将项目添加到购物车/更新项目的数量但是它还会更新我所在州的items对象中的项目,添加一个&#39; qty&#39;键/值对不是我想要的。
我在购物车对象上使用了setState,但由于某种原因,我的items对象也被更改了。
答案 0 :(得分:2)
尝试使用spread syntax更新您的州,这样您就不会遇到这种麻烦。 Redux也使用了很多。通过这样做,你不会改变你的对象并创建它们的干净副本。
您的代码不是复制项目在线(var numbers = new List<Number>
{
new Number {X = 1, Y = 137},
new Number {X = 1, Y = 143},
new Number {X = 11, Y = 37},
new Number {X = 11, Y = 46},
new Number {X = 11, Y = 132},
new Number {X = 46, Y = 65},
new Number {X = 46, Y = 139},
new Number {X = 69, Y = 90}
};
var result = numbers.GroupBy(c => c.X);
var result2 = numbers.FirstOrDefault(c => result.Select(d => d.Key).Contains(c.Y));
var finalResult = numbers.Where(x => x.X == result2?.Y)
.Select(x => { x.X = result2.X;x.Y = x.Y; return x; } )
.Union(numbers.Where(c => c.X != result2?.Y)).GroupBy(c => c.X ,
(key, element) => new
{
Key = key,
Element = element.Select(c => c.Y).ToList()
});
)。相反,它会从同一项目中添加引用,并且通过更改下一行中的newCart[key] = item;
,您也会在qty
键中更新它。
items
&#13;
const Item = ({ name, price, onClick }) =>
<div onClick={onClick}>
{name} {price}
</div>
class App extends React.Component {
constructor() {
super()
this.state = {
items: {
0: { name: 'Red shirt', price: 10 },
1: { name: 'Blue shirt', price: 11 },
2: { name: 'Green shirt', price: 12 },
3: { name: 'Yellow shirt', price: 13 }
},
cart: {},
user: {}
}
}
addToCart(key, item) {
const hasItem = this.state.cart[key]
this.setState({
...this.state,
cart: {
...this.state.cart,
[key]: {
...(hasItem ? this.state.cart[key] : item),
qty: hasItem ? this.state.cart[key].qty + 1 : 1,
},
},
})
}
render() {
const { cart, items } = this.state
return (
<div>
<div>Click to add:</div>
{Object.keys(items).map(key =>
<Item
{...items[key]}
key={key}
onClick={this.addToCart.bind(this, key, items[key])}
/>
)}
<div style={{ marginTop: 20 }}>
{Object.keys(cart).map(key =>
<div key={key}>{cart[key].name}:{cart[key].qty}</div>
)}
</div>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
&#13;