动态添加/删除行不按预期工作

时间:2017-08-09 05:10:19

标签: reactjs

我想通过点击添加/删除按钮来添加/删除行的表单。我现在的问题是,删除按钮总是只删除最后一行,而不是删除按钮所在的行。当我使用数组删除操作符时,它可以删除所需的行。然而,这个方法并没有真正删除数组中的对象,可能我很难在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>
    )
}

2 个答案:

答案 0 :(得分:1)

问题是您是直接修改组件状态而不是使用this.setState()更新不可变副本。

罪魁祸首就是这条线:

let oldArray = this.state.dropdown;

它不会复制状态而是获取引用,所以现在oldArray和this.state.dropdown都指向内存中的相同结构。

当你随后切片,拼接和更新oldArray时,你违反了React组件关于状态可变性的合同(参见Object.values)。

要解决此问题,您需要像这样深度克隆this.state.dropdown

let oldArray = JSON.parse(JSON.stringify(this.state.dropdown))

(详见https://facebook.github.io/react/docs/state-and-lifecycle.html#do-not-modify-state-directly

答案 1 :(得分:1)

我想在@Kim Burgaard的答案中添加更多内容,Immutable Liststate

中数组的良好替代品

dropdown: List([{first: "true", hideAdd: "false", id: -1}])