0

I want to add multiple persons dynamically in my form. Like I have Person 1 username and email then when I click Add Person it should make same fields for person 2 on the same page. When I click the Submit button it should give me the object of all persons.

App.js

import './App.css';

import React, { Component } from 'react'
import PropTypes from 'prop-types'

export default class App extends Component {

  state = {
    fields:[]
  };

  addPerson() {
    this.setState({fields:[...this.state.fields, ""]})
  };

  handleChange(e, index) {
    this.state.fields[index] = e.target.value; 
    this.setState({fields: this.state.fields});
  }

  handleSubmit(e) {
    console.log(this.state,"$$")
  }

  render() {
    return (
      <div className="App">
      <header className="App-header">
      <div>
            <h1>The Form</h1>
            {
                this.state.fields.map((field, index) => {
                  return(
                    <div key={index}>
                        <input onChange={(e)=>this.handleChange(e, index)} value={field}/>
                    </div>
                )
              }
              )
            }
            <button onClick={(e) => this.addPerson(e)}>Add Person</button>
            <button onClick={(e) => this.handleSubmit(e)}>Submit</button>
        </div>
      </header>
    </div>
    )
  }
}

I want my state would be like this...

 state = {
    fields:[
      {
        id: 1,
        name: 'Max',
        email: '[email protected]'
      }
    ]
  };

Demo of my current page.

2 Answers 2

1

This is my solution codesandbox

You need to have two inputs, for email and name, and depending on which input is updated, update the value of person in array.

import React, { Component } from "react";
import "./styles.css";

export default class App extends Component {
  state = {
    fields: []
  };

  addPerson() {
    const newPerson = {
      id: Math.random(),
      name: "",
      email: ""
    };

    this.setState({ fields: [...this.state.fields, newPerson] });
  }

  handleChange(e, index) {
    const fieldsCopy = [...this.state.fields];

    fieldsCopy.forEach(item => {
      if (item.id === index) {
        item[e.target.name] = e.target.value;
      }
    });
    this.setState({ fields: fieldsCopy }, () => console.log(this.state.fields));
  }

  handleSubmit(e) {
    console.log(this.state, "$$");
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <div>
            <h1>The Form</h1>
            {this.state.fields.map(field => {
              return (
                <div key={field.id}>
                  <input
                    onChange={e => this.handleChange(e, field.id)}
                    name="name"
                  />
                  <input
                    onChange={e => this.handleChange(e, field.id)}
                    name="email"
                  />
                </div>
              );
            })}
            <button onClick={e => this.addPerson(e)}>Add Person</button>
            <button onClick={e => this.handleSubmit(e)}>Submit</button>
          </div>
        </header>
      </div>
    );
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Edited:

Here is my version of it:

import './App.css';

import React, { Component } from 'react'
import PropTypes from 'prop-types'

export default class App extends Component {

  index = 0;
  state = {
    fields: []
  };

  handleChange(e, idx) {
    const { name, value } = e.target;
    this.setState(state => {
      return state.fields[idx][name] = value;
    });
  }

  addPerson = () => {
    const person = { id: this.index, name: '', email: '' };
    this.index++;
    this.setState({ fields: [ ...this.state.fields, person ] })
  }

  handleSubmit = () => {
    console.log(this.state.fields);
  }

  render() {
    const { fields } = this.state;
    return (
      <div className="App">
      <header className="App-header">
        <div>
          <h1>The Form</h1>
            {fields.length
              ? fields.map((field, idx) => (
                <div key={idx}>
                  <label>Name:</label>
                  <input type="text" onChange={(e)=>this.handleChange(e, idx)} name="name" value={field.name}/>
                  <label>Email:</label>
                  <input type="email" onChange={(e)=>this.handleChange(e, idx)} name="email" value={field.email}/>
                </div>
                ))
              : null
            }
          <button onClick={this.handleSubmit}>Submit</button>
          <button onClick={() => this.addPerson()}>Add Person</button>
        </div>
      </header>
    </div>
    )
  }
}

If you are using the person id as unique identifier outside this component's state, I would suggest using some id generator library like uuid.

I hope this helps!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.