javascript - 删除动态元素 Reactjs

标签 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

最佳答案

您可以按如下方式进行。基本思路是获取所有需要删除的字段的id,并对其进行迭代,删除这些id对应的所有组件。

Sandbox for code

  • addField 被调用时 fields FieldsSelection 的状态 组件通过添加具有唯一 ID 的键和 Field 来更新 组件作为它的值(value)以及所有 Prop 。

  • remove 状态跟踪如果 remove 字段被点击并且 通过传递它来切换每个 Field 组件中的删除复选框 作为 Prop 。

  • fieldsToRemove 状态通过 markFields 属性更新 每次单击删除字段复选框时,字段组件。

  • deleteFields 被调用时,它遍历 fieldsToRemove 声明并从 fields 中移除相应的组件 状态对象。

  • 我使用 uuid 包为每个 Field 提供唯一 ID,而不是删除 通过索引,这不是一个好方法,也与 key prop 冲突 使用react。

FieldSection.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;

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;
    const styles = this.props.remove
      ? { display: "inline", visibility: "visible" }
      : { display: "inline", visibility: "hidden" };
    return (
      <div>
        <div>
          <label>
            <strong>New Field </strong>
          </label>
          <div id="remove-" className="remove" style={styles}>
            <label> --Remove </label>{" "}
            <input
              type="checkbox"
              id="removeBox"
              className="rmvCheckbox"
              onChange={e => {
                this.props.mark(e.target.checked, this.props.id);
              }}
            />
            <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;

关于javascript - 删除动态元素 Reactjs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54954875/

相关文章:

javascript - 安全性:innerHTML 与 textContent 与 API

javascript - 有没有办法在 Reactjs 中设置元素的初始高度?

reactjs - 使用服务名称在 docker-compose React 容器中调用 API 到 django 容器

javascript - Phonegap 设备准备好在 iOS 中使用 Cordova 2.2.0 不触发

javascript - 无法嵌套 forEach 以在 Javascript 中工作

css - 如何更改 BootsFaces 中的对齐方式?需要导航栏的最后一个链接到右上角

html - 如何在单个表格行中将一个对象左对齐,一个对象在中心(整行)对齐?

reactjs - Create-react-app 和过时的节点版本

javascript - 具有属性的 JSX 动态标签

javascript - 如何让我的机器人提及发出该机器人命令的人