Search code examples
reactjsuse-statetsx

useState on startDate not updating the date when I use setStartDate


here is my codes

import format from "date-fns/format";
import setHours from "date-fns/setHours";
import setMinutes from "date-fns/setMinutes";

const [startDate, setStartDate] = useState<Date>(new Date());

const startTime = setHours(setMinutes(date, 0), hour);
console.log(startTime); // showing correct date and time as I set

setStartDate(startTime);
console.log(startDate); // this is showing current date and time

But when I do

console.log(startDate);

I get current date and time. However if I do

console.log(startTime);

It shows the correct date and time as I want it.

Can you please help. I am using tsx format of React. Developer is not available for another few hours and I have to deliver this quickly to my client.


Solution

  • useState is an asynchronous function. By the time you are trying to read the state, it's in execution and its value is yet to be updated. Consider the following example:

    //Defining the state
    const [startDate, setStartDate] = useState<Date>(new Date());
    
    
    const startTime = setHours(setMinutes(date, 0), hour); //Calculating new state
    console.log(startTime); // Works fine due to synchronouse behaviour
    
    setStartDate(startTime);  //Async, will wait if any other state updates are in pipeline. If not, it'll try to update asynchronously
    console.log(startDate); // By the time you reach here it's still updating and pointing to the old value.
    

    If you want to read the new value, you may consider using useEffect(fn,[]). In your case, you can read a new state as follows:

    const [startDate, setStartDate] = useState<Date>(new Date());
    
    useEffect(()=>{
        console.log(startDate); // Fires whenever startDate changes
      },[startDate])
    

    You can visit codesandbox here for a working demo. Also, you can read more about useEffect here and here[Detailed]