0

I'm learning react native and I'm doing a small app that regists the time of sleep for each day.

I'm using the useEffect() to trigger some modifications of values showed on screen, one of those is the average time average() that I update inside that useEffect:

const [updateAction, setUpdateAction] = useState(false);

useEffect(() => {
        console.log("lenght:" + registSleep.length);
        var registed = false;
        if (!isNaN(enteredHours)) {
            for (var i = 0; i < registSleep.length; i++) {
                if (
                    registSleep[i].day === selectedDay &&
                    registSleep[i].month === selectedMonth &&
                    registSleep[i].year === selectedYear
                ) {
                    registed = true;
                    registSleep[i].hours = enteredHours;
                }
            }
            if (!registed) {
                var newReg = {
                    day: selectedDay,
                    month: selectedMonth,
                    year: selectedYear,
                    hours: enteredHours,
                };
                setNewRegist((prevReg) => [
                    ...prevReg,
                    newReg,
                ]); 
            }
            if (registSleep.length != 0) {
                average();
            }       
        }
        console.log("2. lenght:" + registSleep.length);
        setviewInfoAction(!viewInfoAction);
    }, [updateAction]);

To debug, as you can see I print to console the lenght before I add a new value to the array of regists setNewRegist(...) and as far as I know it should be printing lenght: 0 and then 2. lenght: 1 but instead it prints lenght: 0 and then 2. lenght: 0 and on the next trigger lenght: 1 and then 2. lenght: 1.

Why the array is not updating on addition?

miguel__frtt
  • 73
  • 1
  • 9

2 Answers2

2

I'm assuming setNewRegist is useState Hook, where it's value is registSleep

const [registSleep, setNewRegist] = useState([ ... ])

Two reasons why it's not working. useState Hook is asynchronous, the logic will not stop for the logic inside setState.

setNewRegist( ... update registSleep)
console.log(registSleep) // will run before setState finishes

However even it did finish in time, registSleep was already set at a fixed value, so it will not change unless the component is rerendered, which is what setState does, to trigger the component to rerender.

Caleb Taylor
  • 2,670
  • 2
  • 21
  • 31
1
//I am considering this
const [ registSleep , setNewRegist ] = useState([])

setNewRegist is async function, so next statment will execute first in your case console.log so it won't have updated registSleep .

So How to check right?

Tada.... !!! You can check each update of registSleep via useEffect like this :

useEffect(() => {
   // Here you can get updated length
   // as soon as registSleep updates
   console.log(registSleep.length); 
},[registSleep]) // <-- watch for any update on `registSleep`
Vivek Doshi
  • 56,649
  • 12
  • 110
  • 122