简体   繁体   English

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

[英]Delete a component from a list of component in ReactJS

I have a reactjs code adding forms on button click. 我有一个reactjs代码在单击按钮时添加表单。 Now I want to delete an individual form on remove button click in component. 现在,我想删除组件上的删除按钮单击上的单个表单。 I have remove button in Test Component. 我在“测试组件”中有“删除”按钮。 The problem I am facing when I press any remove button all forms are deleted, I just want to delete a particular form. 当我按下任何删除按钮时,所有表格都被删除时我所面临的问题是,我只想删除一个特定的表格。

App.js App.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;

Test.js Test.js

import React, { Component } from 'react';
import logo from './logo.svg';

class Test extends Component {
  Removeform()
  {
    this.props.delete_this(this.props.key); 
  }
  render() {
    return(
        <form>

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

export default Test;

Here is a probably wrong way of doing this. 这可能是错误的方法。 I've changed some names for the functions and state. 我为函数和状态更改了一些名称。 Also, you need a remove function to pass your Test component and call it with the id (here it is form prop) of your form. 另外,您需要一个remove函数来传递Test组件,并使用form的ID(此处为form prop)对其进行调用。

For the forms, I'm creating an array including numbers. 对于表单,我正在创建一个包含数字的数组。 After creating each form this number is incremented. 创建每种形式后,此数字都会增加。 Then by mapping this array I'm rendering the forms with a form prop. 然后通过映射此数组,我使用form道具渲染form To remove the form, I'm filtering the array and returning a new one without this number. 为了删除表单,我正在过滤数组并返回一个没有该数字的新数组。

Again, for my opinion this is a wrong way of doing this. 同样,我认为这是错误的做法。 Just create your forms as objects and give them unique id's. 只需将表单创建为对象并为其赋予唯一的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> 

Update 更新

Here is maybe a little bit enhanced one. 这可能是增强的一点。 Using objects for forms, keeping them by ids. 将对象用于表单,并通过id保留它们。 But, it's your code, it's your logic. 但是,这是您的代码,这是您的逻辑。 For example in this form there are only two inputs and their names are fixed as in your example. 例如,以这种形式,只有两个输入,并且它们的名称是固定的,如您的示例所示。 Do you only want two of them or do you want more? 您只想要其中两个还是想要更多? Your code, your logic. 您的代码,您的逻辑。

 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> 

There are a couple things wrong here based on the code you posted. 根据您发布的代码,这里有几处错误。

First of all, take note that nothing is actually being deleted. 首先,请注意,实际上没有任何内容被删除。 Because you are using a form tag, when you press a button things are being submitted. 因为您使用的是form标签,所以当您按下按钮时,将提交所有内容。 Which basically causes the component to refresh as consequence. 基本上,这会导致组件刷新。 To make it not do this, all you have to do as a evt.preventDefault when clicking the button. 要使其不执行此操作,请在单击按钮时将所有操作作为evt.preventDefault So in your case, the new code will look something like this: 因此,在您的情况下,新代码将如下所示:

  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>
    );
  }

Secondly, I believe that by design you aren't allowed to use key as props. 其次,我认为设计不允许您将key用作道具。 So regardless of what value you pass in, it will always be undefined . 因此,无论您传递什么值,它始终都是undefined You will have to name your key prop something else. 您将不得不将其他key道具命名。 For this example, we will just call it blah to prove that it could be anything, but key . 对于此示例,我们将其称为blah以证明它可以是任何东西,但key

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM