React - clearing an input value after form submit
I'm presented with a rather silly problem. I am in the process of creating my first React application and I have encountered a little issue, where I am not able to clear my input value, after I submit a form. A tried googling this problem, found some similar threads here, but I was not able to resolve this. I do NOT want to change the state of my component/application, just to change the value of the input to an empty string. I tried clearing the value of the input in my onHandleSubmit()
function, but I got an error:
"Cannot set property 'value' of undefined".
My SearchBar Component:
import React, { Component } from "react";
class SearchBar extends Component {
constructor(props) {
super(props);
this.state = {
city: ""
};
this.onHandleChange = this.onHandleChange.bind(this);
this.onHandleSubmit = this.onHandleSubmit.bind(this);
}
render() {
return (
<form>
<input
id="mainInput"
onChange={this.onHandleChange}
placeholder="Get current weather..."
value={this.state.city}
type="text"
/>
<button onClick={this.onHandleSubmit} type="submit">
Search!
</button>
</form>
);
}
onHandleChange(e) {
this.setState({
city: e.target.value
});
}
onHandleSubmit(e) {
e.preventDefault();
const city = this.state.city;
this.props.onSearchTermChange(city);
this.mainInput.value = "";
}
}
export default SearchBar;
Solution 1:
You are having a controlled component where input
value is determined by this.state.city
. So once you submit you have to clear your state which will clear your input automatically.
onHandleSubmit(e) {
e.preventDefault();
const city = this.state.city;
this.props.onSearchTermChange(city);
this.setState({
city: ''
});
}
Solution 2:
Since you input field is a controlled element, you cannot directly change the input field value without modifying the state.
Also in
onHandleSubmit(e) {
e.preventDefault();
const city = this.state.city;
this.props.onSearchTermChange(city);
this.mainInput.value = "";
}
this.mainInput
doesn't refer the input since mainInput is an id
, you need to specify a ref to the input
<input
ref={(ref) => this.mainInput= ref}
onChange={this.onHandleChange}
placeholder="Get current weather..."
value={this.state.city}
type="text"
/>
In you current state the best way is to clear the state to clear the input value
onHandleSubmit(e) {
e.preventDefault();
const city = this.state.city;
this.props.onSearchTermChange(city);
this.setState({city: ""});
}
However if you still for some reason want to keep the value in state even if the form is submitted, you would rather make the input uncontrolled
<input
id="mainInput"
onChange={this.onHandleChange}
placeholder="Get current weather..."
type="text"
/>
and update the value in state onChange
and onSubmit
clear the input using ref
onHandleChange(e) {
this.setState({
city: e.target.value
});
}
onHandleSubmit(e) {
e.preventDefault();
const city = this.state.city;
this.props.onSearchTermChange(city);
this.mainInput.value = "";
}
Having Said that, I don't see any point in keeping the state unchanged, so the first option should be the way to go.
Solution 3:
this.mainInput
doesn't actually point to anything. Since you are using a controlled component (i.e. the value of the input is obtained from state) you can set this.state.city
to null:
onHandleSubmit(e) {
e.preventDefault();
const city = this.state.city;
this.props.onSearchTermChange(city);
this.setState({ city: '' });
}
Solution 4:
In your onHandleSubmit
function, set your state to {city: ''}
again like this :
this.setState({ city: '' });
Solution 5:
if you want to clear the fields of a form and you are using component function not Class component you can do that it's easy let's say we have three inputs inside a form title, price, and date and we want after we get those values from the user we want clear the fields
import React, { useState } from "react";
function ClearForm() {
// our initial states
const [enteredTitle, setEnteredTitle] = useState("");
const [enteredPrice, setEnteredPrice] = useState("");
const [enteredDate, setEnteredDate] = useState("");
// this function for get our title value from the user.
function titleChangeHandler(event) {
setEnteredTitle(event.target.value);
}
// this function for get our price value from the user.
// price that we will get is string we have to convert it to number simply add + in front of the event.target.value like this +event.target.value
function priceChangeHandler(event) {
setEnteredPrice(+event.target.value);
}
// this function for get our date value from the user.
// don't forget we we will get it as string .
function dateChangeHandler(event) {
setEnteredDate(event.target.value);
}
// here we will gather our data title, price, and date
let expensesData = {
title: enteredTitle,
price: enteredPrice,
date: new Date(enteredDate), // we have to convert our date form string to date
};
// this function will clear our fields
// we will call it inside submitFormHandler
// after submit form we we will call submitFormHandler function and we will pass event as parameter to clearFields
function clearFields(event) {
// we have to convert event.target to array
// we use from method to convert event.target to array
// after that we will use forEach function to go through every input to clear it
Array.from(event.target).forEach((e) => (e.value = ""));
}
// this function to submit form
function submitFormHandler(event) {
// we don't want our page to refresh
event.preventDefault();
// print expenses data
console.log(expensesData)
// clear the fields
clearFields(event);
//update our states
// why we should update our states to empty string
// if we have not done it we clears the fields but we still have the data in our states
// if the user submit the form without any data but our states still has the previous data
//update title
setEnteredTitle("");
//update title
setEnteredPrice("");
//update title
setEnteredDate("");
}
return (
// our form
<form onSubmit={submitFormHandler}>
<label>Title</label>
<input type="text" onChange={titleChangeHandler} />
<label>Price</label>
<input
type="number"
onChange={priceChangeHandler}
/>
<label>Date</label>
<input type="date" onChange={dateChangeHandler} />
<button type="submit">submit</button>
</form>
);
}
export default ClearForm;