如何在React中根据索引从嵌套数组中删除对象?

3
我点击产品上的“删除”图标。我取出它的索引并将其保存在状态中,例如:select: 1index: 1。 如何设置this.setState以删除嵌套在数组products的数组colors中的对象。例如,删除对象:
{
  a: 'orange'
} 

从数组products中的colors中删除 this.state.selectproducts中的项目,“this.state.index”是要删除的项目中的颜色。
在实际应用中,它是什么样子的?给你产品和颜色的ID?我希望它是动态的。我点击产品,下载其索引并删除。
class App extends Component {
  constructor(){
    super();

    this.state {
      products: [  
            {
                colors: [{a:'black'}, {a:'orange'}, {a:'purple'}]
                desc: 'gfgfg'
            },
            {
                colors: [{a: 'yellow'}, {a: 'white'}, {a:'gray'}],
                desc: 'gfgfgfg'
            },
            {
                colors: [{a: 'pink'}, {a: 'brown'}, {a:'green'}],
                desc: 'gfgfgfg'
            }
        ],
        select: 1 //example
        index: 1 //example
    }

  }

  removeItem = () => {
    const { select, index } = this.state;

    if(index) {
      this.setState({
          products: [
            ...this.state.products[select].colors.slice(0, index),
            ...this.state.products[select].colors.slice(index + 1),
          ]
      });
    }
  };


  render () {

    return (
      <div>
        <ul>
            {
                this.state.products
                .map((product, index) =>
                    <Product
                        key={index}
                        index={index}
                        product={product}
                    />
                )
            }
        </ul>
          <Products

          />
      </div>
    )
  } 
}

那么 this.state.select 是要被删除的产品中的项目,而 this.state.index 是要被删除的 colors 下的项目? - Chris
“select”和“index”的区别是什么? - Jose A. Ayllón
this.state.select 是产品中的项,this.state.index 是要删除的项中的颜色。 - Umbro
2个回答

1
你需要将删除函数传递给Product组件,在Product组件中将选择和索引传递给removeItem函数。
修改你的删除项目,接受两个参数selectindex
removeItem = (select, index) => {

  const filtered = this.state.products[select].colors.filter(
    (color, i) => i !== index
  );

  this.setState(prevState => {
    return {
      select: select,
      index: index,
      products: [
        ...prevState.products.slice(0, select),
        Object.assign({}, prevState.products[select], { colors: filtered }),
        ...prevState.products.slice(select + 1)
      ]
    };
  });
};

将函数作为 prop 传递给 Product 组件。
<div>
  <ul>
    {this.state.products.map((product, index) => (
      <Product
        key={index}
        index={index}
        removeItem={this.removeItem}
        product={product}
      />
    ))}
  </ul>
</div>

在您的产品组件中,传递颜色的索引和选择。
<button onClick={() => removeItem(index, i)}>X</button>

演示

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>

<div id="root"></div>

<script type="text/babel">

class Product extends React.Component {
  render() {
    const { product, removeItem, index } = this.props;
    return (
      <div>
        <p>{product.desc}</p>
        <ul>
          {product.colors.map((color, i) => (
            <li>
              {color.a} <button onClick={() => removeItem(index, i)}>X</button>
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      name: "React",
      products: [
        {
          colors: [{ a: "black" }, { a: "orange" }, { a: "purple" }],
          desc: "gfgfg"
        },
        {
          colors: [{ a: "yellow" }, { a: "white" }, { a: "gray" }],
          desc: "gfgfgfg"
        },
        {
          colors: [{ a: "pink" }, { a: "brown" }, { a: "green" }],
          desc: "gfgfgfg"
        }
      ],
      select: 1, //example
      index: 1 //example
    };
  }

    removeItem = (select, index) => {
      const filtered = this.state.products[select].colors.filter(
        (color, i) => i !== index
      );

      this.setState(prevState => {
        return {
          select: select,
          index: index,
          products: [
            ...prevState.products.slice(0, select),
            Object.assign({}, prevState.products[select], { colors: filtered }),
            ...prevState.products.slice(select + 1)
          ]
        };
      });
    };

  render() {
    return (
    <div>
      <ul>
        {this.state.products.map((product, index) => (
          <Product
            key={index}
            index={index}
            removeItem={this.removeItem}
            product={product}
          />
        ))}
      </ul>
    </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
</script>


你很棒 :) - Umbro

0

只需使用Array.filter()创建一个不包含特定元素的新数组。因此,您的新颜色数组为:

this.state.products[select].colors.filter( color => color.a !== 'orange' )

这将保留所有颜色,其中a不是橙色。 请记住,数组是从零开始的,因此您的selectindex都应该从0开始。

如果您不想存储实际索引,请改用描述。

因此,如果select代替数组索引,则可以执行以下操作:gfgfg

const state = {
  products: [
      {
          colors: [{a:'black'}, {a:'orange'}, {a:'purple'}],
          desc: 'gfgfg'
      },
      {
          colors: [{a: 'yellow'}, {a: 'white'}, {a:'gray'}],
          desc: 'gfgfgfg'
      },
      {
          colors: [{a: 'pink'}, {a: 'brown'}, {a:'green'}],
          desc: 'gfgfgfg'
      }
  ],
  selected_product: 'gfgfg',
  color: 'orange'
};

const setState = update => Object.assign( state, update );

console.log( 'before update' );
console.log( JSON.stringify( state.products[0] ));

setState({
  products: state.products.map( product => {
    if ( product.desc === state.selected_product ) {
      product.colors = product.colors.filter( color => color.a !== state.color );
    }
    return product;
  })
});

console.log( 'after update' );
console.log( JSON.stringify( state.products[0] ));

同样的逻辑显然可以使用索引完成,但这可能会导致代码变长。 如果必须完全不可变,则可能需要更新部分代码。


这不是我预期的。在实际应用中它是什么样子?给出你的产品和颜色ID?我希望它是动态的。我点击产品,下载它的索引并删除。 - Umbro
给所有产品分配一个独特的ID,例如来自产品数据库的ID。将该ID作为数据属性包含在行中。在集合中再次查找产品。我总是使用ID进行操作,因为这样可以使用基本超链接,无需添加点击事件将索引转换回实际的产品标识符。 - Shilly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接