0

My problem is when I'm deleting inputs that added dynamically it delete's wrong input. I reproduced my code in jsfiddle https://jsfiddle.net/armakarma/qwg3j2fa/24/ . Try to add five more inputs, type something in each input and try to delete second input. It will delete last one. Where I'm doing mistake?

addNewInputs() {

    let newInputValues = {
        datetime: "10.05.2019 14:00",
        position_id: 1,
        contact: "",
        address_id: "",
        new_address: "",

    }
    this.setState(prevState => ({
        arrayOfAddresses: [...prevState.arrayOfAddresses, newInputValues],
    }))
}

deleteInput(idx) {

    let tempObj = this.state.arrayOfAddresses

    tempObj.splice(idx, 1)
    this.setState(prevState => ({
        arrayOfAddresses: tempObj,
    }))

}

onChooseAddress(e, idx) {
    console.log(e.target.value)

}

render() {

    return ( <
        div > {
            this.state.arrayOfAddresses.map((item, idx) => {
                return (
                    <div key = {idx} >
                      <input name = "contact"
                      onChange = {(e) => this.onChooseAddress(e)}
                    /> 
                      <button onClick = {() => this.deleteInput(idx)} > x < /button> 
                    </div>
                )
            })
        } 
          <button onClick = {() => this.addNewInputs()} > Add new input < /button> 
        /div>
    )
}
}
Yerlan Yeszhanov
  • 2,149
  • 12
  • 37
  • 67
  • [How do I create a runnable React Stack Snippet on Stack overflow?](https://meta.stackoverflow.com/questions/338537) – adiga May 04 '19 at 10:07
  • arrName.splice(starting index,number of element you want to delete); Ex: arrName.splice(1,1); Ref: https://stackoverflow.com/questions/500606/deleting-array-elements-in-javascript-delete-vs-splice/51090038#51090038 – Srikrushna May 04 '19 at 10:22
  • @SrikrushnaPal OP is not asking for correct usage of `.splice()`. – Anurag Srivastava May 04 '19 at 10:57

2 Answers2

2

The problem is with the chooseAddress method, you're not passing the index from the onChange callback, that's why the state is not updating, and also you have not added value prop to the input, that's why rendering was wrong, because of input's internal state

class TodoApp extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
    adresses:[
  {
    "id": 1,
    "address": "address 1",
  },
  {
    "id": 2,
    "address": "address 2",
  },
  {
    "id": 3,
    "address": "address 3",
  },
  {
    "id": 4,
    "address": "address 4",
  }
],
        arrayOfAddresses: [
        {
          datetime: "10.05.2019 14:00",
          position_id: 1,
          contact: "",
          address_id: "",
          new_address: "",
        },
      ],

    }
  }

  addNewInputs() {

    let newInputValues = {
      datetime: "10.05.2019 14:00",
      position_id: 1,
      contact: "",
      address_id: "",
      new_address:"",

    }
    this.setState(prevState => ({
      arrayOfAddresses: [...prevState.arrayOfAddresses, newInputValues],
    }))
  }

deleteInput(idx) {

  this.setState(prevState => {
    let tempObj = [...prevState.arrayOfAddresses]
    tempObj.splice(idx, 1)
    console.log(tempObj) 
    return {
      arrayOfAddresses: tempObj,
    }
  })

}

onChooseAddress(e, idx) {
const {value} = e.target;
    this.setState(state=>{
    let tempObj = [...this.state.arrayOfAddresses]
    tempObj[idx].new_address = value
      return {
          arrayOfAddresses: tempObj,
      }
    })
  }

  render() {

    return (
      <div>
        {this.state.arrayOfAddresses.map((item,idx)=>
    <div>

          <input
            name="contact"
            value={item.new_address}
            onChange={(e) => this.onChooseAddress(e, idx)}
          />
          <button onClick={() => this.deleteInput(idx)}> x</button>
    </div>
        )}
        <button  onClick={() => this.addNewInputs()}> Add new input </button>
      </div>
    )
  }
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"))
Shridhar Sharma
  • 2,337
  • 1
  • 9
  • 13
1

There are two things you need to change:

  1. Set the value of <input>. The problem is that the arrayOfAddresses is set correctly, but correct values are not reflected in the input.

  2. Add the corresponding idx value to the onChange of <input>

Here's the relevant code change:

<input name="contact" value={item.new_address} onChange={(e) => this.onChooseAddress(e, idx)}
 />

Here's the fiddle: JSFiddle

Anurag Srivastava
  • 14,077
  • 4
  • 33
  • 43