将另一个项添加到数组时从数组中删除项

时间:2022-01-25 19:43:37

I have an array of numbers and when an item is added to this array the numbers should be replaced by this item.

我有一个数字数组,当一个项目添加到这个数组时,数字应该被这个项目替换。

The problem I'm having is that most of the time it will replace the number, however sometimes it will add the item next to the number.

我遇到的问题是大多数时候它会替换数字,但有时它会在数字旁边添加项目。

I also have the same problem when removing the item in that the number will sometimes appear next to the item.

删除项目时我也遇到同样的问题,因为项目旁边有时会显示该数字。

Also It currently allows an item to be added multiple times so that if an item is added twice it will show one instance of the item and the remove button has to be clicked twice to actually remove the item.

此外,它目前允许多次添加项目,以便如果项目被添加两次,它将显示该项目的一个实例,并且必须单击删除按钮两次才能实际删除该项目。

How can I prevent the behavior of the number appearing next to the item when being added/removed and also prevent being able to add an item more than once?

如何在添加/删除项目时防止出现在项目旁边的数字的行为,并且还可以防止能够多次添加项目?

https://codesandbox.io/s/jp26jrkk89

Hello.js

import React from 'react';
import update from 'immutability-helper'
import styled from 'styled-components'
import Product from './Product'

const NumberWrap = styled.div`
  display: flex;
  flex-wrap:wrap
  border: 1px solid #ccc;
  flex-direction: row;
`

const Numbers = styled.div`
  display:flex;
  background: #fafafa;
  color: #808080;
  font-size: 32px;
  flex: 0 0 20%;
  min-height: 200px;
  justify-content: center;
  align-items:center;
  border-right: 1px solid #ccc;
`

const CardWrap = styled.div`
  display:flex;
  flex-wrap: wrap;
  flex-direction: row;
  margin-top: 20px;
`

export default class Hello extends React.Component {
  constructor() {
    super()
    this.state = {
      placeholder: [1, 2, 3, 4, 5],
      addedArray: [],
      data: [
        { id: 1, header: 'Item 1' },
        { id: 2, header: 'Item 2' },
        { id: 3, header: 'Item 3' },
        { id: 4, header: 'Item 4' }
      ],
      addedItems: [],
    }
  }

  handleAdd = (id) => {
    const nextAdded = [id, ...this.state.addedArray];
    this.setState({
      addedArray: nextAdded,
      addedItems: update(this.state.addedItems, {
        $push: [
          id,
        ],
      })
    })
  }

  handleRemove = (id) => {
    const index = this.state.addedItems.indexOf(id);
    const nextAdded = this.state.addedArray.filter(n => n != id);
    this.setState({
      addedArray: nextAdded,
      addedItems: update(this.state.addedItems, {
        $splice: [
          [index, 1]
        ],
      })
    })
  }

  render() {
    return (
      <div>
        <NumberWrap>
          {
            this.state.placeholder.map(num =>
              <Numbers>
                {this.state.addedArray.filter(n => n == num).length == 0 && num}
                {
                  this.state.data.filter(item => {
                    return this.state.addedItems.indexOf(item.id) === num - 1;
                  }).slice(0, 5).map(item =>
                    <Product {...item} remove={() => { this.handleRemove(item.id) }} />
                    )
                }
              </Numbers>
            )
          }
        </NumberWrap>


        <CardWrap>
          {
            this.state.data.map(item =>
              <Product
                {...item}
                add={() => {
                  this.handleAdd(item.id)
                }}
              />
            )}
        </CardWrap>
      </div>
    )
  }
}

Product.js

import React from "react";
import styled from "styled-components";

const Card = styled.div`
  flex: 0 0 20%;
  border: 1px solid #ccc;
`;

const Header = styled.div`
  padding: 20px;
`;

const AddBtn = styled.button`
  width:100%;
  height: 45px;
`;

const Product = props => {
  const { add, id, header, remove } = props;
  return (
    <Card>
      <Header key={id}>
        {header}
      </Header>
      <AddBtn onClick={add}>Add</AddBtn>
      <AddBtn onClick={remove}>Remove</AddBtn>
    </Card>
  );
};

export default Product;

2 个解决方案

#1


1  

Here is the link to the demo :

以下是演示的链接:

Please check :

请检查 :

https://codesandbox.io/s/8kl2pkw5m0


I have removed the addedItems and just used addedArray

我删除了addedItems,只使用了addedArray

Here is the one way to stop adding multiple

这是停止添加多个的一种方法

const nextAdded = [...new Set([id, ...this.state.addedArray])];

Create a set out of array then gain create it array this way all the duplicate entry will be removed.

创建一个数组的集合,然后以这种方式获取创建它的所有重复条目将被删除。

#2


2  

In this case it seems easier to work with your items directly and store them in an object.

在这种情况下,直接使用您的项目并将它们存储在对象中似乎更容易。

Check out my fork for a working example.

查看我的前叉以获取一个工作示例。

  • Changed addedItems to an object
  • 将addedItems更改为对象

  • Changed add handler to use the item object directly
  • 更改了添加处理程序以直接使用项目对象


export default class Hello extends React.Component {
  constructor() {
    super()
    this.state = {
      placeholder: [1, 2, 3, 4, 5],
      data: [
        { id: 1, header: 'Item 1' },
        { id: 2, header: 'Item 2' },
        { id: 3, header: 'Item 3' },
        { id: 4, header: 'Item 4' }
      ],
      addedItems: {},
    }
  }

  handleAdd = (item) => {
    this.setState({
      addedItems: update(this.state.addedItems, {
        [item.id]: {$set: item}
      })
    })
  }

  handleRemove = (item) => {
    this.setState({
      addedItems: update(this.state.addedItems, {
        $unset: [item.id]
      })
    })
  }

  render() {
    return (
      <div>
        <NumberWrap>
          {this.state.placeholder.map(num => {
            const item = this.state.addedItems[num];
            return (
              <Numbers>
                {item &&
                  <Product
                    key={num}
                    {...item}
                    remove={() => {
                      this.handleRemove(item);
                    }}
                  />
                }
              </Numbers>
            );
          })}
        </NumberWrap>
        <CardWrap>
          {this.state.data.map(item =>
            <Product
              {...item}
              add={() => {
                this.handleAdd(item)
              }}
            />
          )}
        </CardWrap>
      </div>
    )
  }
}

#1


1  

Here is the link to the demo :

以下是演示的链接:

Please check :

请检查 :

https://codesandbox.io/s/8kl2pkw5m0


I have removed the addedItems and just used addedArray

我删除了addedItems,只使用了addedArray

Here is the one way to stop adding multiple

这是停止添加多个的一种方法

const nextAdded = [...new Set([id, ...this.state.addedArray])];

Create a set out of array then gain create it array this way all the duplicate entry will be removed.

创建一个数组的集合,然后以这种方式获取创建它的所有重复条目将被删除。

#2


2  

In this case it seems easier to work with your items directly and store them in an object.

在这种情况下,直接使用您的项目并将它们存储在对象中似乎更容易。

Check out my fork for a working example.

查看我的前叉以获取一个工作示例。

  • Changed addedItems to an object
  • 将addedItems更改为对象

  • Changed add handler to use the item object directly
  • 更改了添加处理程序以直接使用项目对象


export default class Hello extends React.Component {
  constructor() {
    super()
    this.state = {
      placeholder: [1, 2, 3, 4, 5],
      data: [
        { id: 1, header: 'Item 1' },
        { id: 2, header: 'Item 2' },
        { id: 3, header: 'Item 3' },
        { id: 4, header: 'Item 4' }
      ],
      addedItems: {},
    }
  }

  handleAdd = (item) => {
    this.setState({
      addedItems: update(this.state.addedItems, {
        [item.id]: {$set: item}
      })
    })
  }

  handleRemove = (item) => {
    this.setState({
      addedItems: update(this.state.addedItems, {
        $unset: [item.id]
      })
    })
  }

  render() {
    return (
      <div>
        <NumberWrap>
          {this.state.placeholder.map(num => {
            const item = this.state.addedItems[num];
            return (
              <Numbers>
                {item &&
                  <Product
                    key={num}
                    {...item}
                    remove={() => {
                      this.handleRemove(item);
                    }}
                  />
                }
              </Numbers>
            );
          })}
        </NumberWrap>
        <CardWrap>
          {this.state.data.map(item =>
            <Product
              {...item}
              add={() => {
                this.handleAdd(item)
              }}
            />
          )}
        </CardWrap>
      </div>
    )
  }
}