简体   繁体   中英

Splice() deletes wrong element in array

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM