React Hooks - setState takes two clicks before working

567 views Asked by At

I have an array of tags that take an input and update when the user presses enter. For some reason, the user needs to press enter twice before anything happens.

const [ tags, setTags ] = useState([]);

const addTag = (inputEvent) => {
    if (inputEvent.key === 'Enter') {   
        setTags([ ...tags, inputEvent.target.value ]);
        inputEvent.target.value = '';
    }
};

return(

<input
  type="text"
  placeholder="Press enter"
  onKeyUp={(inputEvent) => addTag(inputEvent)}
/>

)

2

There are 2 answers

2
Prateek Thapa On BEST ANSWER
  1. Use the ref to access the current tag from your input field.
  2. Use form so that it is easier to add the tags and listen to Enter submit.
  3. On submit, update your tags, and reset your form using the ref.
import React from "react";

export default function App() {
  const [tags, setTags] = React.useState([]);
  const inputRef = React.useRef(null);
  const formRef = React.useRef(null);

  const addTag = (e) => {
    e.preventDefault();

    setTags([...tags, inputRef.current.value]);
    formRef.current.reset();
  };

  return (
    <div>
      <p>{tags.join(",")}</p>
      <form onSubmit={addTag} ref={formRef}>
        <input type="text" ref={inputRef} placeholder="Press enter" />
      </form>
    </div>
  );
}


Note :- It is advisable in React to use ref to access DOM elements and manipulating them.

You could check a working example here -> https://codesandbox.io/s/wispy-microservice-3j455?file=/src/App.js:0-469

1
hackape On

Need more context to be sure. But i would guess this is a classic stale state problem. Instead of setTags([ ...tags, inputEvent.target.value ]), try use the callback function signature:

setTags(tags => [ ...tags, inputEvent.target.value ])