从ReactJS中的组件列表中删除一个组件

时间:2018-08-05 13:12:26

标签: javascript reactjs

我有一个reactjs代码,可在单击按钮时添加表格。现在,我想删除组件上的删除按钮单击上的单个表单。我在“测试组件”中有“删除”按钮。当我按下任何删除按钮时,所有表格都被删除,我只想删除一个特定的表格。

App.js

var_dump($_POST["delButton"]);

Test.js

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Test from './Test.js';

class App extends Component {
  state={
    numform: 0
  }

  Addform()
  {
    this.setState({
      numform: this.state.numform + 1
    }); 
  }

  render() {
    const form = [];
    for(var i=0;i<this.state.numform;i+=1)
    {
      form.push(<Test key={i}/>);
    }
    return(
        <div className="App ">
          <div className="App-header App-intro">
            <button onClick={()=>this.Addform()}>+</button>
          </div>
            {form}
        </div>
    );
  }

}

export default App;

2 个答案:

答案 0 :(得分:1)

这可能是错误的方法。我为函数和状态更改了一些名称。此外,您还需要一个remove函数来传递Test组件,并使用表单的ID(此处为form prop)对其进行调用。

对于表格,我正在创建一个包含数字的数组。创建每种形式后,此数字都会增加。然后通过映射此数组,我使用form道具渲染表单。要删除表单,我正在过滤数组并返回一个没有该数字的新数组。

再次,我认为这是错误的做法。只需将表单创建为对象并为其赋予唯一的ID即可。

class App extends React.Component {
  state = {
    forms: [],
    lastNum: 0,
  }

  addForm = () => {
    this.setState( prevState => ( {
      forms: [ ...prevState.forms, prevState.lastNum++ ],
    } ));
  }

  removeForm = form => {
    const newForms = this.state.forms.filter( el => el !== form  );
    this.setState( { forms: newForms } );
  }

  render() {
    const forms = this.state.forms.map( form => (
      <Test key={form} form={form} removeForm={this.removeForm} />
    ));

    return (
      <div className="App ">
        <div className="App-header App-intro">
          <button onClick={this.addForm}>+</button>
        </div>
        {forms}
      </div>
    );
  }
}

const Test = ( props ) => {
  const handleRemove =  e => {
    e.preventDefault();
    props.removeForm( props.form );
  }
  return (
    <form>
      <input type="text" name="i1"></input>
      <input type="text" name="i2"></input>
      <input type="submit" value="submit"></input>
      <button value="Remove" onClick={handleRemove}>Remove</button>
    </form>
  );
}


ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

更新

这里可能是增强一点的。将对象用于表单,并通过id保留它们。但是,这是您的代码,这是您的逻辑。例如,以这种形式,只有两个输入,并且它们的名称是固定的,如您的示例所示。您只想要其中两个还是想要更多?您的代码,您的逻辑。

class App extends React.Component {
  state = {
    forms: {},
  };

  addForm = () => {
    const newForm = {
      id: guid(),
      i1: "",
      i2: "",
    }
    this.setState(prevState => ({
      forms: { ...prevState.forms, [newForm.id]: newForm },
    }));
  };

  removeForm = id => {
    const forms = { ...this.state.forms };
    delete forms[id];
    this.setState({ forms });
  };

  onChange = ( e ) => {
    const { id, name, value } = e.target;
    this.setState( prevState => ( {
      forms: { ...prevState.forms, [id]: { ...prevState.forms[id], [name]: value } }
    } ));
  };

  onSubmit = id => { 
    const { i1, i2 } = this.state.forms[id];
    alert( `Form id: ${id}, input1: ${i1}, input2: ${i2} ` );
  }

  renderForms = () => Object.keys(this.state.forms).map(key => (
    <FormItem
      key={this.state.forms[key].id}
      id={this.state.forms[key].id}
      removeForm={this.removeForm}
      onChange={this.onChange}
      onSubmit={this.onSubmit}
      />
  ));

  render() {
    return (
      <div className="App ">
        <div className="App-header App-intro">
          <button onClick={this.addForm}>+</button>
        </div>
        {this.renderForms()}
      </div>
    );
  }
}

const FormItem = (props) => {
  const { id, removeForm, onChange, onSubmit } = props;
  
  const handleRemove = () => removeForm(id);
 
  const handleSubmit = e => {
    e.preventDefault();
    onSubmit( id );
  } 

  return (
    <form onSubmit={handleSubmit}>
      <input id={id} onChange={onChange} type="text" name="i1"></input>
      <input id={id} onChange={onChange} type="text" name="i2"></input>
      <button type="submit">Submit</button>
      <button value="Remove" onClick={handleRemove}>Remove</button>
    </form>
  );
}

function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

答案 1 :(得分:0)

根据您发布的代码,这里有几处错误。

首先,请注意,实际上没有任何内容被删除。因为您使用的是form标签,所以当您按下按钮时,将提交所有内容。基本上,这会导致组件刷新。要使其不执行此操作,请在单击按钮时以evt.preventDefault的身份进行所有操作。因此,在您的情况下,新代码将如下所示:

  Removeform(evt)
  {
    evt.preventDefault()
    // Do delete related stuff
  }

...
// In the render of the same component
  render() {
    return(
        <div>

          <input type="text" name="i1"></input> 
          <input type="text" name="i2"></input>
          <input type="submit" value="submit"></input>
          <button onClick={(evt)=>this.Removeform(evt)}>Remove</button>
        </div>
    );
  }

其次,我认为从设计上不允许您使用key作为道具。因此,无论您传递什么值,它始终为undefined。 您将不得不将key道具命名为其他名称。对于此示例,我们将其命名为blah以证明它可以是任何东西,但key除外。

for(var i=0;i<this.state.numform;i+=1)
{
  form.push(<Test blah={i}/>);
}