score:1

Accepted answer

you need to pass the remove function to product component, in product component pass the select and index to removeitem function.

modify your remove item, to take in two parameters, select and index.

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)
      ]
    };
  });
};

pass the function as prop to product component.

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

in your product component, pass the index of the color and the select.

<button onclick={() => removeitem(index, i)}>x</button>

demo

<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>

score:0

just use array.filter() to create a new array not containing the specific element. so your new color array for that desc is:

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

this keeps all the colors where a is not orange. keep in mind that arrays are zero-based, so your select and index should both start at 0.

if you do not want to store the actual indexes, use the desc instead.

so if select would be gfgfg instead of the array index, you could do:

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] ));

same logic can obviously be done using the indexes, but that might result in longer code. might have to update some of the code if everything has to be fully immutable.


Related Query

More Query from same tag