Очень похоже на ответ @Bernardo Siqueira, но:
- Упрощает поля для использования поля
name
в качестве id
- Показывает текущую структуру / значения
this.state.Fields
массив - Запрещает пользователю удалять поля, если есть только одно
- Добавляет параметр для отправки формы
Рабочий пример: https://codesandbox.io/s/qm96vv8z9
index.js
import map from "lodash/map";
import filter from "lodash/filter";
import React, { Component } from "react";
import { render } from "react-dom";
import FieldInput from "./FieldInput";
import "uikit/dist/css/uikit.min.css";
import "./styles.css";
class App extends Component {
state = {
fieldsCount: 1,
Fields: [
{
name: "Field0",
value: ""
}
]
};
handleChange = name => ({ target: { value } }) => {
this.setState(prevState => ({
Fields: map(
this.state.Fields,
field => (field.name === name ? { ...field, value } : field)
)
}));
};
showFieldValues = fields => {
return map(fields, ({ value }) => value);
};
handleSubmit = e => {
e.preventDefault();
alert(`Field value(s): ${this.showFieldValues(this.state.Fields)}`);
};
addField = () => {
this.setState(prevState => ({
Fields: [
...this.state.Fields,
{
name: `Field${this.state.fieldsCount}`,
value: ""
}
],
fieldsCount: this.state.fieldsCount + 1
}));
};
deleteField = name => {
this.setState(prevState => ({
Fields: filter(this.state.Fields, field => field.name !== name)
}));
};
render = () => (
<form onSubmit={this.handleSubmit} style={{ textAlign: "center" }}>
<h1>Dynamic Field Creation</h1>
<FieldInput
{...this.state}
deleteField={this.deleteField}
handleChange={this.handleChange}
/>
<button
type="button"
style={{ marginRight: 20 }}
className="uk-button uk-button-primary"
onClick={this.addField}
>
Add Field
</button>
<button type="submit" className="uk-button uk-button-secondary">
Submit
</button>
<pre style={{ textAlign: "left", height: 300, scrollY: "auto" }}>
<code>{JSON.stringify(this.state.Fields, null, 4)}
);} render (, document.getElementById ("root"));
FieldInput.js
import map from "lodash/map";
import React from "react";
export default ({ Fields, handleChange, deleteField }) =>
map(Fields, ({ name }, key) => (
<div key={name} style={{ marginBottom: 20 }}>
<input
className="uk-input"
onChange={handleChange(name)}
name={name}
placeholder="Write something..."
type="text"
value={Fields[key].value}
style={{ width: 300, marginRight: 20 }}
/>
<button
className="uk-button uk-button-danger"
style={{ display: "inline-block" }}
onClick={() => deleteField(name)}
disabled={Fields.length === 1}
>
<i className="fa fa-times" aria-hidden="true" />
</button>
</div>
));