javascript - 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"))
推荐阅读
- xcode - cmake 不包括 /usr/local/opt/openssl/lib
- javascript - Python获取发布数据以调用远程python脚本以显示在页面上
- javascript - 需要将 CSV 导入 html/javascript 并在数据列表中使用
- swift - 准备 segue 不传递数据
- python - 在从 JS 到 PyQt5 的鼠标点击时存储 lat long
- node.js - Firebase 将通知标题和正文设置为数据库值
- python - UpdateView 以及更新另一个模型字段?
- python - 来自csv文件的beautifulsoup多个关键字
- c++ - 你如何计算重叠时间跨度的总持续时间
- go - k8s 中 Secrets 列表的 LabelSelector