为什么React以错误的顺序呈现我的DOM元素?

时间:2017-11-20 12:54:40

标签: reactjs sorting rendering

我正在使用React 16构建一个简单的电子商务应用程序。当我从购物车中删除项目时,即使原始数组未发生变异,显示的项目顺序也会更改。新阵列也正确排序。冲突中的钥匙也没有。它们在渲染过程中也不会改变。

以下是购物车之前从第一件商品中删除一件商品: enter image description here

以下是之后>从第一项中删除一个数量的购物车

enter image description here

如您所见,该项目会跳至最后一个订单。

以下是removeFromCart代码:

export const removeFromCart = item => prevState => {
  let index = prevState.cart.indexOf(item.key)

  console.log('cart before removal', prevState.cart)

  let newCart = [
    ...prevState.cart.slice(0, index),
    ...prevState.cart.slice(index + 1)
  ]

  console.log('cart after removal', newCart)

  return {
    cart: newCart
  }
}

这是我的CartPage组件:

function CartPage({ items, onAddOne, onRemoveOne }) {
  return items.length > 0 ? (
    <ul className="CartPage-items">
      {items.map(item => (
        <li key={item.key} className="CartPage-item">
          <Item item={item}>
            <div className="CartItem-controls">
              <button
                onClick={() => onRemoveOne(item)}
                className="CartItem-removeOne"
              >
                &ndash;
              </button>
              <span className="CartItem-count">{item.count}</span>
              <button
                onClick={() => onAddOne(item)}
                className="CartItem-addOne"
              >
                +
              </button>
            </div>
          </Item>
        </li>
      ))}
    </ul>
  ) : (
    <p>Your shopping cart is empty</p>
  )
}

可以查看完整代码here 可以看到实时应用here

打开控制台以查看数组顺序。请在购物车中添加一堆商品,然后尝试删除一个数量,以便重现问题。

2 个答案:

答案 0 :(得分:1)

我只看了你的源代码。我可以从中推断出,当您创建购物车物品对象时,您正在使用Object.keys(itemCounts),其中itemCounts是一个javascript对象。

请注意,您不会按照插入它们的顺序获取密钥。如果您想要订购商品,则可以使用数组

以下是一些参考链接

How to iterate javascript object properties in the order they were written

Does JavaScript Guarantee Object Property Order?

希望有所帮助

答案 1 :(得分:0)

您必须找到该项目所在的特定索引,然后对其进行修改,最后以相同的顺序返回到状态。否则,您的产品将以错误的顺序显示。

我第一次看到prevState在反应中,所以我不知道它是如何工作的。您的代码似乎非常简洁。我通常创建增量和减量按钮。我将向您展示逻辑在增量方法中的工作原理:

increment = id => {   //I passed the product id
    let tempCart = [...this.state.cart]; //copy the values of the cart in the state into tempCart
    const selectedProduct = tempCart.find(item => {//I find the item in tempCart
      return item.id === id;
    });
    const index = tempCart.indexOf(selectedProduct);//the index of that item in tempCart
    const product = tempCart[index];//and finally i built my virtual product. now you can modify this.
.
.
//after modification update the state
 this.setState(() => {
      return {
        cart: [...tempCart]
      };
    }, this.addTotals); //this.addTotals to update the total with tax. I call this right after i set the state.