0

I have a Row Component that i am importing into my App.js component and apparently i but the delete function doesn't seem to be deleting the correct row. Even if i delete the second one, it deletes the last one first. So basically if i click delete on second row, it should delete the second one not the third etc.

My App.js or my root component looks like this: -

import React, {Component} from 'react';
import './App.css';
import Row from './Row.js'

class App extends Component {
   state = {
      rows: [
       {value: 'row1', options:[1,2,3,4,5] },
       {value: 'row2', options:[1,2,3,4,5] },
       {value: 'row3', options:[ 1,2,3,4,5 ]}
     ]
  }

  updateValue = (e, idx) => {
  const rows = [...this.state.rows];
  rows[idx].value = e.target.value;
 this.setState({
  rows,
 });
}

addRow = () => {
const rows = [...this.state.rows, {value:'', options: [1,2,3,4,5}];
 this.setState({
    rows,
   });
 }

 deleteRow = (idx) => {
 const copy = [...this.state.rows]
 copy.splice(idx,1)
 this.setState ({
 rows:copy
  })
}

render() {
   return (
      <div>
    {
  this.state.rows.map ( (row,idx) => {
    return (
      <Row 
      key = {idx} 
      value = { row.value } 
      onChange = { (e) => this.updateValue(e,idx) } 
      delete = { this.deleteRow.bind(this,idx) } />
       )
    })
   }
 <button onClick = {this.addRow}> Add </button>
 </div>
     )
   }
} 

 export default App;

And my row component looks like this:-

const Row = ( props) => {
let options = props.options.map(opt => <option key={opt}>{opt}</option>);

return (
   <div>
    <input value= { props.value } onChange={ props.onChange }></input>
    <select>
        {options}
    </select>
    <button onClick = { props.delete} > Delete </button>  
   </div>
  )
}

export default Row

I asked a similar question yesterday link but didn't realize at the time that the items weren't being deleted from the right position?

3
  • Dont u think u r missing this i.e. this.props ? Commented Jan 27, 2020 at 17:57
  • Your example actually seems to be working properly for me. I commented out the options rendering in your Row component, but that's a different issue than deleting the rows. Commented Jan 27, 2020 at 18:04
  • 1
    It works for me too. Fixed several syntactic errors and it ran correctly. Commented Jan 27, 2020 at 18:15

1 Answer 1

1

Try this

deleteRow = (item) => {
 let filtered = this.state.rows.filter(row=>row.value!==item.value);
 this.setState ({
 rows: filtered
  })
}

pass row to your delete function

    <Row 
      key = {idx} 
      value = { row.value } 
      onChange = { (e) => this.updateValue(e,idx) } 
      delete = {()=>this.deleteRow(row) } />
       )

if every row(object) is having unique id then use that id instead of value like-

 let filtered = this.state.rows.filter(row=>row.id!==item.id);
Sign up to request clarification or add additional context in comments.

9 Comments

@Somethingwhatever check now by changing both mentioned code
if multiple rows shared the same value, this would delete extra rows
@khuynh what would you suggest then? because my code doesn't seem to be doing what is expected :|
This is bad practise. new state should not old state like that. Then you should use function for setting state
I agree this is better practice than splicing the states (given the rows have a unique id to properly filter on). However, I believe it is slightly better practice to use the prevProps argument with setState. This guarantees that the state will be up to date.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.