State array updating on next click - reactjs

I have 3 state values: username, password and address, and corresponding 3 textboxes where I am including the values in the respective states. Now I want that on click of a submit button, these states should be added on a state array called add_data:
state:
this.state = {
uname: '',
pass: '',
address:'',
salary:'',
add_data:[]
}
inputs:
<div>
<label>username:</label>
<input type="text" noValidate name="uname" onChange={this.changeHandler} />
</div>
<div>
<label>password:</label>
<input type="password" noValidate name="pass" onChange={this.changeHandler} />
</div>
<div>
<label>address:</label>
<textarea noValidate name="address" onChange={this.changeHandler}></textarea>
</div>
<div>
<button onClick={this.submitForm}>Edit</button>
</div>
click and change functions:
changeHandler = e => {
var adddata_obj;
this.setState({ [e.target.name]: e.target.value })
}
submitForm = () => {
console.log(this.state);
this.setState({
add_data: [...this.state.add_data, { username: this.state.uname, password: this.state.pass, address: this.state.address }]
})
}
The problem is that when I click on edit button, the add_data array does not update. Instead, when I change something else on the textboxes, it shows the value od edt_data fro the last click. Please help.

Here is a complete working code example (test it here: https://codesandbox.io/embed/mq66o03r3j):
import React from "react";
import {render} from "react-dom";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
uname: "",
pass: "",
address: "",
salary: "",
add_data: []
};
}
changeHandler = e => {
this.setState({[e.target.name]: e.target.value});
};
submitForm = () => {
this.setState({
add_data: [
...this.state.add_data,
{
username: this.state.uname,
password: this.state.pass,
address: this.state.address
}
],
uname: "",
pass: "",
address: "",
salary: ""
});
};
render() {
return (
<div>
<div>
<label>username:</label>
<input
type="text"
name="uname"
onChange={this.changeHandler}
value={this.state.uname}
/>
</div>
<div>
<label>password:</label>
<input
type="password"
name="pass"
onChange={this.changeHandler}
value={this.state.pass}
/>
</div>
<div>
<label>address:</label>
<textarea
name="address"
onChange={this.changeHandler}
value={this.state.address}
/>
</div>
<div>
<button onClick={this.submitForm}>Edit</button>
</div>
<div>
<p>Saved data:</p>
<table>
<tr>
<td>User</td>
<td>Password</td>
<td>Address</td>
</tr>
{this.state.add_data.map(d => (
<tr>
<td>{d.username}</td>
<td>{d.password}</td>
<td>{d.address}</td>
</tr>
))}
</table>
</div>
</div>
);
}
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
Now you can find your mistakes by yourself. Don't hesitate to ask me, when something is unclear.

Your code works fine #user3450590, see your snippet here just with the add_data being rendered out as a list https://stackblitz.com/edit/state-array-updating-on-next-click.
The only thing I changed was where you log the state. setSet is asynchronous ( see here), you can pass it a callback as a second argument if you need to log out the changes.
As per #virtusmaior's example you also leave the original values in the state which you may want to change when you submit your form.
Also as a nice little cherry on top your submit function would benefit from destructuring. ie
submitForm = () => {
console.log(this.state);
this.setState(state => {
const { add_data, ...values } = state;
return {
add_data: [...add_data, { ...values }]
};
});
}

Related

remove the value enterd in input fild after submistion :react js [duplicate]

I have a form containing various input fields and two buttons; one for submitting and one for cancelling.
<form id="create-course-form">
<input type="text" name="course_Name" ref="fieldName">
<input type="text" name="course_org" ref="fieldOrg">
<input type="text" name="course_Number" ref="fieldNum">
<input type="submit" name="saveCourse" value="Create">
<input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse}>
</form>
What I want is to empty all inputs when the cancel button is clicked. So far I've managed to do this by using each input's ref prop.
cancelCourse(){
this.refs.fieldName.value="";
this.refs.fieldorg.value="";
this.refs.fieldNum.value="";
}
However, I want to empty the input fields without having to empty each one seperately. I want something similar to this (jQuery): $('#create-course-form input[type=text]').val('');
The answer here depends on whether or not your inputs are controlled or uncontrolled. If you are unsure or need more info on this, check out what the official docs say about controlled components and uncontrolled components. Thanks #Dan-Esparza for providing the links.
Also, please note that using string literals in ref is deprecated. Use the standard callback method instead.
Clearing a form with uncontrolled fields
You can clear the entire form rather than each form field individually.
cancelCourse = () => {
document.getElementById("create-course-form").reset();
}
render() {
return (
<form id="create-course-form">
<input />
<input />
...
<input />
</form>
);
}
If your form didn't have an id attribute you could use a ref as well:
cancelCourse = () => {
this.myFormRef.reset();
}
render() {
return (
<form ref={(el) => this.myFormRef = el;}>
<input />
<input />
...
<input />
</form>
);
}
Clearing a form with controlled fields
If you are using controlled form fields, you may have to explicitly reset each component inside your form, depending on how your values are stored in the state.
If they are declared individually, you need to reset each one explicitly:
cancelCourse = () => {
this.setState({
inputVal_1: "",
inputVal_2: "",
...
inputVal_n: "",
});
}
render() {
return (
<input value={this.state.inputVal_1} onChange={this.handleInput1Change}>
<input value={this.state.inputVal_2} onChange={this.handleInput2Change}>
...
<input value={this.state.inputVal_n} onChange={this.handleInputnChange}>
);
}
Demo below:
class MyApp extends React.Component {
constructor() {
super();
this.state = {
inputVal_1: "",
inputVal_2: "",
inputVal_3: "",
inputVal_4: "",
inputVal_5: "",
inputVal_6: "",
inputVal_7: "",
inputVal_8: "",
inputVal_9: "",
inputVal_10: ""
};
}
handleInput1Change = (e) => {
this.setState({inputVal_1: e.target.value});
}
handleInput2Change = (e) => {
this.setState({inputVal_2: e.target.value});
}
handleInput3Change = (e) => {
this.setState({inputVal_3: e.target.value});
}
handleInput4Change = (e) => {
this.setState({inputVal_4: e.target.value});
}
handleInput5Change = (e) => {
this.setState({inputVal_5: e.target.value});
}
handleInput6Change = (e) => {
this.setState({inputVal_6: e.target.value});
}
handleInput7Change = (e) => {
this.setState({inputVal_7: e.target.value});
}
handleInput8Change = (e) => {
this.setState({inputVal_8: e.target.value});
}
handleInput9Change = (e) => {
this.setState({inputVal_9: e.target.value});
}
handleInput10Change = (e) => {
this.setState({inputVal_10: e.target.value});
}
cancelCourse = () => {
this.setState({
inputVal_1: "",
inputVal_2: "",
inputVal_3: "",
inputVal_4: "",
inputVal_5: "",
inputVal_6: "",
inputVal_7: "",
inputVal_8: "",
inputVal_9: "",
inputVal_10: ""
});
}
render() {
return (
<form>
<input value={this.state.inputVal_1} onChange={this.handleInput1Change} />
<input value={this.state.inputVal_2} onChange={this.handleInput2Change} />
<input value={this.state.inputVal_3} onChange={this.handleInput3Change} />
<input value={this.state.inputVal_4} onChange={this.handleInput4Change} />
<input value={this.state.inputVal_5} onChange={this.handleInput5Change} />
<input value={this.state.inputVal_6} onChange={this.handleInput6Change} />
<input value={this.state.inputVal_7} onChange={this.handleInput7Change} />
<input value={this.state.inputVal_8} onChange={this.handleInput8Change} />
<input value={this.state.inputVal_9} onChange={this.handleInput9Change} />
<input value={this.state.inputVal_10} onChange={this.handleInput10Change} />
<input type="submit" name="saveCourse" value="Create" />
<input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse} />
</form>
);
}
}
ReactDOM.render(<MyApp />, document.getElementById("app"));
<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="app"></div>
There is a cleaner way to do this though. Rather than having n state properties and n event handlers, one for each input, with some clever coding we can reduce the code dramatically.
In the constructor we just declare an empty object, which will be used to hold input values. We use only one input handler and pass it the index of the input element we want to change the value of. This means that the value of an individual input is generated the moment we start typing into it.
To reset the form, we only need to set our input object back to being empty again.
The input value is this.state.inputVal[i]. If i doesn't exist (we haven't typed anything yet into that input) we want the value to be an empty string (instead of null).
cancelCourse = () => {
this.setState({inputVal: {}});
}
render() {
return (
<form>
{[...Array(n)].map(
(item, i) => <input value={this.state.inputVal[i] || ""} onChange={this.handleInputChange.bind(this, i)} />
)}
</form>
);
}
Demo below:
class MyApp extends React.Component {
constructor() {
super();
this.state = {
inputVal: {}
};
}
handleInputChange = (idx, {target}) => {
this.setState(({inputVal}) => {
inputVal[idx] = target.value;
return inputVal;
});
}
cancelCourse = () => {
this.setState({inputVal: {}});
}
render() {
return(
<form>
{[...Array(10)].map( //create an array with a length of 10
(item, i) => <input value={this.state.inputVal[i] || ""} onChange={this.handleInputChange.bind(this, i)} /> //bind the index to the input handler
)}
<input type="submit" name="saveCourse" value="Create" />
<input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse} />
</form>
);
}
}
ReactDOM.render(<MyApp />, document.getElementById("app"));
<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="app"></div>
Very easy:
handleSubmit(e){
e.preventDefault();
e.target.reset();
}
// If using class component
<form onSubmit={this.handleSubmit.bind(this)}>
...
</form>
// If using function component
<form onSubmit={handleSubmit}>
...
</form>
Using event.target.reset() only works for uncontrolled components, which is not recommended. For controlled components you would do something like this:
import React, { Component } from 'react'
class MyForm extends Component {
initialState = { name: '' }
state = this.initialState
handleFormReset = () => {
this.setState(() => this.initialState)
}
render() {
return (
<form onReset={this.handleFormReset}>
<div>
<label htmlFor="name">Name</label>
<input
type="text"
placeholder="Enter name"
name="name"
value={name}
onChange={this.handleInputOnChange}
/>
</div>
<div>
<input
type="submit"
value="Submit"
/>
<input
type="reset"
value="Reset"
/>
</div>
</form>
)
}
}
ContactAdd.propTypes = {}
export default MyForm
You can also do it by targeting the current input, with anything.target.reset() . This is the most easiest way!
handleSubmit(e){
e.preventDefault();
e.target.reset();
}
<form onSubmit={this.handleSubmit}>
...
</form>
Here's an update to Chris's answer above, using modern React hooks.
Same high level idea; your form can be either a Controlled or Uncontrolled component.
Uncontrolled components:
Uncontrolled components leave state management up to the browser. That means you have to ask the browser to reset the form inputs. To do that, capture the form element as a ref, and then call the submit() method on that element.
export default function Form() {
const ref = React.useRef();
function reset(ev) {
ev.preventDefault();
ref.current.reset();
}
return (
<form ref={ref}>
<label htmlFor="email">Email Address</label>
<input id="email" type="email" name="email" />
<label htmlFor="message">Message</label>
<textarea id="message" name="message" />
<button type="submit">Submit</button>
<button onClick={reset}>Reset</button>
</form>
);
}
Controlled components:
With a controlled component, you manage the state in React. That means you have to create the initial state, and update it every time an input changes. In this world, resetting the form is just a matter of setting the form state back to its initial state.
export default function Form() {
const [state, setState] = React.useState({ email: "", message: "" });
function reset(ev) {
ev.preventDefault();
setState({ email: "", message: "" });
}
return (
<form className="Form">
<label htmlFor="email">Email Address</label>
<input
id="email"
type="email"
name="email"
value={state.email}
onChange={(ev) => {
setState({ ...state, email: ev.target.value });
}}
/>
<label htmlFor="message">Message</label>
<textarea
id="message"
name="message"
value={state.message}
onChange={(ev) => {
setState({ ...state, message: ev.target.value });
}}
/>
<button type="submit">Submit</button>
<button onClick={reset}>Reset</button>
</form>
);
}
Full example at https://codesandbox.io/s/reactformreset-10cjn3
Following code should reset the form in one click.
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props);
this.handleSubmit=this.handleSubmit.bind(this);
}
handleSubmit(e){
this.refs.form.reset();
}
render(){
return(
<div>
<form onSubmit={this.handleSubmit} ref="form">
<input type="text" placeholder="First Name!" ref='firstName'/><br/<br/>
<input type="text" placeholder="Last Name!" ref='lastName'/><br/><br/>
<button type="submit" >submit</button>
</form>
</div>
}
}
To clear your form, admitted that your form's elements values are saved in your state, you can map through your state like that :
// clear all your form
Object.keys(this.state).map((key, index) => {
this.setState({[key] : ""});
});
If your form is among other fields, you can simply insert them in a particular field of the state like that:
state={
form: {
name:"",
email:""}
}
// handle set in nested objects
handleChange = (e) =>{
e.preventDefault();
const newState = Object.assign({}, this.state);
newState.form[e.target.name] = e.target.value;
this.setState(newState);
}
// submit and clear state in nested object
onSubmit = (e) =>{
e.preventDefault();
var form = Object.assign({}, this.state.form);
Object.keys(form).map((key, index) => {
form[key] = "" ;
});
this.setState({form})
}
This one works best to reset the form.
import React, { Component } from 'react'
class MyComponent extends Component {
constructor(props){
super(props)
this.state = {
inputVal: props.inputValue
}
// preserve the initial state in a new object
this.baseState = this.state ///>>>>>>>>> note this one.
}
resetForm = () => {
this.setState(this.baseState) ///>>>>>>>>> note this one.
}
submitForm = () => {
// submit the form logic
}
updateInput = val => this.setState({ inputVal: val })
render() {
return (
<form>
<input
onChange={this.updateInput}
type="text
value={this.state.inputVal} />
<button
onClick={this.resetForm}
type="button">Cancel</button>
<button
onClick={this.submitForm}
type="submit">Submit</button>
</form>
)
}
}
When the form is submitted, the 'event' will be passed as an argument to the handleSubmit method, and if that you can access the <form> element by typing event.target. then you just need to reset the form using .reset() form method.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset
handleSubmit = (event)=>{
event.preventDefault()
....
event.target.reset()
}
render() {
return (
<>
<form onSubmit={this.handleSubmit}>
<label htmlFor='movieTitle'>Title</label>
<input name='movieTitle' id='movieTitle' type='text' />
<input type='submit' value='Find Movie Info' />
</form>
</>
)
}
I don't know if this is still relevant. But when I had similar issue this is how I resolved it.
Where you need to clear an uncontrolled form you simply do this after submission.
this.<ref-name-goes-here>.setState({value: ''});
Hope this helps.
import React, { Component } from 'react'
export default class Form extends Component {
constructor(props) {
super(props)
this.formRef = React.createRef()
this.state = {
email: '',
loading: false,
eror: null
}
}
reset = () => {
this.formRef.current.reset()
}
render() {
return (
<div>
<form>
<input type="email" name="" id=""/>
<button type="submit">Submit</button>
<button onClick={()=>this.reset()}>Reset</button>
</form>
</div>
)
}
}
/*
See newState and use of it in eventSubmit() for resetting all the state.
I have tested it is working for me. Please let me know for mistakes
*/
import React from 'react';
const newState = {
fullname: '',
email: ''
}
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
fullname: ' ',
email: ' '
}
this.eventChange = this
.eventChange
.bind(this);
this.eventSubmit = this
.eventSubmit
.bind(this);
}
eventChange(event) {
const target = event.target;
const value = target.type === 'checkbox'
? target.type
: target.value;
const name = target.name;
this.setState({[name]: value})
}
eventSubmit(event) {
alert(JSON.stringify(this.state))
event.preventDefault();
this.setState({...newState});
}
render() {
return (
<div className="container">
<form className="row mt-5" onSubmit={this.eventSubmit}>
<label className="col-md-12">
Full Name
<input
type="text"
name="fullname"
id="fullname"
value={this.state.fullname}
onChange={this.eventChange}/>
</label>
<label className="col-md-12">
email
<input
type="text"
name="email"
id="email"
value={this.state.value}
onChange={this.eventChange}/>
</label>
<input type="submit" value="Submit"/>
</form>
</div>
)
}
}
export default Form;
the easiest way is doing it regularly with just HTML and using the button type "reset" there is no need to mess with anything in react at all, no state, no nothing.
import React, {useState} from 'react'
function HowReactWorks() {
return (
<div>
<form>
<div>
<label for="name">Name</label>
<input type="text" id="name" placeholder="name" />
</div>
<div>
<label for="password">Password</label>
<input type="password" id="password" placeholder="password" />
</div>
<button type="reset">Reset</button>
<button>Submit</button>
</form>
</div>
)
}
export default HowReactWorks
edited for the people that don't know how to include HTML in react
You can use this method as well
const resetData = (e) => {
e.preventDefault();
settitle("");
setdate("");
};
<input type="text" onChange={(e) => settitle(e.target.value)} value={title} />
<input type="date" onChange={(e) => setdate(e.target.value)} value={date} />
<button onClick={resetData}>Reset Data</button>
This is the solution that worked for me, in the case of parent component triggering reset of child controlled input components:
const ParentComponent = () => {
const [reset, setReset] = useState()
const submitHandler = (e) => {
e.preventDefault()
//do your stuff
setReset(Date.now()) // pass some value to trigger update
}
return (
<form onSubmit={submitHandler}>
<ChildInputComponent reset={reset} />
<ChildInputComponent reset={reset} />
</form>
)
}
const ChildInputComponent = ({reset}) => {
const [value, setValue] = useState()
useEffect(() => {
setValue('')
}, [reset])
return <input value={value} onChange={(e) => setValue(e.target.value)} />
}
Assuming you declared
const [inputs, setInputs] = useState([]);
As multiple parameters. You can actually reset the items using this syntax:
setInputs([]);
Just in case, this how you define handleChange.
You can use this form or any ways you want.
const handleChange = (event) => {
const name = event.target.name;
const email = event.target.email;
const message = event.target.message;
const value = event.target.value;
setInputs(values => ({...values, [name]: value, [email]: value, [message]: value}))
}
You can use this form as an example.
<form onSubmit={handleSubmit}>
<div className="fields">
<div className="field half">
<label for="name">Name</label>
<input value={inputs.name || ''} type="text" name="name" id="nameId" onChange={handleChange} maxLength="30" />
</div>
<div className="field half">
<label for="email">Email</label>
<input value={inputs.email || ''} type="text" name="email" id="emailId" onChange={handleChange} maxLength="40"/>
</div>
<div className="field">
<label for="message">Message</label>
<textarea value={inputs.message || ''} name="message" id="messageId" rows="6" onChange={handleChange} maxLength="400" />
</div>
</div>
<ul className="actions">
<li><input type="submit" value="Send Message" className="primary" /></li>
<li><input onClick={resetDetails} type="reset" value="Clear" /></li>
</ul>
</form>
This is just one of many ways to declare forms. Good luck!
const onReset = () => {
form.resetFields();
};
state={
name:"",
email:""
}
handalSubmit = () => {
after api call
let resetFrom = {}
fetch('url')
.then(function(response) {
if(response.success){
resetFrom{
name:"",
email:""
}
}
})
this.setState({...resetFrom})
}
Why not use HTML-controlled items such as <input type="reset">

Basic Form react

Hello I just want to make a form and my textboxes does not take my inputs and my submit works but sends no values. What am I doing wrong? I know it's a basic question but I don't know what the problem is in my code.
Key problems:
it doesn't update the state nor take my inputs.
fields editable but cant write into them
Code
import React, { Component } from "react";
class Postform extends Component {
constructor(props) {
super(props);
this.state = {
name: "",
category: "",
price: "",
};
}
changeHandler = (e) => {
this.setState = { [e.target.name]: e.target.value };
};
submitHandler = (e) => {
e.preventDefault();
console.log(this.state);
};
render() {
const { name, category, price } = this.state;
return (
<div>
<form onSubmit={this.submitHandler}>
<div>
<input
type="text"
name="name"
placeholder="Name"
value={name}
onChange={this.changeHandler}
/>
<input
type="text"
name="category"
placeholder="Category"
value={category}
onChange={this.changeHandler}
/>
<input
type="text"
name="price"
placeholder="Price"
value={price}
onChange={this.changeHandler}
/>
</div>
<button type="submit">Add product</button>
</form>
</div>
);
}
}
export default Postform;
Change this line to
changeHandler = e => {
this.setState({[e.target.name]: e.target.value });
};
Since setState is a function it is not a property !

Can't input data into form field React

Hi I am making a form can someone please tell me why i cannot seem to enter text in the input fields. I did the type "text" and i thought that usually takes care of that. Any insight would be 100% appreciated.
import React, {Component} from 'react';
class CreateExercise extends Component{
constructor(){
super()
this.onChangeUsername = this.onChangeUsername.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
username:'',
description: '',
duration: 0,
users: []
}
}
componentDidMount() {
this.setState({
users: ['test user'],
username: 'test user'
})
}
onChangeUsername(e) {
this.setState({
username: e.target.value
});
}
onChangeUsername(e) {
this.setState({
description: e.target.value
});
}
onChangeUsername(e) {
this.setState({
duration: e.target.value
});
}
onSubmit(e) {
e.preventDefault();
const exercise = ({
username: this.state.username,
description: this.state.description,
duration: this.state.duration
})
console.log(exercise)
window.location = '/';
}
render(){
return(
<div>
<h3>Create New Exercise Log</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Username: </label>
<select ref="userInput"
required
className="form-control"
value={this.state.username}
onChange={this.onChangeUsername}>
{
this.state.users.map(function(user) {
return <option
key={user}
value={user}>{user}
</option>
})
}
</select>
</div>
<div className="form-group">
<label>Description: </label>
<input type="text"
required
className="form-control"
value={this.state.description}
onChange={this.onChangeDescription}
/>
</div>
<div className="form-group">
<label>Duration (in minutes)</label>
<input
type="text"
className="form-control"
value={this.state.duration}
onChange={this.onChangeDuration}
/>
</div>
<div className="form-group">
<input type="submit" value="Create Exercise Log" className="btn btn-primary"/>
</div>
</form>
</div>
)
}
}
export default CreateExercise;
dont use {this.state} in your value fields. Theres no need for it.
also you have 3
onChangeUsername(e) {
im guessing you might want to update the other two methods
It seems like you have some missing handlers and bindings. For example, if you add the event handler onChangeDuration:
onChangeDuration(e) {
this.setState({
duration: e.target.value
});
}
and also do the binding inside the constructor method like:
this.onChangeDuration = this.onChangeDuration.bind(this);
Your duration field should be working.
You can apply the same logic to the description field as well.
Also do not forget to remove the unnecessary onChangeUsername methods. Hope that helps.

How to dynamically generate pair of input fields using reactjs

I have tried the following code to create a react form to dynamically generate input fields to enter the series of person's name one by one. But user needs to enter the first name and last name instead of just name. So that, the form needs to generate pair of dynamic input fields. I am new to react. Can anyone please give an hint on how to accomplish this.
Note : The following code has been taken from the stackoverflow answer of #Mayank Shukla at How to implement a dynamic form with controlled components in React.JS?.
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'));
Idea is, maintain an array of object in state variable. Each object will have two keys firstName and secondName (you can add more fields). Treat each object as a single unit and for all the keys render input element, and whenever user will click on add more, add one more object/entry the the array with two keys.
Working Fiddle.
Working Snippet:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
users: [{firstName: "", lastName: ""}]
};
this.handleSubmit = this.handleSubmit.bind(this);
}
addClick(){
this.setState(prevState => ({
users: [...prevState.users, { firstName: "", lastName: "" }]
}))
}
createUI(){
return this.state.users.map((el, i) => (
<div key={i}>
<input placeholder="First Name" name="firstName" value={el.firstName ||''} onChange={this.handleChange.bind(this, i)} />
<input placeholder="Last Name" name="lastName" value={el.lastName ||''} onChange={this.handleChange.bind(this, i)} />
<input type='button' value='remove' onClick={this.removeClick.bind(this, i)}/>
</div>
))
}
handleChange(i, e) {
const { name, value } = e.target;
let users = [...this.state.users];
users[i] = {...users[i], [name]: value};
this.setState({ users });
}
removeClick(i){
let users = [...this.state.users];
users.splice(i, 1);
this.setState({ users });
}
handleSubmit(event) {
alert('A name was submitted: ' + JSON.stringify(this.state.users));
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" />
Try this
state = {
number: [""],
dataArr: []
}
render() {
return (
<div>
<div onClick={()=>this.setState(prevState => ({number: [...prevState.number, ""]}))}>Add More element</div>
{this.state.number.map((e, i)=> {
return (
<input value={this.state.number[i]} onChange={(data) => this.setState({dataArr: update(this.state.dataArr, {i: {$set: data}})})} />
)
})}
</div>
)
}
You will have to handle the data inside this.state.dataArr. For instance, this.state.dataAtt[0] will contain the starting value in input field before user presses "Add More Element" button and then when user presses the same button again data will be added in this.state.dataArr[1] and so on.
You will need react-addons-update lib.

Clear and reset form input fields

I have a form containing various input fields and two buttons; one for submitting and one for cancelling.
<form id="create-course-form">
<input type="text" name="course_Name" ref="fieldName">
<input type="text" name="course_org" ref="fieldOrg">
<input type="text" name="course_Number" ref="fieldNum">
<input type="submit" name="saveCourse" value="Create">
<input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse}>
</form>
What I want is to empty all inputs when the cancel button is clicked. So far I've managed to do this by using each input's ref prop.
cancelCourse(){
this.refs.fieldName.value="";
this.refs.fieldorg.value="";
this.refs.fieldNum.value="";
}
However, I want to empty the input fields without having to empty each one seperately. I want something similar to this (jQuery): $('#create-course-form input[type=text]').val('');
The answer here depends on whether or not your inputs are controlled or uncontrolled. If you are unsure or need more info on this, check out what the official docs say about controlled components and uncontrolled components. Thanks #Dan-Esparza for providing the links.
Also, please note that using string literals in ref is deprecated. Use the standard callback method instead.
Clearing a form with uncontrolled fields
You can clear the entire form rather than each form field individually.
cancelCourse = () => {
document.getElementById("create-course-form").reset();
}
render() {
return (
<form id="create-course-form">
<input />
<input />
...
<input />
</form>
);
}
If your form didn't have an id attribute you could use a ref as well:
cancelCourse = () => {
this.myFormRef.reset();
}
render() {
return (
<form ref={(el) => this.myFormRef = el;}>
<input />
<input />
...
<input />
</form>
);
}
Clearing a form with controlled fields
If you are using controlled form fields, you may have to explicitly reset each component inside your form, depending on how your values are stored in the state.
If they are declared individually, you need to reset each one explicitly:
cancelCourse = () => {
this.setState({
inputVal_1: "",
inputVal_2: "",
...
inputVal_n: "",
});
}
render() {
return (
<input value={this.state.inputVal_1} onChange={this.handleInput1Change}>
<input value={this.state.inputVal_2} onChange={this.handleInput2Change}>
...
<input value={this.state.inputVal_n} onChange={this.handleInputnChange}>
);
}
Demo below:
class MyApp extends React.Component {
constructor() {
super();
this.state = {
inputVal_1: "",
inputVal_2: "",
inputVal_3: "",
inputVal_4: "",
inputVal_5: "",
inputVal_6: "",
inputVal_7: "",
inputVal_8: "",
inputVal_9: "",
inputVal_10: ""
};
}
handleInput1Change = (e) => {
this.setState({inputVal_1: e.target.value});
}
handleInput2Change = (e) => {
this.setState({inputVal_2: e.target.value});
}
handleInput3Change = (e) => {
this.setState({inputVal_3: e.target.value});
}
handleInput4Change = (e) => {
this.setState({inputVal_4: e.target.value});
}
handleInput5Change = (e) => {
this.setState({inputVal_5: e.target.value});
}
handleInput6Change = (e) => {
this.setState({inputVal_6: e.target.value});
}
handleInput7Change = (e) => {
this.setState({inputVal_7: e.target.value});
}
handleInput8Change = (e) => {
this.setState({inputVal_8: e.target.value});
}
handleInput9Change = (e) => {
this.setState({inputVal_9: e.target.value});
}
handleInput10Change = (e) => {
this.setState({inputVal_10: e.target.value});
}
cancelCourse = () => {
this.setState({
inputVal_1: "",
inputVal_2: "",
inputVal_3: "",
inputVal_4: "",
inputVal_5: "",
inputVal_6: "",
inputVal_7: "",
inputVal_8: "",
inputVal_9: "",
inputVal_10: ""
});
}
render() {
return (
<form>
<input value={this.state.inputVal_1} onChange={this.handleInput1Change} />
<input value={this.state.inputVal_2} onChange={this.handleInput2Change} />
<input value={this.state.inputVal_3} onChange={this.handleInput3Change} />
<input value={this.state.inputVal_4} onChange={this.handleInput4Change} />
<input value={this.state.inputVal_5} onChange={this.handleInput5Change} />
<input value={this.state.inputVal_6} onChange={this.handleInput6Change} />
<input value={this.state.inputVal_7} onChange={this.handleInput7Change} />
<input value={this.state.inputVal_8} onChange={this.handleInput8Change} />
<input value={this.state.inputVal_9} onChange={this.handleInput9Change} />
<input value={this.state.inputVal_10} onChange={this.handleInput10Change} />
<input type="submit" name="saveCourse" value="Create" />
<input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse} />
</form>
);
}
}
ReactDOM.render(<MyApp />, document.getElementById("app"));
<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="app"></div>
There is a cleaner way to do this though. Rather than having n state properties and n event handlers, one for each input, with some clever coding we can reduce the code dramatically.
In the constructor we just declare an empty object, which will be used to hold input values. We use only one input handler and pass it the index of the input element we want to change the value of. This means that the value of an individual input is generated the moment we start typing into it.
To reset the form, we only need to set our input object back to being empty again.
The input value is this.state.inputVal[i]. If i doesn't exist (we haven't typed anything yet into that input) we want the value to be an empty string (instead of null).
cancelCourse = () => {
this.setState({inputVal: {}});
}
render() {
return (
<form>
{[...Array(n)].map(
(item, i) => <input value={this.state.inputVal[i] || ""} onChange={this.handleInputChange.bind(this, i)} />
)}
</form>
);
}
Demo below:
class MyApp extends React.Component {
constructor() {
super();
this.state = {
inputVal: {}
};
}
handleInputChange = (idx, {target}) => {
this.setState(({inputVal}) => {
inputVal[idx] = target.value;
return inputVal;
});
}
cancelCourse = () => {
this.setState({inputVal: {}});
}
render() {
return(
<form>
{[...Array(10)].map( //create an array with a length of 10
(item, i) => <input value={this.state.inputVal[i] || ""} onChange={this.handleInputChange.bind(this, i)} /> //bind the index to the input handler
)}
<input type="submit" name="saveCourse" value="Create" />
<input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse} />
</form>
);
}
}
ReactDOM.render(<MyApp />, document.getElementById("app"));
<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="app"></div>
Very easy:
handleSubmit(e){
e.preventDefault();
e.target.reset();
}
// If using class component
<form onSubmit={this.handleSubmit.bind(this)}>
...
</form>
// If using function component
<form onSubmit={handleSubmit}>
...
</form>
Using event.target.reset() only works for uncontrolled components, which is not recommended. For controlled components you would do something like this:
import React, { Component } from 'react'
class MyForm extends Component {
initialState = { name: '' }
state = this.initialState
handleFormReset = () => {
this.setState(() => this.initialState)
}
render() {
return (
<form onReset={this.handleFormReset}>
<div>
<label htmlFor="name">Name</label>
<input
type="text"
placeholder="Enter name"
name="name"
value={name}
onChange={this.handleInputOnChange}
/>
</div>
<div>
<input
type="submit"
value="Submit"
/>
<input
type="reset"
value="Reset"
/>
</div>
</form>
)
}
}
ContactAdd.propTypes = {}
export default MyForm
You can also do it by targeting the current input, with anything.target.reset() . This is the most easiest way!
handleSubmit(e){
e.preventDefault();
e.target.reset();
}
<form onSubmit={this.handleSubmit}>
...
</form>
Here's an update to Chris's answer above, using modern React hooks.
Same high level idea; your form can be either a Controlled or Uncontrolled component.
Uncontrolled components:
Uncontrolled components leave state management up to the browser. That means you have to ask the browser to reset the form inputs. To do that, capture the form element as a ref, and then call the submit() method on that element.
export default function Form() {
const ref = React.useRef();
function reset(ev) {
ev.preventDefault();
ref.current.reset();
}
return (
<form ref={ref}>
<label htmlFor="email">Email Address</label>
<input id="email" type="email" name="email" />
<label htmlFor="message">Message</label>
<textarea id="message" name="message" />
<button type="submit">Submit</button>
<button onClick={reset}>Reset</button>
</form>
);
}
Controlled components:
With a controlled component, you manage the state in React. That means you have to create the initial state, and update it every time an input changes. In this world, resetting the form is just a matter of setting the form state back to its initial state.
export default function Form() {
const [state, setState] = React.useState({ email: "", message: "" });
function reset(ev) {
ev.preventDefault();
setState({ email: "", message: "" });
}
return (
<form className="Form">
<label htmlFor="email">Email Address</label>
<input
id="email"
type="email"
name="email"
value={state.email}
onChange={(ev) => {
setState({ ...state, email: ev.target.value });
}}
/>
<label htmlFor="message">Message</label>
<textarea
id="message"
name="message"
value={state.message}
onChange={(ev) => {
setState({ ...state, message: ev.target.value });
}}
/>
<button type="submit">Submit</button>
<button onClick={reset}>Reset</button>
</form>
);
}
Full example at https://codesandbox.io/s/reactformreset-10cjn3
Following code should reset the form in one click.
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props);
this.handleSubmit=this.handleSubmit.bind(this);
}
handleSubmit(e){
this.refs.form.reset();
}
render(){
return(
<div>
<form onSubmit={this.handleSubmit} ref="form">
<input type="text" placeholder="First Name!" ref='firstName'/><br/<br/>
<input type="text" placeholder="Last Name!" ref='lastName'/><br/><br/>
<button type="submit" >submit</button>
</form>
</div>
}
}
To clear your form, admitted that your form's elements values are saved in your state, you can map through your state like that :
// clear all your form
Object.keys(this.state).map((key, index) => {
this.setState({[key] : ""});
});
If your form is among other fields, you can simply insert them in a particular field of the state like that:
state={
form: {
name:"",
email:""}
}
// handle set in nested objects
handleChange = (e) =>{
e.preventDefault();
const newState = Object.assign({}, this.state);
newState.form[e.target.name] = e.target.value;
this.setState(newState);
}
// submit and clear state in nested object
onSubmit = (e) =>{
e.preventDefault();
var form = Object.assign({}, this.state.form);
Object.keys(form).map((key, index) => {
form[key] = "" ;
});
this.setState({form})
}
This one works best to reset the form.
import React, { Component } from 'react'
class MyComponent extends Component {
constructor(props){
super(props)
this.state = {
inputVal: props.inputValue
}
// preserve the initial state in a new object
this.baseState = this.state ///>>>>>>>>> note this one.
}
resetForm = () => {
this.setState(this.baseState) ///>>>>>>>>> note this one.
}
submitForm = () => {
// submit the form logic
}
updateInput = val => this.setState({ inputVal: val })
render() {
return (
<form>
<input
onChange={this.updateInput}
type="text
value={this.state.inputVal} />
<button
onClick={this.resetForm}
type="button">Cancel</button>
<button
onClick={this.submitForm}
type="submit">Submit</button>
</form>
)
}
}
When the form is submitted, the 'event' will be passed as an argument to the handleSubmit method, and if that you can access the <form> element by typing event.target. then you just need to reset the form using .reset() form method.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset
handleSubmit = (event)=>{
event.preventDefault()
....
event.target.reset()
}
render() {
return (
<>
<form onSubmit={this.handleSubmit}>
<label htmlFor='movieTitle'>Title</label>
<input name='movieTitle' id='movieTitle' type='text' />
<input type='submit' value='Find Movie Info' />
</form>
</>
)
}
I don't know if this is still relevant. But when I had similar issue this is how I resolved it.
Where you need to clear an uncontrolled form you simply do this after submission.
this.<ref-name-goes-here>.setState({value: ''});
Hope this helps.
import React, { Component } from 'react'
export default class Form extends Component {
constructor(props) {
super(props)
this.formRef = React.createRef()
this.state = {
email: '',
loading: false,
eror: null
}
}
reset = () => {
this.formRef.current.reset()
}
render() {
return (
<div>
<form>
<input type="email" name="" id=""/>
<button type="submit">Submit</button>
<button onClick={()=>this.reset()}>Reset</button>
</form>
</div>
)
}
}
/*
See newState and use of it in eventSubmit() for resetting all the state.
I have tested it is working for me. Please let me know for mistakes
*/
import React from 'react';
const newState = {
fullname: '',
email: ''
}
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
fullname: ' ',
email: ' '
}
this.eventChange = this
.eventChange
.bind(this);
this.eventSubmit = this
.eventSubmit
.bind(this);
}
eventChange(event) {
const target = event.target;
const value = target.type === 'checkbox'
? target.type
: target.value;
const name = target.name;
this.setState({[name]: value})
}
eventSubmit(event) {
alert(JSON.stringify(this.state))
event.preventDefault();
this.setState({...newState});
}
render() {
return (
<div className="container">
<form className="row mt-5" onSubmit={this.eventSubmit}>
<label className="col-md-12">
Full Name
<input
type="text"
name="fullname"
id="fullname"
value={this.state.fullname}
onChange={this.eventChange}/>
</label>
<label className="col-md-12">
email
<input
type="text"
name="email"
id="email"
value={this.state.value}
onChange={this.eventChange}/>
</label>
<input type="submit" value="Submit"/>
</form>
</div>
)
}
}
export default Form;
the easiest way is doing it regularly with just HTML and using the button type "reset" there is no need to mess with anything in react at all, no state, no nothing.
import React, {useState} from 'react'
function HowReactWorks() {
return (
<div>
<form>
<div>
<label for="name">Name</label>
<input type="text" id="name" placeholder="name" />
</div>
<div>
<label for="password">Password</label>
<input type="password" id="password" placeholder="password" />
</div>
<button type="reset">Reset</button>
<button>Submit</button>
</form>
</div>
)
}
export default HowReactWorks
edited for the people that don't know how to include HTML in react
You can use this method as well
const resetData = (e) => {
e.preventDefault();
settitle("");
setdate("");
};
<input type="text" onChange={(e) => settitle(e.target.value)} value={title} />
<input type="date" onChange={(e) => setdate(e.target.value)} value={date} />
<button onClick={resetData}>Reset Data</button>
This is the solution that worked for me, in the case of parent component triggering reset of child controlled input components:
const ParentComponent = () => {
const [reset, setReset] = useState()
const submitHandler = (e) => {
e.preventDefault()
//do your stuff
setReset(Date.now()) // pass some value to trigger update
}
return (
<form onSubmit={submitHandler}>
<ChildInputComponent reset={reset} />
<ChildInputComponent reset={reset} />
</form>
)
}
const ChildInputComponent = ({reset}) => {
const [value, setValue] = useState()
useEffect(() => {
setValue('')
}, [reset])
return <input value={value} onChange={(e) => setValue(e.target.value)} />
}
Assuming you declared
const [inputs, setInputs] = useState([]);
As multiple parameters. You can actually reset the items using this syntax:
setInputs([]);
Just in case, this how you define handleChange.
You can use this form or any ways you want.
const handleChange = (event) => {
const name = event.target.name;
const email = event.target.email;
const message = event.target.message;
const value = event.target.value;
setInputs(values => ({...values, [name]: value, [email]: value, [message]: value}))
}
You can use this form as an example.
<form onSubmit={handleSubmit}>
<div className="fields">
<div className="field half">
<label for="name">Name</label>
<input value={inputs.name || ''} type="text" name="name" id="nameId" onChange={handleChange} maxLength="30" />
</div>
<div className="field half">
<label for="email">Email</label>
<input value={inputs.email || ''} type="text" name="email" id="emailId" onChange={handleChange} maxLength="40"/>
</div>
<div className="field">
<label for="message">Message</label>
<textarea value={inputs.message || ''} name="message" id="messageId" rows="6" onChange={handleChange} maxLength="400" />
</div>
</div>
<ul className="actions">
<li><input type="submit" value="Send Message" className="primary" /></li>
<li><input onClick={resetDetails} type="reset" value="Clear" /></li>
</ul>
</form>
This is just one of many ways to declare forms. Good luck!
const onReset = () => {
form.resetFields();
};
state={
name:"",
email:""
}
handalSubmit = () => {
after api call
let resetFrom = {}
fetch('url')
.then(function(response) {
if(response.success){
resetFrom{
name:"",
email:""
}
}
})
this.setState({...resetFrom})
}
Why not use HTML-controlled items such as <input type="reset">

Resources