skip to Main Content

I have seted the value inside the function using useState, in same function I have accessed the set value but it doesn’t give me the updated value. If I access the set value outside function it gives the updated value. why useState have this behavior and how I can get updated value in in same function where I set value?

export default function App() {
const [value, setValue] = useState(1);

const myFunction= ()=>{
      setValue(2);
      console.log(value) //it gives me 1, but I need 2 as I set in above line
}

//but if I access the value outside myfunction it gives 2

console.log(value) // it gives 2
return(
    ....
    ....
)
}

3

Answers


  1. When the console.log in your myFunction is called still the value=1. Even though you’ve set it before the updated value is not passed to the log. Console.log before the return runs when the setValue is called(rerender) At the time the value=2.

    You can use useRef to get updated values without rerenders. Use State values(variables) only for showing UI changes.

    export default function App() {
    const value = useRef(1);
    
    const myFunction= ()=>{
          value.current = 2;
          console.log(value.current) 
    }
    
    
    console.log(value.current)
    return(
        ....
        ....
    )
    }
    
    Login or Signup to reply.
  2. useState will change the value on the next render, not immediately. If you need to use the value in some other function either listen for value changes with an useEffect, or store the new value in another variable:

    export default function App() {
    const [value, setValue] = useState(1);
    
    const myFunction= ()=>{
      // storing value I think it happens before rerender
      const newValue = 2
      setValue(newValue)
      doOtherStuff(newValue);
      console.log(newValue);
    }
    // or listen for value changes this will be called after rerender
    useEffect(()=>{
      doOtherStuff(value);
      console.log(value);
    },[value])
    }
    
    Login or Signup to reply.
  3. Just to give a bit more explanation:

    The value returned by useState is stored as a regular variable. When you create an instance of myFunction, it gets tied to the closure of that specific render, and to that specific value variable.

    For your case, where you call setValue and then need to do something with that value, PhantomSpooks’ answer is spot on: either use a local variable to store and distribute the updated value, or move that logic to useEffect (usual useEffect caveats apply in that case; it may be asynchronous and may be executed nie times).

    The generic way to circumvent this limitation of useState is to use a ref, as Chari proposes, though not as written in the answer; you should replace state with ref, as setting the ref won’t trigger re-render.

    You may use a ref as secondary storage, like that:

    const [value, setValue] = useState(1);
    // This sets only initial value for the ref. You have to be mindful of setting it explicitly when calling seValue.
    const liveValue = useRef(value);
    
    // A tempting option might be to just add a line
    liveValue.current = value;
    // but this is quite risky and may lead to subtle bugs,
    // as the ref won't be updated immediately on setValue, leading to
    // possible race conditions.
    
    function myFunction1() {
      // Better to update it manually
      setValue(newValue);
      liveValue.current = newValue;
    }
    
    function myFunction2() {
      // This will always use the last set value of liveValue.current.
      doSomething(liveValue.current);
    }
    

    As you can see, useRef can be tricky, so it’s usually best to stick to the previous solution, either the local variable or useEffect, depending od the semantics of what you are doing.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search