React.js-动态添加,删除数组

时间:2018-07-17 11:55:51

标签: javascript reactjs

我有一个接受输入并将其添加到列表并显示它们的组件:

import React, {Component} from 'react'
import {
    Form,
    Col,
    Label,
    FormGroup,
    Button,
    Alert,
    Input,
    Row,
} from 'reactstrap'

export default class NewSubreddit extends Component {
    constructor(props) {
        super(props)
        this.state = {rules: []}
    }

    addRule() {
        const rule = document.getElementById('new-rule').value
        if(rule) {
            this.setState(prev => ({
                rules: prev.rules.concat(rule),
            }))
        }
        console.log(this.state)
    }

    deleteRule(e) {
        e.preventDefault()
        console.log(e.target)
        // this.setState(prev => ({

        // }))
    }

    render() {
        return (
            <React.Fragment>
                <Form>
                    <FormGroup row>
                        <Label sm={2}>Rules</Label>
                        <Col sm={10}>
                            <Row>
                                <Col>
                                    <Input id='new-rule' type='text' placeholder='Add a rule that members of this community should follow!'/>
                                </Col>
                                <Col>
                                    <Button onClick={() => this.addRule()}>ADD RULE</Button>
                                </Col>
                            </Row>
                        </Col>
                    </FormGroup>
                    <FormGroup row>
                        <Col>
                            {this.state.rules.map((rule) => 
                                <Alert key={rule} isOpen={true} toggle={this.deleteRule}>{rule}</Alert>
                            )}
                        </Col>
                    </FormGroup>
                </Form>   
            </React.Fragment>
        )
    }
}

因此,我能够将规则添加到rules中存在的数组state中。

在这里我需要做两件事:

  • 限制仅创建固定数量的规则(例如4)。
  • 通过切换警报来删除规则。

我尝试通过尝试访问deleteRuleevent.target.value函数中进行删除,但它是undefined

4 个答案:

答案 0 :(得分:2)

您可以通过以下方法删除特定元素:

  deleteRule = (idx) => () => {
    this.setState({
        rules: this
            .state
            .rules
            .filter((s, sidx) => idx !== sidx)
    });
}

您必须将函数调用为:

     <Col>
        {this.state.rules.map((rule,idx) => 
        <Alert key={rule} isOpen={true} toggle={this.deleteRule(idx)}>{rule} 
        </Alert>
         )}
      </Col>

希望获得帮助

答案 1 :(得分:1)

您可以创建一个内联函数,并将规则在数组中的索引传递到deleteRule而不是事件中,然后将该规则从您的状态中删除。

当您的状态中有4条或更多规则时,您也可以隐藏添加按钮。

示例

class NewSubreddit extends Component {

  // ...

  deleteRule(ruleIndex) {
    this.setState(previousState => {
      const rules = [...previousState.rules];
      rules.splice(ruleIndex, 1);
      return { rules };
    });
  }

  render() {
    return (
      <React.Fragment>
        <Form>
          <FormGroup row>
            <Label sm={2}>Rules</Label>
            <Col sm={10}>
              <Row>
                <Col>
                  <Input
                    id="new-rule"
                    type="text"
                    placeholder="Add a rule that members of this community should follow!"
                  />
                </Col>
                <Col>
                  {this.state.rules.length < 4 && (
                    <Button onClick={() => this.addRule()}>ADD RULE</Button>
                  )}
                </Col>
              </Row>
            </Col>
          </FormGroup>
          <FormGroup row>
            <Col>
              {this.state.rules.map((rule, index) => (
                <Alert
                  key={rule}
                  isOpen={true}
                  toggle={() => this.deleteRule(index)}
                >
                  {rule}
                </Alert>
              ))}
            </Col>
          </FormGroup>
        </Form>
      </React.Fragment>
    );
  }
}

答案 2 :(得分:1)

您可以创建具有最大规则数的const并更新您的addRule函数

您可以在构造函数中添加

this.maxNumberOfRules = 4;

然后更新

addRule() {
    const rule = document.getElementById('new-rule').value
    if(!rule || this.state.rules.length === this.maxNumberOfRules) {
        return null;
    }
    this.setState({rules: [...this.state.rules, rule]})
}

[... this.state.rules,rule]创建一个包含所有项和新项的新数组。 然后,您可以传递要删除的规则或规则索引

{this.state.rules.map((rule, index) => 
    <Alert key={rule} isOpen={true} toggle={(e) => this.deleteRule(e, index)}>{rule}</Alert>
 )}

并更改

deleteRule(e, indexForDelete) {
    e.preventDefault()
    console.log(index)
    this.setState({rules: this.state.rules.filter((rule, ruleIndex) => ruleIndex !== indexForDelete)})
}

filter()方法创建一个数组,其中包含所有通过测试的数组元素(作为函数提供)。

答案 3 :(得分:0)

您正在将删除功能添加到关闭按钮,但它没有任何值。您需要为“ Col”添加click事件,否则您可以将规则作为参数传递。

<Col>
  {this.state.rules.map((rule) => 
    <Alert key={rule} isOpen={true} toggle={() => this.deleteRule(rule)}>{rule}</Alert>
  )}

deleteRule(rule) {
    console.log(rule);
    // make a separate copy of the array
    var array = [...this.state.rules]; 
    var index = array.indexOf(rule);
    array.splice(index, 1);
    this.setState({rules: array});
}

我用stackblitz的代码创建了一个简单的堆栈应用,请看一下。

https://stackblitz.com/edit/react-eqv744