删除动态元素React.js

时间:2019-03-02 03:12:04

标签: javascript html reactjs

-FieldSection.js-

    import React, { Component } from 'react';
    import Field from './Field.js';

    class FieldSection extends Component{
      constructor(props){
        super(props);

        this.state ={
          numberOfFields: 1
        }
      }
      addField = () => {
        const { numberOfFields } = this.state;
        this.setState({ numberOfFields: numberOfFields + 1 }); 
     }  
      listFields = (numberOfFields) => {
        var fields = [];
        for(var i=0; i<numberOfFields; i++){
          fields.push(
            (<Field number={i} />)
          )
        }
        return fields;
      }

      render () {
        const {listFields, addField} = this;
        const {numberOfFields} = this.state;
        return (
          <div>
              <label><u>Fields</u></label>
              {listFields(numberOfFields)}
              <div id="fieldButtons">
                <button id="addField" type="button" onClick={addField}> Add Field </button>
                <button id="removeField" type="button"> Remove Field </button>
              </div>
          </div>
        )
      }
    }  

    export default FieldSection;



  -----------------Field.js-------------------
import React from 'react';

class Field extends React.Component {
  constructor(props){
    super(props);

    this.state = {
      value: 'empty',
      specVisible: 'hidden',
      display: 'none'
    };
  }
  SelectChange = (event) => {
    this.setState({value: event.target.value});
    if(event.target.value === "string" )
    {
      this.setState({specVisible: 'visible'});
      this.setState({display: 'block'});
    }
    else {
      this.setState({specVisible: 'hidden'})
      this.setState({display: 'none'})
    }
  }
  render (){
    const {SelectChange} = this;
    const {value, specVisible, display} = this.state;
    return (
      <div>
        <div>
          <label><strong>New Field </strong></label>  
          <div id="remove-" className="remove" style={{display: "inline", visibility: "hidden"}}>
           <label> --Remove </label> <input type="checkbox" id="removeBox" className="rmvCheckbox" /> 
            <br />
          </div>
          <label> Name: </label>
          <input id="name-" className="name" type="text" name="name" /> <br />
          <label> Description: </label>
          <input id="description-" className="description" name="description" /> <br />
          <label> Datatype: </label>
          <select value={value} onChange={SelectChange} id={`selectData-${this.props.number}`} className="selectData" name="selectData" /*onClick={AddListener}*/>
            <option value="empty"> </option>
            <option value="string"> String </option>
            <option value="character"> Character </option>
            <option value="timestamp"> Timestamp </option>
            <option value="integer"> Integer </option>
            <option value="long"> Long </option>
            <option value="double"> Double </option>
            <option value="boolean"> Boolean </option>
          </select> <br />
        </div>
        <div id={`specifySection-${this.props.number}`} className="specifySection" style={{visibility: specVisible, display: display}} >
          <label> Specify Length: </label>
          <input className="specifyLength" type="text" name="length"/> <br />
      </div>
    </div>
  )}
}

export default Field

我正在尝试实现一项功能,其中您单击“删除字段”按钮,然后出现所有新字段旁边的复选框列表。只要您确认删除,就会删除所有选定的元素。

很显然,我可以在numberOfFields状态中减去一个,但是我想删除特定的元素,而不仅仅是最后一个字段。

那会是什么样?

Code Result

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作。基本思想是获取需要删除的字段的所有ID,并对其进行迭代,然后删除与这些ID对应的所有组件。

Sandbox for code

  • 当调用addField的{​​{1}}时, FieldsSelection 的状态 通过添加具有唯一ID的键和 Field 来更新组件 组件及其所有道具的价值。

  • fields状态跟踪是否单击了删除字段,并且 通过传递每个 Field 组件中的remove复选框 作为道具。

  • remove状态通过fieldsToRemove道具在 每次单击“删除字段”复选框时, Field 组件。

  • 调用markFields时,它将在deleteFields上进行迭代 状态,并从fieldsToRemove中删除相应的组件 状态对象。

  • 我使用fields包为每个uuid设置唯一ID,而不是删除 通过索引,这不是一个好方法,并且与 反应。

FieldSection.js

Field

Field.js

import React, { Component } from "react";
import Field from "./Field.js";
import { v4 } from "uuid";

class FieldSection extends Component {
  constructor(props) {
    super(props);

    this.state = {
      fields: {},
      remove: false,
      fieldsToRemove: []
    };
  }
  addField = () => {
    const fields = this.state.fields;
    const id = v4();
    fields[id] = <Field key={id} id={id} mark={this.markFields} />;
    this.setState({ fields });
  };
  listFields = () => {
    var ids = Object.keys(this.state.fields);
    return ids.map(id => {
      return React.cloneElement(this.state.fields[id], {
        remove: this.state.remove
      });
    });
  };
  markFields = (checked, i) => {
    if (checked) {
      const arr = [...this.state.fieldsToRemove];
      arr.push(i);
      this.setState({ fieldsToRemove: arr });
    } else {
      const arr = this.state.fieldsToRemove.filter(x => i !== x);
      this.setState({ fieldsToRemove: arr });
    }
  };
  removeFields = () => {
    this.setState({ remove: !this.state.remove });
  };

  deleteFields = () => {
    const fields = { ...this.state.fields };

    this.state.fieldsToRemove.forEach(id => {
      delete fields[id];
    });

    this.setState({ fields, fieldsToRemove: [], remove: false });
  };

  render() {
    const { listFields, addField, removeFields, deleteFields } = this;
    const { numberOfFields, remove } = this.state;
    return (
      <div>
        <label>
          <u>Fields</u>
        </label>
        {listFields()}
        <div id="fieldButtons">
          <button id="addField" type="button" onClick={addField}>
            {" "}
            Add Field{" "}
          </button>
          <button id="removeField" type="button" onClick={removeFields}>
            {" "}
            Remove Field{" "}
          </button>
          <br />
          <button type="button" onClick={deleteFields}>
            {" "}
            Delete Fields{" "}
          </button>
        </div>
      </div>
    );
  }
}

export default FieldSection;