Reputation: 203
After the form is submitted, the password field input is emptied, but not the email input field.
As you can see in the HandleSubmit function: ref.current.value = ""; is what I've used as an attempt to clear the input fields after form submission, but it is only working for the password input field.
I've looked at a few other answers on SO, and I've tried e.target.reset(), and I've also tried setField(""); with no luck yet yet.
import React from 'react';
import Form from 'react-bootstrap/Form';
import { Button } from 'react-bootstrap';
import { Container } from 'react-bootstrap';
import { useState } from 'react';
import { useRef } from 'react';
const allThis = () => {
const [form, setForm] = useState({})
const [errors, setErrors] = useState({})
const setField = (field, value) => {
setForm({
...form,
[field]: value
})
// Check and see if errors exist, and remove them from the error object:
if (!!errors[field]) setErrors({
...errors,
[field]: null
})
}
const ref = useRef(null); // set up empty field
const handleSubmit = (e) => {
e.preventDefault();
const newErrors = findFormErrors()
if (Object.keys(newErrors).length > 0) {
setErrors(newErrors)
} else {
alert('Thank you for your feedback!');
ref.current.value = ""; // empty the field
}
}
const findFormErrors = () => {
const { email, password } = form
const newErrors = {};
if (!email || email === '') newErrors.email = 'cannot be blank!';
/* else if (email.length > 30) newErrors.email = 'email is too long!'; */
if (!password || password === " ") newErrors.password = "cannot be blank";
return newErrors
}
return (
<Container>
<Form className="reduceForm">
<Form.Label className="contact">Contact Me</Form.Label>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control input ref={ref} type="email" placeholder="Enter email"
onChange={e => setField('email', e.target.value)}
isInvalid={!!errors.email} />
<Form.Control.Feedback type='invalid'>
{errors.email}
</Form.Control.Feedback>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control input ref={ref} type="password" placeholder="Password"
onChange={e => setField('password', e.target.value)}
isInvalid={!!errors.password} />
<Form.Control.Feedback type='invalid'>
{errors.password}
</Form.Control.Feedback>
</Form.Group>
<Button onClick={handleSubmit} variant="primary" type="submit">
Submit
</Button>
</Form>
</Container>
)
}
export default allThis
Upvotes: 2
Views: 491
Reputation: 19554
The React team recommends writing forms declaratively, using state instead of refs. You're already setting your inputs to state when they're changed, so you can solve this in an easier to maintain way by passing value props to your inputs.
import React from 'react';
import Form from 'react-bootstrap/Form';
import { Button } from 'react-bootstrap';
import { Container } from 'react-bootstrap';
import { useState } from 'react';
const initialForm = {
email: '',
password: ''
};
export default function AllThis() {
const [form, setForm] = useState(initialForm);
const [errors, setErrors] = useState({});
const setField = (field, value) => {
setForm({
...form,
[field]: value
});
// Check and see if errors exist, and remove them from the error object:
if (!!errors[field])
setErrors({
...errors,
[field]: null
});
};
const handleSubmit = e => {
e.preventDefault();
const newErrors = findFormErrors();
if (Object.keys(newErrors).length > 0) {
setErrors(newErrors);
} else {
alert('Thank you for your feedback!');
setForm(initialForm);
}
};
const findFormErrors = () => {
const { email, password } = form;
const newErrors = {};
if (!email || email === '') newErrors.email = 'cannot be blank!';
/* else if (email.length > 30) newErrors.email = 'email is too long!'; */
if (!password || password === ' ') newErrors.password = 'cannot be blank';
return newErrors;
};
return (
<Container>
<Form className="reduceForm">
<Form.Label className="contact">Contact Me</Form.Label>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control
input
type="email"
placeholder="Enter email"
value={form.email}
onChange={e => setField('email', e.target.value)}
isInvalid={!!errors.email}
/>
<Form.Control.Feedback type="invalid">
{errors.email}
</Form.Control.Feedback>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
input
type="password"
placeholder="Password"
value={form.password}
onChange={e => setField('password', e.target.value)}
isInvalid={!!errors.password}
/>
<Form.Control.Feedback type="invalid">
{errors.password}
</Form.Control.Feedback>
</Form.Group>
<Button onClick={handleSubmit} variant="primary" type="submit">
Submit
</Button>
</Form>
</Container>
);
}
Upvotes: 1
Reputation: 79
You have to declare different variable for email and password. I prefer just using useState.
const [email, setEmail] = useState("");
const [password, setPassword] = useState("")
// Input
<Form.Control input value={email} type="email" placeholder="Enter email"
onChange={e => setEmail(e.target.value}
isInvalid={!!errors.email} />
<Form.Control input value={password} type="password" placeholder="Password"
onChange={e => setPassword(e.target.value}
isInvalid={!!errors.password} />
// handleSubmit
setEmail("");
setPassword("");
Upvotes: 1
Reputation: 309
you are setting one ref to two different fields. Therefore only the last one is being retained i.e. password one (and email field's ref is being overwritten) use 2 different refs for them. Of if possible use ref to your form if react-bootstrap/form supports it.
Upvotes: 1