0

I want to validate input before submitting. But something went wrong, every time submit() run :((

const [value, setValue] = React.useState("");
const [error, setError] = React.useState("");
const validate = () => {
  value.length>5?setError("Some errors"):setError("");
}
const submit = () => {do something...}
...
<input onChange={e => setValue(e.target.value)} />

<Button  onClick={() => {
  validate();
  if(!error.length) submit()
}> Submit </Button>

hqtrung
  • 42
  • 4
  • setError is async and the new value of error will not be updated until rerender. Maybe change validate to return a string and not update the state value, you can then setError in the button onClick as well as check it in the if statement. – Jacob Smit Oct 22 '20 at 20:49
  • How can i pass this ? – hqtrung Oct 22 '20 at 20:51
  • setError is not async. It's synchronous but the value of the original `error` variable does not change as it's already been assigned. It takes a new re-render (calling the component function again) to reassign the variable again. – Dylan Kerler Oct 22 '20 at 20:52
  • 1
    Does this answer your question? [Reactjs - Form input validation](https://stackoverflow.com/questions/41296668/reactjs-form-input-validation) – Zain ul abideen Oct 22 '20 at 21:20

1 Answers1

2

Because the error variable will only contain the new value in the next render of the component. This is due to the way useState, or rather Hooks in general work.

Instead, you'll have to return whether or not the result is valid in the validate function.

const validate = () => {
  value.length>5?setError("Some errors"):setError("");
  return value.length <= 5;
}

<Button  onClick={() => {
  const isValid = validate();
  if(isValid) submit()
}> Submit </Button>
Dylan Kerler
  • 2,007
  • 1
  • 8
  • 23