首页 > 解决方案 > 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>
    )
}
}

标签: javascriptreactjs

解决方案


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

推荐阅读