Reputation: 738
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]'
}
]
};
Upvotes: 0
Views: 294
Reputation: 399
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!
Upvotes: 0
Reputation: 2259
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>
);
}
}
Upvotes: 1