【问题标题】:How to set a counter for duplicate values in React?如何在 React 中为重复值设置计数器?
【发布时间】:2021-01-22 00:51:59
【问题描述】:

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

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

这是我的代码

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;

【问题讨论】:

  • render 函数在哪里?
  • 您可以使用状态映射来存储字符串和计数(作为键值对),并且在 handleChange 上只需更新映射中值的计数
  • 请分享你的render函数。
  • 我刚刚添加了包含地图和渲染的其余代码

标签: javascript arrays reactjs react-native


【解决方案1】:

问题

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

解决方案

  1. 先检查newItem状态,如果为空则提前返回
  2. 按名称属性搜索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

【讨论】:

    【解决方案2】:

    将您的“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: ""
        });
      };
    

    【讨论】:

    • @Moona,稍作编辑。您不需要状态计数器,但您需要在每个对象中使用一个计数器来跟踪订购了多少相同的商品。
    猜你喜欢
    • 1970-01-01
    • 2019-05-09
    • 2015-08-01
    • 2018-10-25
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    相关资源
    最近更新 更多