React - clearing an input value after form submit
Asked Answered
V

13

65

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;
Vannavannatta answered 3/10, 2017 at 7:40 Comment(1)
Thanks everybody for their comments ! Silly me...it worked. I thought that if I change the state, my data would disappear from the screen (yep, that's how bad my logic worked). Thank you!Vannavannatta
V
72

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: ''
    });
}
Vesicatory answered 3/10, 2017 at 7:45 Comment(0)
H
18

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.

Hals answered 3/10, 2017 at 7:45 Comment(2)
Case where formData ,receiced in submit event is used that time ref is usefull.Jeep
which one should be used just for simple form submit, controlled or uncontrolled component ?Jeep
N
4

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: '' });
}
Noggin answered 3/10, 2017 at 7:46 Comment(0)
E
4

The simplest Solution: add an onSubmit eventListener on the Form element, and reset itself.

<form onSubmit={(ev) => ev.target.reset()} />
Embryology answered 20/3, 2023 at 14:12 Comment(0)
F
3

In your onHandleSubmit function, set your state to {city: ''} again like this :

this.setState({ city: '' });
Fujio answered 3/10, 2017 at 7:46 Comment(0)
R
1

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;

Restriction answered 27/10, 2021 at 11:7 Comment(0)
S
1

You can follow below react example to submit form and clear the form fields after submit:

import React, { useState } from "react";

function Form() {
  const [users, setUsers] = useState({ name: "", comapny: "", empid: "" });

  function handleOnchange(event) {
    setUsers({
      ...users,
      [event.target.name]: event.target.value,
    });
  }
  /** clear form fields after submit **/ 
  function handleSubmit(event) {
    event.preventDefault();
    console.log(event);
    let emptyvals = { name: "", comapny: "", empid: "" };
    setUsers(emptyvals);
  }

  return (
    <form onSubmit={(event) => handleSubmit(event)}>
      <input
        type="text"
        id="name"
        name="name"
        placeholder="Enter name"
        value={users.name}
        onChange={(e) => handleOnchange(e)}
      />
      <br />
      <input
        type="text"
        id="comapny"
        name="comapny"
        placeholder="Company"
        value={users.comapny}
        onChange={(e) => handleOnchange(e)}
      />
      <br />
      <input
        type="text"
        id="empid"
        name="empid"
        placeholder="Enter EmpID"
        value={users.empid}
        onChange={(e) => handleOnchange(e)}
      />
      <br />
      <button type="submit">Submit</button>
    </form>
  );
}

export default Form;

Thank you.

Segregationist answered 18/4, 2023 at 12:49 Comment(0)
B
0

The answers above are incorrect, they will all run weather or not the submission is successful... You need to write an error component that will receive any errors then check if there are errors in state, if there are not then clear the form....

use .then()

example:

 const onSubmit =  e => {
e.preventDefault();
const fd = new FormData();
fd.append("ticketType", ticketType);
fd.append("ticketSubject", ticketSubject);
fd.append("ticketDescription", ticketDescription);
fd.append("itHelpType", itHelpType);
fd.append("ticketPriority", ticketPriority);
fd.append("ticketAttachments", ticketAttachments);
newTicketITTicket(fd).then(()=>{
  setTicketData({
    ticketType: "IT",
    ticketSubject: "",
    ticketDescription: "",
    itHelpType: "",
    ticketPriority: ""
  })
})  

};

Borchardt answered 21/8, 2019 at 15:52 Comment(0)
W
0

This is the value that i want to clear and create it in state 1st STEP

state={
TemplateCode:"",
}

craete submitHandler function for Button or what you want 3rd STEP

submitHandler=()=>{
this.clear();//this is function i made
}

This is clear function Final STEP

clear = () =>{
  this.setState({
    TemplateCode: ""//simply you can clear Templatecode
  });
}

when click button Templatecode is clear 2nd STEP

<div class="col-md-12" align="right">
  <button id="" type="submit" class="btn btnprimary" onClick{this.submitHandler}> Save 
  </button>
</div>
Warfare answered 29/4, 2020 at 7:35 Comment(0)
R
0

clear fields using useState hook


function clearForm() {
  // our initial states
  const [enteredTitle, setEnteredTitle] = useState("");
  const [enteredAmount, setEnteredAmount] = 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 amount  value from the user.
  // amount 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 amountChangeHandler(event) {
    setEnteredAmount(+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 gother our data title, price, and date
  let expensesData = {
    title: enteredTitle,
    amount: enteredAmount,
    date: new Date(enteredDate), // we have to convert our date form string to date
  };
  
  // this function to submit form
  function submitFormHandler(event) {
    // we don't want our page to refresh
    event.preventDefault();
  // princt  expensesData
     console.log( expensesData)
    //update our states 
    //update title 
    setEnteredTitle("");//enteredTitle="";
    //update title
    setEnteredAmount("");//enteredAmount="";
    //update title
    setEnteredDate("");//enteredDate="";
  }
  return (
    // our form
    <form onSubmit={submitFormHandler}>
          <label>Title</label>
          <input
            type="text"
            // after submit our form we will clier our title field automatically
            value={enteredTitle}//enteredTitle="";
            onChange={titleChangeHandler}
          />
          <label>Amount</label>
          <input
            type="number"
           
            // after submit our form we will clier our amount field automatically 
            value={enteredAmount}//enteredAmount="";
            onChange={amountChangeHandler}
          />
       
          <label>Date</label>

          <input
            type="date"
            // after submit our form  we will clier our date field automatically 
            value={enteredDate}//enteredDate="";
            onChange={dateChangeHandler}
          />
        <button type="submit">submit</button>
    </form>
  );
}

export default clearForm;
Restriction answered 27/10, 2021 at 11:41 Comment(0)
M
0

I don't know what happens before 5 year, but now if your tag is like this. Make sure to use value attribute.

<input value={enteredValue} type= "text" onChange={goalInputChangeHandler}/>

Than you can use this trick to achieve the result

const [enteredValue, setEnteredValue] = useState('');

const goalInputChangeHandler = event => {
  setEnteredValue(event.target.value);
};

const formSubmitHandler = event => {
  event.preventDefault()
  props.onAdd(enteredValue)
  
  //by assign the empty string 
  setEnteredValue('')
};

Happy coding :)

Mistiemistime answered 20/6, 2022 at 23:1 Comment(0)
U
0

If you have a form with input and states like this

const [title,setTitle] = useState("");
const [content,setContent] = useState("");
//initialize a state with an empty array to store blogs
const [blogs,setBlogs] = useState([]);

After Clicking on submit you can

function handleSubmit(e){
     e.preventDefault();
     setBlogs({title, content})
     setBlogs( [{title, content} , ...blogs] )
     setTitle("");  // to reset title
     setContent(""); // to reset content
}

Form Code


{/* Form for to write the blog */}
        <form onSubmit={handleSubmit}>

            {/* Row component to create a row for first input field */}
            <Row label="Title">
                    <input className="input"
                           value={formData.title}
                           onChange={(e)=>setFormData({title:e.target.value,content:formData.content})}
                           placeholder="Enter the Title of the Blog here.."/>
            </Row >

            {/* Row component to create a row for Text area field */}
            <Row label="Content">
                    <textarea className="input content"
                           value={formData.content}
                           onChange={(e)=>setFormData({title:formData.title,content:e.target.value})} // we are passing both bcz
                           // we we dont then it will overwrite the pre obj so we can't get the title or content.
                           //as it is an obj we have to det both value
                            placeholder="Content of the Blog goes here.."/>
            </Row >

            {/* Button to submit the blog */}            
            <button className = "btn">ADD</button>
        </form>
                 
    </div>

    <hr/>

    {/* Section where submitted blogs will be displayed */}
    <h2> Blogs </h2>
    
    {
        blogs.map((obj,i)=>(
            <div className="blog" key={i}>
            <h3>{obj.title}</h3> 
            <p>{obj.content}</p>
            </div>
        ))
    }
    </>
    )
Undertake answered 27/6, 2023 at 18:34 Comment(0)
C
0

this.setState({ city: '' }); This one is one solution. but, Doing this is not optimal solution when you have more field.

Try react hook form or Formik

Coccyx answered 16/5 at 5:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.