每次我单击一个size选项,然后单击“添加到购物车”时,我都希望将所选对象的数据添加到此数组cart
中。这目前可以,但是只能添加一个对象,当您尝试再次添加它时,旧数据将消失,并被新对象替换。
我想将奇数对象保留在数组中,并添加新对象。我该怎么做?
index.js
export class App extends Component {
constructor(props) {
super(props);
this.state = {
evenSelected: null
};
}
handleSelectL1 = i => {
this.setState({
evenSelected: i,
oldSelected: null
});
};
render() {
const product = [
{
name: " size one",
price: 1
},
{
name: "size two",
price: 2
},
,
{
name: "size three",
price: 3
}
];
const cart = [];
const addCart = function() {
cart.push(product[evenIndex]);
if (cart.length > 0) {
}
};
console.log("cart", cart);
const evenIndex = this.state.evenSelected;
const priceShown = product[evenIndex] && product[evenIndex].price;
return (
<div>
<Child
product={product}
handleSelectL1={this.handleSelectL1}
evenIndex={evenIndex}
/>
<h2>Price:{priceShown} </h2>
<button onClick={addCart}>Add to cart</button>
</div>
);
}
}
child.js
export class Child extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { product, evenIndex } = this.props;
return (
<div>
{product.map((p, i) => {
return (
<div
key={p.id}
className={evenIndex === i ? "selectedRBox" : "selectorRBox"}
onClick={() => this.props.handleSelectL1(i)}
>
<h1 className="selectorTextL">{p.name}</h1>
</div>
);
})}
</div>
);
}
}
这是我在沙箱上的代码:https://codesandbox.io/s/14vyy31nlj
答案 0 :(得分:3)
我刚刚修改了您的代码以使其正常运行。 Here is the complete code。您需要cart作为状态的一部分,因此它不会在每个渲染中初始化,并在添加元素时使组件再次渲染。
删除该函数以使其成为该类的方法:
addToCart() {
const selectedProduct = products[this.state.evenSelected];
this.setState({
cart: [...this.state.cart, selectedProduct]
});
}
并在渲染器上调用它:
render() {
console.log("cart", this.state.cart);
const evenIndex = this.state.evenSelected;
const priceShown = products[evenIndex] && products[evenIndex].price;
return (
<div>
<Child
product={products}
handleSelectL1={this.handleSelectL1}
evenIndex={evenIndex}
/>
<h2>Price:{priceShown} </h2>
<button onClick={this.addToCart.bind(this)}>Add to cart</button>
</div>
);
}
}
检查我是否绑定了渲染,在某些情况下会带来性能问题。您应该check this
更新
正如devserkan引起我的注意(谢谢!),当您使用以前的状态来定义新状态(例如向数组中添加元素)时,最好使用updater
函数而不是传递新对象进行合并:
this.setState(prevState => ({
cart: [...prevState.cart, products[selectedProduct]],
}));
有关更多信息,check the official docs。
答案 1 :(得分:2)
我不太了解您要做什么,但是这里有一些更改。我已将product
从组件中移出,就像静态变量一样。另外,我更改了addCart
方法,在其中设置状态,而无需更改原始状态并保留旧对象。
const product = [
{
name: " size one",
price: 1
},
{
name: "size two",
price: 2
},
{
name: "size three",
price: 3
}
];
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
evenSelected: null,
cart: [],
};
}
handleSelectL1 = i => {
this.setState({
evenSelected: i,
oldSelected: null
});
};
addCart = () => {
const evenIndex = this.state.evenSelected;
this.setState( prevState => ({
cart: [ ...prevState.cart, product[evenIndex] ],
}))
};
render() {
console.log(this.state.cart);
const evenIndex = this.state.evenSelected;
const priceShown = product[evenIndex] && product[evenIndex].price;
return (
<div>
<Child
product={product}
handleSelectL1={this.handleSelectL1}
evenIndex={evenIndex}
/>
<h2>Price:{priceShown} </h2>
<button onClick={this.addCart}>Add to cart</button>
</div>
);
}
}
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { product, evenIndex } = this.props;
return (
<div>
{product.map((p, i) => {
return (
<div
key={p.id}
className={evenIndex === i ? "selectedRBox" : "selectorRBox"}
onClick={() => this.props.handleSelectL1(i)}
>
<h1 className="selectorTextL">{p.name}</h1>
</div>
);
})}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
.selectorRBox {
width: 260px;
height: 29.5px;
border: 1px solid #727272;
margin-top: 18px;
}
.selectedRBox {
width: 254px;
height: 29.5px;
margin-top: 14px;
border: 4px solid pink;
}
.selectorTextL {
font-family: "Shree Devanagari 714";
color: #727272;
cursor: pointer;
font-size: 18px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>