-1

I have trouble understanding React states and useEffect in this particular example. I have 2 initial states, word which is initialized as empty string, and field that gets value from a function initField()

initField function returs concated string that is word + 'FIELD'

function initField(){
   console.log("CALLED")
    return word+ ' - '+ "FIELD"
  }

after changing states in useEffect hooks, I expected the output of the field to be "WORD - FIELD" but the output I get is only "- FIELD"

I cant understand why is that happening, can someone give deep explanation ?

This is my full code

function App() {
 
  const [word,setWord]=useState('');
  const [field,setField]=useState(initField())

  function initField(){
   console.log("CALLED")
    return word+ ' - '+ "FIELD"
  }

  useEffect(()=>{
    setWord("WORD");
    setField(initField());
  },[])  

  return (
    <div className="App">
       <h1>{field}</h1>
    </div>
  );
}
  • Does this answer your question? [Why does calling react setState method not mutate the state immediately?](https://stackoverflow.com/questions/30782948/why-does-calling-react-setstate-method-not-mutate-the-state-immediately) – possum Aug 31 '23 at 15:51
  • The values change on the next render - so functions like `useEffect()` run to completion with the old values. So initial value of `word` is `''`, then `useEffect()` runs, `setWord()` gets called **but `word` still has its old value**, *then* `setField()` gets called while `word` is still `''` – Codebling Aug 31 '23 at 15:53
  • After setWord("WORD") gets called in useEffect, component rerenders for the first time and the initField should have the word 'WORD' instead of empty string. – rlight430 Aug 31 '23 at 15:56

1 Answers1

1

When you set a state using useState during a render, the value of the state isn't updated during the same render but until the next render. Assuming in the same render

    setWord("WORD");

word isn't updated immediately after this. Therefore

    setField(initField());

will still have word -> '', and the outcome still is - FIELD

The proper way would be to initialize the value during setState --

  const [word,setWord] = useState('WORD');
Taiwei Tuan
  • 430
  • 2
  • 12
  • If I console.log(word) inside initField function, the output in the console will be empty string and then WORD – rlight430 Aug 31 '23 at 15:58
  • Not sure what you mean, but you can see the console logs here https://codesandbox.io/s/new-grass-fcs785?file=/src/App.tsx – Taiwei Tuan Aug 31 '23 at 16:04
  • Yes, I have added console log of a word insite initField function and it console logs first time "" and then the second time it logs "WORD". I dont understand why – rlight430 Sep 01 '23 at 07:08