As I am looking at the examples in the reference for controlled form components
in react.js official website, I am wondering how is one supposed to implement a form
in which you would be able to remove
and add
input
elements dynamically in such a way that they are controlled components? Is this even possible?
In the examples we can see:
class NameForm extends React.Component { constructor(props) { super(props); this.state = {value: ''}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert('A name was submitted: ' + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" value={this.state.value} onChange={this.handleChange} /> </label> <input type="submit" value="Submit" /> </form> ); } }
Due to the nature of my work, I often find myself having to implement such forms. Moreover, I don't add
or remove
input
elements directly - I am managing custom components, but for the sake of simplicity here I am asking for basic form elements.
The values will be input.name and input.Create a function called handleFormChange. Assign this function to the input fields as an onChange event. This onChange event takes two parameters, index and event. Index is the index of the array and event is the data we type in the input field.
How adding/removing input elements dynamically possible?
Yes, it is possible, you can add/remove input
elements dynamically
, But for that you need to take care of few things:
1- Proper binding of events.
2- Array to store the values of each input element separately.
3- When user fill value in any input element then updating only that specific value in state.
Logic:
Maintain an array inside state, that will store the values. Use #array.map to create ui (input element) for each array values. while creating the fields, use a remove button
with each field, and pass the index of field in that function
, it will help you to identify which field you wants to delete, do the same thing for onChange
also.
Check this example:
class App extends React.Component { constructor(props) { super(props); this.state = { values: [] }; this.handleSubmit = this.handleSubmit.bind(this); } createUI(){ return this.state.values.map((el, i) => <div key={i}> <input type="text" value={el||''} onChange={this.handleChange.bind(this, i)} /> <input type='button' value='remove' onClick={this.removeClick.bind(this, i)}/> </div> ) } handleChange(i, event) { let values = [...this.state.values]; values[i] = event.target.value; this.setState({ values }); } addClick(){ this.setState(prevState => ({ values: [...prevState.values, '']})) } removeClick(i){ let values = [...this.state.values]; values.splice(i,1); this.setState({ values }); } handleSubmit(event) { alert('A name was submitted: ' + this.state.values.join(', ')); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> {this.createUI()} <input type='button' value='add more' onClick={this.addClick.bind(this)}/> <input type="submit" value="Submit" /> </form> ); } } ReactDOM.render(<App />, document.getElementById('container'));
<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='container'/>
Check the working jsfiddle
: https://jsfiddle.net/mayankshukla5031/ezdxg224/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With