更新 - 动态添加/删除行不按预期工作
我想要做一个表单,可以添加/删除行通过点击添加/删除按钮。我现在的问题是,删除按钮总是可以删除最后一行,而不是删除按钮所在的行。当我使用数组删除操作符时,它可以删除所需的行。然而,这种方法并没有真正删除数组中的对象,并且可能很难在for循环中进行检查。我想知道我在哪里做错了?更新 - 动态添加/删除行不按预期工作
更新时间: 1.增加的jsfiddle https://jsfiddle.net/69z2wepo/84246/ 2.保存下拉值母公司的状态
constructor(props){
super(props)
this.state = {
dropdown: [
{first: "true", hideAdd: "false", result: ""}
]
}
this.addRow = this.addRow.bind(this);
this.removeRow = this.removeRow.bind(this);
this.onChange = this.onChange.bind(this);
}
onChange = (key, value) => {
let oldArray = JSON.parse(JSON.stringify(this.state.dropdown));
oldArray[key]['result'] = value;
this.setState({dropdown:oldArray}, function(){
console.log(this.state.dropdown);
//console.log(this.state.dropdown.length)
})
}
removeRow = (e, key) => {
e.preventDefault();
let oldArray = JSON.parse(JSON.stringify(this.state.dropdown));
oldArray.slice();
oldArray.splice(key, 1);
for (let i=0; i<oldArray.length; i++){
if (i==0){
oldArray[i]['first'] = 'true';
}
if (oldArray.length==1){
oldArray[i]['hideAdd'] = 'false';
}else{
oldArray[i]['hideAdd'] = 'true';
if (i == oldArray.length-1){
oldArray[i]['hideAdd'] = 'false';
}
}
}
this.setState({dropdown:oldArray}, function(){
console.log(this.state.dropdown);
//console.log(oldArray);
//console.log(oldArray.length);
})
}
render() {
return (
<Grid.Column>
<Grid style={comStyles().gridWidth}>
<Grid.Row>
<Grid.Column width={4} textAlign='left' style={comStyles().lineHeight}>Then</Grid.Column>
<Grid.Column width={12}>
{
this.state.dropdown.map((item, index) => (
<RulesThenDropdown default={item.result} onChange={this.onChange} add={this.addRow} remove={this.removeRow} id={index} key={index} hideAdd={item.hideAdd} first={item.first} />
))
}
</Grid.Column>
</Grid.Row>
</Grid>
</Grid.Column>
)
}
而以下是从子组件的代码
render() {
const Options = thenOptions;
let extra = "";
const removeBtn = <button onClick={(e,m)=>this.props.remove(e,this.props.id)} className="circular ui icon button"><i className="icon minus"></i></button>
const addBtn = <button onClick={(e,m)=>this.props.add(e,this.props.id)} className="circular ui icon button"><i className="icon plus"></i></button>
if(this.props.first==="false"){
if(this.props.hideAdd=="true"){
extra = removeBtn;
}else{
extra = <div>{addBtn}{removeBtn}</div>;
}
}else if(this.props.first==="true"){
if(this.props.hideAdd!="true"){
extra = addBtn;
}else{
extra = removeBtn;
}
}
return (
<div style={comStyles().buttonsMainWrapper}>
<Form.Dropdown
placeholder='Then'
fluid
selection
options={Options}
defaultValue = {this.props.result}
onChange={(e,{ value })=>this.props.onChange(this.props.id, value)}
/>
<div style={comStyles().buttonsGroup}>
{
extra
}
</div>
</div>
)
}
问题是你'直接修改组件状态,而不是使用this.setState()更新不可变副本。
罪魁祸首是这一行:
let oldArray = this.state.dropdown;
不复制的状态,而是获得参考,所以现在既oldArray和this.state.dropdown都指向存储器中的相同的结构。
当您随后进行切片,拼接和更新oldArray时,您打破了有关状态可变性的React组件合同(请参阅https://facebook.github.io/react/docs/state-and-lifecycle.html#do-not-modify-state-directly)。
要解决这个问题,你需要深克隆this.state.dropdown
像这样:
let oldArray = JSON.parse(JSON.stringify(this.state.dropdown))
不幸的是,行为仍然是一样的:( – HUNG
)您还需要分配oldArray.slice()和oldArray.splice()的结果。与array.push和array.pop不同,它们不会对数组产生副作用,而是返回一个新数组,因为您已经深度复制了oldArray,所以可以跳过slice语句并将'oldArray.splice(...)'更改为'oldArray = oldArray.splice(...)' –
对不起,我仍然有点困惑。let oldArray = JSON.parse(JSON.stringify(this.state。落下)); 我首先这样做,那么你的意思是这里的oldArray已经被深度复制了,然后我可以oldArray.splice(key,1)并继续for循环来更新某个值,最后setState?现在还是一样,我不确定我是否误解了任何步骤 – HUNG
我想添加更多@Kim Burgaard答案,那Immutable List是在state
dropdown: List([{first: "true", hideAdd: "false", id: -1}])
一个很好的替代阵列中的端部,这个问题是这行'oldArray.splice(key,1);'?您是否尝试过'console.log'并检查前后的'oldArray'值? –
嗨Firice,是的,数组似乎是正确的 – HUNG
'splice'和'delete'之间'oldArray'的结果是一样的吗?如果在'oldArray = oldArray.filter(n => n)'之后使用'delete'并清理'oldArray'' –