-1

I can't figure out why the inputElementArray.length is always 0 when called from useEffect.

function view() {
  const [inputElementArray, setInputElementArray] = useState<HTMLInputElement[]>([]);

  useEffect(() => {
    addElement();
    addElement();
  }},[])

  const addElement = () => {
    let input = document.createElement("input");
    let arrayLength = inputElementArray.length; // <-- this is 0 every time this function gets called from UseEffect() ?
    
    setInputElementArray([...inputElementArray,input] )
  }
}
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
sander
  • 1,426
  • 4
  • 19
  • 46
  • 3
    Tangential: it's almost never a good idea to mix React w/ direct DOM manipulation (and there's rarely a reason to). – Dave Newton Feb 23 '23 at 16:15
  • 1
    Setting state is asynchronous (and individual setStates may be batched). The state won't be updated by the time you try to use it. It's not clear what problem you think you're trying to solve, but it's unlikely *(but not impossible)* this is the best way. – Dave Newton Feb 23 '23 at 16:18
  • @DaveNewton I have learned my lesson, you are correct. Using useEffect() is not the correct way to do this. Instead I should use .map() to map the elements in the array and let React do the re-rendering. – sander Feb 25 '23 at 11:09

1 Answers1

0

Consider when you update state you are not able to log it instantly after you do state update(this is the default behavior of react). for example:

function updateState() {
  setInputElementArray(something);
  console.log(inputElementArray)
}

you will always logging the initial state and not the updated one. And this behavior is same for everywhere even use effect.

If you want to log your state right after it gets update you have to create a useEffect and depend it on that state like:

useEffect(() => {
 console.log(inputElementArray)
}},[inputElementArray])