将多个对象添加到数组?

时间:2018-08-13 12:59:37

标签: javascript arrays reactjs

每次我单击一个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

2 个答案:

答案 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>