使用map将新项目推送到数组的末尾,而不是将具有更新值的新数组推送到

时间:2018-10-16 04:44:34

标签: javascript arrays reactjs

我有一个项目列表,用户可以单击以将项目添加到其数组中。它不是在更新数组中的值,而是推送具有相同数字的新值。我正在从Lodash FP获取地图。

这就是我用来映射的内容:

JustifyContent

如果我单击数组中的一个项目,我得到的结果是:

{map((item) => (<Item {...item} key={btoa(Math.random()).substring(0, 12)} />), items)}

但是我期望的结果是:

0: {id: "item1", quantity: 1} 1: {id: "item1", quantity: 1}

实施:

允许您添加项目的组件:

0: {id: "item1", quantity: 2}

循环遍历结果的组件:

const Product = ({add, id, title, image}) => (
  <div className={styles.product} onClick={() => add(id)}>
    <img src={image} alt={title} className={styles.productImage}/>
    {title}
  </div>
);

export default connect(() => ({}), {add})(Product);`

正在执行的操作:

const Cart = connect(
  () => ({}),
  {clear}
)(({items, clear, total}) => {
  return (
    <div>
      <Heading><FontAwesomeIcon icon={faShoppingCart} /> Cart</Heading>
      {items.length ? <button onClick={clear}>Clear all items</button> : null }
      <table>
        <thead>
          <tr>
            <th>Product</th>
            <th>Price</th>
            <th>Quantity</th>
            <th>Total</th>
          </tr>
        </thead>
        <tbody>
          {/* The original version, with a randomly generated key */}
          {items.length ? map((item) =>
            (<Item {...item} key={btoa(Math.random()).substring(0, 12)} />),
          items) : <tr><td>Your cart is empty!</td></tr>}
        </tbody>
      </table>
      {items.length ? <div className={styles.total}>${total}</div> : null }
    </div>);
});

export default connect((state) => {
  return {
    items: state.cart.items,
    total: reduce(
      (sum, {id, quantity}) => sum + products[id].price * quantity,
      0,
      state.cart.items
    ).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'),
  };
})(Cart);

1 个答案:

答案 0 :(得分:0)

如果您要通过id更新状态,则需要映射items数组并找到匹配的id以更新匹配的quantity。以下示例利用了React状态,但对于redux减速器状态(return {...state, items: state.items.map(...etc)})来说却没有什么不同。

工作示例:https://codesandbox.io/s/rjmx8vw99p

import React, { Component } from "react";

export default class App extends Component {
  state = {
    items: [
      { id: "Apples", quantity: 1 },
      { id: "Strawberries", quantity: 1 },
      { id: "Grapes", quantity: 1 },
      { id: "Apricots", quantity: 1 }
    ]
  };

  handleClick = id => {
    this.setState(prevState => ({
      // ...prevState (not needed for this example, but needed for redux)
      items: prevState.items.map(
        item =>
          id === item.id
            ? { id, quantity: item.quantity + 1 }
            : { ...item }
      )
    }));
  };

  render = () => (
    <div className="container">
      <h1>Updating Values Inside Array</h1>
      {this.state.items.map(({ id, quantity }) => (
        <button
          style={{ marginRight: 10 }}
          className="uk-button uk-button-primary"
          key={id}
          onClick={() => this.handleClick(id)}
        >
          {id} ({quantity})
        </button>
      ))}
    </div>
  );
}

上面的代码中发生的事情是简单地将数组添加一个新对象:

items: [
  { id: "item1", quantity: 1 },  // ...spread out previous objects in array
  { id: "item2", quantity: 1 },
  { id: "item3", quantity: 1 },
  { id: "item4", quantity: 1 },
  { id: "item1", quantity: 1 }   // add another object
]

另外,这个:

export default connect(() => ({}), {add})(Product);

应该是这样:

export default connect(null, {add})(Product);