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
You can try this:
Issue
Sure, the
clearFields
handler resets the localname
,description
, andelement
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 therequest
resolves.Solution
You have 2 trivial options:
Fully Controlled Inputs
Fully controlled inputs use React state and pass both a
value
andonChange
handler to the inputs. In other words, the value is controlled by the state.Fully Un-controlled Inputs
Fully uncontrolled inputs do not use React state and pass neither
value
oronChange
handlers to the inputs. Use theform
element’sonSubmit
handler to access the form field values and reset the form.