Reputation: 49
const [name, setName] = useState("");
const [age, setAge] = useState("");
const initialValues = {
name: "",
age: "",
};
const [formValues, setFormValues] = useState(initialValues);
const [formErrors, setFormErrors] = useState({});
const [isSubmit, setIsSubmit] = useState(false);
const handleChange = (e) => {
const { name, value } = e.target;
setFormValues({ ...formValues, [name]: value });
};
const handleSubmit = (e) => {
setFormErrors(validate(formValues));
setIsSubmit(true);
};
const validate = (values) => {
const errors = {};
if (!values.name) {
errors.name = "Name is required";
}
if (!values.age) {
errors.age= "Age is required";
}
return errors;
};
const userCreate = async () => {
await api.post("/createuser", {
name,
age,
});
};
return (
<div class="container">
<Form
onSubmit={
Object.keys(formErrors).length === 0 && isSubmit
? userCreate
: handleSubmit
}
>
<Form.Field>
<label>Name</label>
<input
name="name"
onChange={(e) => {
setName(e.target.value);
handleChange(e);
}}
values={formValues.name}
/>
<span className="error-message">{formErrors.name}</span>
</Form.Field>
<Form.Field>
<label>Age</label>
<input
name="age"
onChange={(e) => {
setAge(e.target.value);
handleChange(e);
}}
values={formValues.age}
/>
<p className="error-message">{formErrors.age}</p>
</Form.Field>
<Button type="submit">Submit</Button>
</Form>
</div>
);
I'm trying to use axios to do POST method for creating user.
I got everything works fine but there's one small problem but I don't know how to fix.
The problem is that I always need to submit the form 2 times to make the POST request. There's nothing happen in the first submit, but it will work in the second submit.
Does anyone know what's wrong with my code?
Edited
According to @DBS solution. I'm trying to follow the steps but now the form can't submit anymore. Can someone let me know if I missed something?
const [name, setName] = useState("");
const [age, setAge] = useState("");
const initialValues = {
name: "",
age: "",
};
const [formValues, setFormValues] = useState(initialValues);
const [formErrors, setFormErrors] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const handleChange = (e) => {
const { name, value } = e.target;
setFormValues({ ...formValues, [name]: value });
};
const handleSubmit = (e) => {
if (!Object.keys(formErrors).length && !isSubmitting) {
setFormErrors(validate(formValues));
} else {
userCreate();
setisSubmitting(true);
}
};
const validate = (values) => {
const errors = {};
if (!values.name) {
errors.name = "Name is required";
}
if (!values.age) {
errors.age= "Age is required";
}
return errors;
};
const userCreate = async () => {
await api.post("/createuser", {
name,
age,
});
};
return (
<div class="container">
<Form
onSubmit={handleSubmit}
>
<Form.Field>
<label>Name</label>
<input
name="name"
onChange={(e) => {
setName(e.target.value);
handleChange(e);
}}
values={formValues.name}
/>
<span className="error-message">{formErrors.name}</span>
</Form.Field>
<Form.Field>
<label>Age</label>
<input
name="age"
onChange={(e) => {
setAge(e.target.value);
handleChange(e);
}}
values={formValues.age}
/>
<p className="error-message">{formErrors.age}</p>
<
Upvotes: 0
Views: 44
Reputation: 183
Are you using the isSubmitting
flag for something? if not below might be work for you.
If there is no error, calling the create method
const handleSubmit = (e) => {
setFormErrors(validate(formValues));
if(Object.keys(formErrors).length === 0) {
userCreate();
}
};
if isSubmitting
is used to check the submit or create in progress
const handleSubmit = (e) => {
setFormErrors(validate(formValues));
if(Object.keys(formErrors).length === 0) {
setIsSubmitting(true);
userCreate();
}
};
The flag isSubmitting
should be set as false on API is success or failed
setIsSubmitting(false)
Upvotes: 0
Reputation: 9959
The issue here is your isSubmit
, it is required to be true
for userCreate
to be called:
onSubmit={
Object.keys(formErrors).length === 0 && isSubmit
? userCreate
: handleSubmit
}
But it starts as false
:
const [isSubmit, setIsSubmit] = useState(false);
And is only ever updated when handleSubmit
is called (which, confusingly, is only called when the validation fails)
So your current code does this:
isSubmit
is false
handleSubmit
is called and isSubmit
is set to true
isSubmit
is true
it will call userCreate
To solve this, there are a few different approaches, but I would:
onSubmit={handleSubmit}
(To keep things clear)isSubmit
(Which I would probably rename to isSubmitting
for clarity, and make sure it's false) (E.g. !Object.keys(formErrors).length && !isSubmitting
)isSubmitting
as false
)userCreate
(And set isSubmitting
to true
)isSubmitting
once the call is complete.Upvotes: 2