开发者问题收集

如何在 React 中设置重复值的计数器?

2020-10-07
854

我的代码基本上是一个带有文本输入和提交按钮的表单。每次用户输入数据时,我的代码都会将其添加到数组中并在表单下显示。

它工作正常;但是,当我添加重复值时,它仍会将其添加到列表中。我希望我的代码计算这些重复项并将它们显示在每个输入旁边。 例如,如果我输入两个“Hello”和一个“Hi”,我希望结果如下: 2 Hello 1 Hi

这是我的代码

import React from 'react';
import ShoppingItem from './ShoppingItem';




class ShoppingList extends React.Component {
    constructor (props){
        super(props);

        this.state ={
           shoppingCart: [],
            newItem :'',
            counter: 0        };

    }

    handleChange =(e) => 
    {
        this.setState ({newItem: e.target.value });
    }

    
    handleSubmit = (e) =>
    {
        e.preventDefault();
        let newList;
        let myItem ={
            name: this.state.newItem,
            id:Date.now()
        }
        if(!this.state.shoppingCart.includes(myItem.name))
        {
            newList = this.state.shoppingCart.concat(myItem);
        }
        if (this.state.newItem !=='')
        {
            this.setState(
                {
                   shoppingCart: newList
                }
         );
        }
        this.state.newItem ="" ;
    }

我的其余代码如下:

render(){      
        return(
            <div className = "App">

                <form onSubmit = {this.handleSubmit}>
                    <h6>Add New Item</h6>
                    <input type = "text" value = {this.state.newItem} onChange ={this.handleChange}/>
                    <button type = "submit">Add to Shopping list</button>
                </form>
                <ul>
                        {this.state.shoppingCart.map(item =>(

                                
                                <ShoppingItem item={item} key={item.id} />
                        )                         
                          )}
                </ul>

            </div>
        );
    }
}

export default ShoppingList;
2个回答

问题

  1. this.state.shoppingCart 是一个对象数组,因此 this.state.shoppingCart.includes(myItem.name) 始终 返回 false,因为它找不到字符串值。
  2. this.state.newItem = ""; 是状态突变

解决方案

  1. 首先检查 newItem 状态,如果为空则提前返回
  2. 通过 name 属性在 this.state.shoppingCart 中搜索第一个匹配项的索引
  3. 如果找到,则需要将购物车映射到新数组,然后将该项复制到新对象引用中并更新数量。
  4. 如果未找到,则复制数组并将新对象附加到末尾,初始值为数量 1 属性。
  5. 更新购物车和 newItem 状态。

代码

handleSubmit = (e) => {
  e.preventDefault();

  if (!this.state.newItem) return;

  let newList;

  const itemIndex = this.state.shoppingCart.findIndex(
    (item) => item.name === this.state.newItem
  );

  if (itemIndex !== -1) {
    newList = this.state.shoppingCart.map((item, index) =>
      index === itemIndex
        ? {
            ...item,
            quantity: item.quantity + 1
          }
        : item
    );
  } else {
    newList = [
      ...this.state.shoppingCart,
      {
        name: this.state.newItem,
        id: Date.now(),
        quantity: 1
      }
    ];
  }

  this.setState({
    shoppingCart: newList,
    newItem: ""
  });
};

注意 :请记住在 ShoppingItem 组件中使用 item.nameitem.quantity

编辑 how-to-set-a-counter-for-duplicate-values-in-react

Drew Reese
2020-10-07

用下面的代码替换你的“handleSubmit”并检查

handleSubmit = (e) => {
    e.preventDefault();
    const { shoppingCart, newItem } = this.state;
    const isInCart = shoppingCart.some(({ itemName }) => itemName === newItem);
    let updatedCart = [];
    let numberOfSameItem = 1;
    if (!isInCart && newItem) {
      updatedCart = [
        ...shoppingCart,
        {
          name: `${numberOfSameItem} ${newItem}`,
          id: Date.now(),
          itemName: newItem,
          counter: numberOfSameItem
        }
      ];
    } else if (isInCart && newItem) {
      updatedCart = shoppingCart.map((item) => {
        const { itemName, counter } = item;
        if (itemName === newItem) {
          numberOfSameItem = counter + 1;
          return {
            ...item,
            name: `${numberOfSameItem} ${itemName}`,
            itemName,
            counter: numberOfSameItem
          };
        }
        return item;
      });
    }
    this.setState({
      shoppingCart: updatedCart,
      newItem: ""
    });
  };
Paveloosha
2020-10-07