1

I am having some issues figuring out how I can get the state of an inputfield, and add it to an useState array.

The way this code is set up, using onChange, it will add every character I type in the textField as a new part of the array, but I dont want to set the value until the user is done typing.

What would be a simple solution to this?

My code:

const [subject, setSubject] = useState([]);`
<input type="text" placeholder={"Eks. 'some example'"} onChange={(e) => setSubject(oldArray => [...oldArray, e.target.value])}/>
4
  • 2
    You can use onBlur for loss of focus (which is when the vanilla 'change' event would usually trigger for an input, React's onChange is actually equivalent to 'input') otherwise you'll need to set your own parameters for what constitutes 'done typing' ie debounce the handler or the like. Commented May 12, 2022 at 21:03
  • How are you determining how the user has stopped typing? Anyway, use a separate state for the input, and whether you're using onBlur to determine whether the user has stopped typing like @pilchard suggests, or you use a button with an onClick, just add that input state to the the main state. Commented May 12, 2022 at 21:08
  • The only issue with setting an state directly, is that i am having an button to add more input fields, which is why im pushing all the results to an array. so for every input field dynamically created, i would need to make a new state dynamically. it might be 2 fields, it might be 100. which causes problems creating and finding that state in lets say an submit button Commented May 12, 2022 at 21:15
  • You either need to delay adding to the state (via setTimeout) if you want it to add when the user is "done typing" (not well defined), or include a different mechanism, such as when the user clicks a separate button or perhaps loses focus from the input. Commented May 12, 2022 at 21:32

2 Answers 2

2

Well, I am not confident with react yet, but unless you don't want to do some validation, why don't you use useRef hook and onBlur combination. UseRef hook basically set a reference on element and then you can use value from that reference which in your case would be textField value. OnBlur will trigger when user clicks outside of input (input lose focus) Code should look like this:

import react, {useRef, useState} from "react";

const someComponent = (props) => {
    const [subject, setSubject] = useState([]);
    const textAreaRef = useRef();

    const onBlurHandler = () => {
         setSubject((prevSubject) => [...prevSubject, textAreaRef.current.value]);
    }

    return <input type="text" placeholder={"Eks. 'some example'"} ref={textAreaRef} onBlur={onBlurHandler}/>
}

Other way would be to use debouncing with useEffet.

Sign up to request clarification or add additional context in comments.

Comments

1

this is a little something i cooked up for you... it watches the change of the input, and 1 second after the person stops typing, it will add the input value.

The main things to look at here are the useEffect() and the <input /> with the new state i made [input, setInput]. or you can play around with this here

export default function App() {

  const [subjects,setSubjects] = useState([]);
  const [input,setInput] = useState("")

  useEffect(() => {
    const timer = setTimeout(() => {
      setSubjects(old => [...old, input])
    }, 1000)

    return () => clearTimeout(timer)
  }, [input])

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <input placeholder="type here" 
      value={input}
      type="text" 
      onChange={e => setInput(e.target.value)}
      />
      {subjects.length === 0 ? 
        <h3>Nothing yet...</h3>
        :
        <h3>{subjects}</h3>
      }
    </div>
  );
}

1 Comment

if you're going for something that replaces the the state entirely and doesn't just pile the text values on top of each other, remove ...old from setSubjects((old) => [...old, input]) so you just have setSubjects(input) when setting the subjects inside of the useEffect().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.