skip to Main Content

So after pressing <button type="submit" className="btn btn-primary">Create</button> i create a card with hero. Then .then(() => clearFields()) helps me to clear input fields because сlicking the Сreate button again returns a blank card. That is, I see that the card was cleared of information correctly. But visually, the fields remain filled in.

How do I make the input fields clear after pressing <button type="submit" className="btn btn-primary">Create</button>?

import { useState, useEffect } from "react";
import { v4 as uuidv4 } from 'uuid';
import { useDispatch } from 'react-redux';
import { heroCreate } from '../../actions';
import { useHttp } from '../../hooks/http.hook';

const HeroesAddForm = () => {
    const [name, setName] = useState('');
    const [description, setDescription] = useState('');
    const [element, setElement] = useState('');
    const {request} = useHttp();

    const dispatch = useDispatch();

    const clearFields = () => {
        setName('');
        setDescription('');
        setElement('');
    }
    const handleSubmit = (event) => {
        event.preventDefault();

        const newHero = {
            id: uuidv4(),
            name: name,
            description: description,
            element: element
        }
        request("http://localhost:3001/heroes", "POST", JSON.stringify(newHero))
        .then(dispatch(heroCreate(newHero)))
        .then(() => clearFields())
        .catch(err => console.log(err));   
        
    }
    return (
        <form className="border p-4 shadow-lg rounded" onSubmit={handleSubmit}>
            <div className="mb-3">
                <label htmlFor="name" className="form-label fs-4">Name of new hero</label>
                <input
                    required
                    type="text"
                    name="name"
                    className="form-control"
                    // id="name" 
                    onChange={event => setName(event.target.value)}
                    placeholder="What is your name?" />
            </div>

            <div className="mb-3">
                <label htmlFor="text" className="form-label fs-4">Description</label>
                <textarea
                    required
                    name="text"
                    className="form-control"
                    // id="text" 
                    placeholder="Tell us something about your hero"
                    onChange={event => setDescription(event.target.value)}
                    style={{ "height": '130px' }} />
            </div>

            <div className="mb-3">
                <label htmlFor="element" className="form-label">Choose hero element</label>
                <select
                    required
                    className="form-select"
                    id="element"
                    onChange={event => setElement(event.target.value)}
                    name="element">
                    <option >I have the element of...</option>
                    <option value="fire">Fire</option>
                    <option value="water">Water</option>
                    <option value="wind">Wind</option>
                    <option value="earth">Earth</option>
                </select>
            </div>

            <button type="submit" className="btn btn-primary">Create</button>
        </form>
    )
}

export default HeroesAddForm;

I wrote the code this way because I thought that .then(() => clearFields()) would clear the fields after the query is executed and the action creator is dispatched.

2

Answers


  1. You can try this:

    const handleSubmit = async (e) => {
      e.preventDefault();
    
      // Perform your post request here, e.g., using fetch or axios
    
      try {
        // Assuming a successful post request
        await postData(formData);
    
        // Clear form fields after successful post
        setFormData({
          fieldName1: '',
          fieldName2: '',
        });
      } catch (error) {
        console.error('Error submitting form:', error);
      }
    };
    
    Login or Signup to reply.
  2. Issue

    Sure, the clearFields handler resets the local name, description, and element state values, but since your form fields are not fully controlled they don’t actually update until you manually edit the inputs.

    There is also a minor issue in the PUT request response processing calling the dispatch immediately instead of after the request resolves.

    Solution

    You have 2 trivial options:

    Fully Controlled Inputs

    Fully controlled inputs use React state and pass both a value and onChange handler to the inputs. In other words, the value is controlled by the state.

    const HeroesAddForm = () => {
      const [name, setName] = useState("");
      const [description, setDescription] = useState("");
      const [element, setElement] = useState("");
      const { request } = useHttp();
    
      const dispatch = useDispatch();
    
      const clearFields = () => {
        setName("");
        setDescription("");
        setElement("");
      };
    
      const handleSubmit = (event) => {
        event.preventDefault();
    
        const newHero = {
          id: uuidv4(),
          name,
          description,
          element
        };
    
        request("http://localhost:3001/heroes", "POST", JSON.stringify(newHero))
          .then(() => dispatch(heroCreate(newHero))) // <-- arrow function call dispatch
          .then(clearFields)
          .catch(console.log);
      };
    
      return (
        <form className="border p-4 shadow-lg rounded" onSubmit={handleSubmit}>
          <div className="mb-3">
            <label htmlFor="name" className="form-label fs-4">
              Name of new hero
            </label>
            <input
              required
              type="text"
              name="name"
              className="form-control"
              onChange={(event) => setName(event.target.value)}
              value={name} // <-- provide value
              placeholder="What is your name?"
            />
          </div>
    
          <div className="mb-3">
            <label htmlFor="text" className="form-label fs-4">
              Description
            </label>
            <textarea
              required
              name="description"
              className="form-control"
              placeholder="Tell us something about your hero"
              onChange={(event) => setDescription(event.target.value)}
              value={description} // <-- provide value
              style={{ height: "130px" }}
            />
          </div>
    
          <div className="mb-3">
            <label htmlFor="element" className="form-label">
              Choose hero element
            </label>
            <select
              required
              className="form-select"
              id="element"
              onChange={(event) => setElement(event.target.value)}
              value={element} // <-- provide value
              name="element"
            >
              <option disabled value="">
                I have the element of...
              </option>
              <option value="fire">Fire</option>
              <option value="water">Water</option>
              <option value="wind">Wind</option>
              <option value="earth">Earth</option>
            </select>
          </div>
    
          <button type="submit" className="btn btn-primary">
            Create
          </button>
        </form>
      );
    };
    

    Fully Un-controlled Inputs

    Fully uncontrolled inputs do not use React state and pass neither value or onChange handlers to the inputs. Use the form element’s onSubmit handler to access the form field values and reset the form.

    const HeroesAddForm = () => {
      const { request } = useHttp();
    
      const dispatch = useDispatch();
    
      const handleSubmit = (event) => {
        event.preventDefault();
    
        const { description, element, name } = event.target;
    
        const newHero = {
          id: uuidv4(),
          name: name.value,
          description: description.value,
          element: element.value
        };
    
        request("http://localhost:3001/heroes", "POST", JSON.stringify(newHero))
          .then(() => dispatch(heroCreate(newHero)))
          .then(() => event.target.reset())
          .catch(console.log);
      };
    
      return (
        <form className="border p-4 shadow-lg rounded" onSubmit={handleSubmit}>
          <div className="mb-3">
            <label htmlFor="name" className="form-label fs-4">
              Name of new hero
            </label>
            <input
              required
              type="text"
              name="name"
              className="form-control"
              placeholder="What is your name?"
            />
          </div>
    
          <div className="mb-3">
            <label htmlFor="text" className="form-label fs-4">
              Description
            </label>
            <textarea
              required
              name="description"
              className="form-control"
              placeholder="Tell us something about your hero"
              style={{ height: "130px" }}
            />
          </div>
    
          <div className="mb-3">
            <label htmlFor="element" className="form-label">
              Choose hero element
            </label>
            <select
              required
              className="form-select"
              id="element"
              defaultValue="" // <-- default value
              name="element"
            >
              <option disabled value="">
                I have the element of...
              </option>
              <option value="fire">Fire</option>
              <option value="water">Water</option>
              <option value="wind">Wind</option>
              <option value="earth">Earth</option>
            </select>
          </div>
    
          <button type="submit" className="btn btn-primary">
            Create
          </button>
        </form>
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search