Home > Back-end >  How to get the latest state value in event handlers in React?
How to get the latest state value in event handlers in React?

Time:10-31

Consider this sample. Let's say we have this structure and we want to check some state value in the onChange handler of an input. In this case I've used the input value to do the if check, and if the condition doesn't pass, we set up an error. However, when I type in 10 characters, the input doesn't trigger the if block right away, but on the next typing. I know that state changes are asynchronous, which is why we'd mostly use useEffect, but in this case, I cannot use it for an event handler.

So I am wondering what is the best way to handle this type of situations, when you need to check some state value inside an event handler and perform some actions based on that.

import { useState } from "react";

export default function App() {
  const [value, setValue] = useState("");
  const [error, setError] = useState(false);

  function onSubmit(event) {
    event.preventDefault();
  }

  function onChange(event) {
    if (value.length < 10) {
      setValue(event.target.value);
    } else {
      setError(true);
    }
  }

  return (
    <form onSubmit={onSubmit}>
      <input type="text" value={value} onChange={onChange} />
      {error && <h2>Error triggered</h2>}
    </form>
  );
}

CodePudding user response:

I hope this will solve your problem.

function onChange(event) {
    if (event.target.value.length >= 10) {
      setError(true);
    } else {
      setError(false);
    }
    setValue(event.target.value);
  }

CodePudding user response:

The problem with your code is that you're checking the length of the state value instead of the current value that the input field holds.

When the user types in the 10th character, the state variable value still holds 9 characters, and so the if check passes even though the length of what event.target.value returns is 10.

Change your function so:

function onChange(event) {
  const currentValue = event.target.value
  if (currentValue.length < 10) {
    setValue(currentValue);
  } else {
    setError(true);
  }
}

This also solves the problem (mentioned by @Henry Woody) of not updating the state even when the user deletes characters that exceed the limit.

  • Related