数组内对象的setState

时间:2018-07-01 20:08:17

标签: javascript reactjs

鉴于我的状态如下:

cart: [
  { id: 1, name: 'apple', price: 100, quantity: 1 }
]

我如何setState那个特定对象的quantity属性?

3 个答案:

答案 0 :(得分:4)

您可以在购物车中获取要更新的indexOf个商品,并使用该商品,更新后的商品以及其余所有商品来更新cart。 / p>

示例

class App extends React.Component {
  state = {
    cart: [
      { id: 1, name: "apple", price: 100, quantity: 1 },
      { id: 2, name: "orange", price: 50, quantity: 10 },
      { id: 3, name: "banana", price: 20, quantity: 100 }
    ]
  };

  increaseQuantity = item => {
    this.setState(previousState => {
      const { cart } = previousState;
      const itemIndex = cart.indexOf(item);

      return {
        cart: [
          ...cart.slice(0, itemIndex),
          { ...cart[itemIndex], quantity: cart[itemIndex].quantity + 1 },
          ...cart.slice(itemIndex + 1)
        ]
      };
    });
  };

  render() {
    return (
      <div>
        {this.state.cart.map(item => (
          <div key={item.id} onClick={() => this.increaseQuantity(item)}>
            {item.name} {item.quantity}
          </div>
        ))}
      </div>
    );
  }
}

答案 1 :(得分:3)

您可以将购物车更新为

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<form><!-- use the form as the wrapper to scroll -->
  <table>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Program</th>
      <th>Class</th>
      <th>Student ID</th>
      <th>Start Date</th>
      <th>End Date</th>
      <th>Country</th>
      <th colspan=5></th><!-- html update numbers of column must be equal on each rows -->
    </tr>
    <!-- below your rendered HTML cleaned up from the php useless in snippet to demonstrate the CSS DEMO about sticky -->
    <tr>
      <td><input type=text name=fname id=name_val value="name"><!-- html update closing tag on input --></td>
      <td><input type=text name=email id=email_val value="email. "></td>
      <td><input type=text name=prog  id=prog_val value="program. "></td>
      <td><input type=text name=class id=class_val value=">class. "></td>
      <td><input type=text name=sdate id=start_val value="start_date. "></td>
      <td><input type=text name=edate id=end_val value="end_date. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=hidden name=hidden value="student_id. "></td>
      <td><input type=submit name=update value="update"> <input type=submit name=delete value="delete"><!-- html update both button in a single cell --> </td>
    </tr>
     <tr>
      <td><input type=text name=fname id=name_val value="name"><!-- html update closing tag on input --></td>
      <td><input type=text name=email id=email_val value="email. "></td>
      <td><input type=text name=prog  id=prog_val value="program. "></td>
      <td><input type=text name=class id=class_val value=">class. "></td>
      <td><input type=text name=sdate id=start_val value="start_date. "></td>
      <td><input type=text name=edate id=end_val value="end_date. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=hidden name=hidden value="student_id. "></td>
      <td><input type=submit name=update value="update"> <input type=submit name=delete value="delete"><!-- html update both button in a single cell --> </td>
    </tr>
     <tr>
      <td><input type=text name=fname id=name_val value="name"><!-- html update closing tag on input --></td>
      <td><input type=text name=email id=email_val value="email. "></td>
      <td><input type=text name=prog  id=prog_val value="program. "></td>
      <td><input type=text name=class id=class_val value=">class. "></td>
      <td><input type=text name=sdate id=start_val value="start_date. "></td>
      <td><input type=text name=edate id=end_val value="end_date. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=hidden name=hidden value="student_id. "></td>
      <td><input type=submit name=update value="update"> <input type=submit name=delete value="delete"><!-- html update both button in a single cell --> </td>
    </tr>
     <tr>
      <td><input type=text name=fname id=name_val value="name"><!-- html update closing tag on input --></td>
      <td><input type=text name=email id=email_val value="email. "></td>
      <td><input type=text name=prog  id=prog_val value="program. "></td>
      <td><input type=text name=class id=class_val value=">class. "></td>
      <td><input type=text name=sdate id=start_val value="start_date. "></td>
      <td><input type=text name=edate id=end_val value="end_date. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=hidden name=hidden value="student_id. "></td>
      <td><input type=submit name=update value="update"> <input type=submit name=delete value="delete"><!-- html update both button in a single cell --> </td>
    </tr>
     <tr>
      <td><input type=text name=fname id=name_val value="name"><!-- html update closing tag on input --></td>
      <td><input type=text name=email id=email_val value="email. "></td>
      <td><input type=text name=prog  id=prog_val value="program. "></td>
      <td><input type=text name=class id=class_val value=">class. "></td>
      <td><input type=text name=sdate id=start_val value="start_date. "></td>
      <td><input type=text name=edate id=end_val value="end_date. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=text name=stdid id=stdid_val value="student_id. "></td>
      <td><input type=hidden name=hidden value="student_id. "></td>
      <td><input type=submit name=update value="update"> <input type=submit name=delete value="delete"><!-- html update both button in a single cell --> </td>
    </tr>
  </table>
</form>

然后使用您购物车商品的ID调用updateCart函数

updateCart(id, itemAttributes) {
  var index = this.state.cart.findIndex(x=> x.id === id);
  if (index === -1)
    // handle error
  else
    this.setState({
      cart: [
         ...this.state.cart.slice(0, index),
         Object.assign({}, this.state.cart[index], itemAttributes),
         ...this.state.cart.slice(index+1)
      ]
    });
}

答案 2 :(得分:2)

 this.setState(prev => ({
   cart: [{ ...prev.cart[0], quantity: 10, }].concat(prev.cart.slice(1))
 }));

复制数组,然后将要更改的对象替换为复制的版本。如果经常这样做,则可以使用一些实用程序:

const replace = index, replacer) => arr =>
   arr.map((el, i) => i === index ? replacer(el) : el);
const key = (k, replacer)  => state => ({...state, [k]: replacer(state[k]) });

可用作:

this.setState(key(
   "cart", 
   replace(
     0, 
     key("quantity", () => 10)
   )
));