Home > Software design >  setArray(array) not working in React UseEffect
setArray(array) not working in React UseEffect

Time:07-21

When I log array I get the correct array. But after when I try to setNewArray(array) and then log newArray it gives me an empty array.

This is for an appointment app where I want to compare available times and taken times to output an array with true if taken and false if available.

This is the piece of my code where I try to do this:

  const [value, onChange] = useState(moment().add(1, 'days')._d);
  const appointmentTimes = ['08', '09', '10', '11', '13', '14'];
  const [appointmentTaken, setAppointmentTaken] = useState([]);
  const appointments = [];
  const selectedTime = '08';

  useEffect(() => {
    const array = [];
    // Getting the taken appointments in database and storing them in an array
    const getAppointments = async () => {
      const querySnapshot = await getDocs(collection(db, 'appointments'));
      querySnapshot.forEach((doc) => {
        appointments.push(doc.id);
      });
      // Comparing the appointmentTimes and appointments
      appointmentTimes.map((time) => {
        // This pushes true to array if in database and false if not
        array.push(
          appointments.includes(
            moment(value).format('YYYY-MM-DD-HH').slice(0, -2)   time
          )
        );
      });
    };
    getAppointments();
    // This gives me an array = [true, true, true, false, true, true] which is correct 
 according to the database
    console.log(array);

    setAppointmentTaken(array);

    // This gives me an empty array
    console.log(appointmentTaken);
  }, []);

I am still learning and this is probably not good practice. Any advice if appreciated.

CodePudding user response:

Looks like you're updating the state, and then logging the state before it has time to actually update. So it is updating, it just wont be updated within that scope. You could try setting it manually,

    const [value, setValue] = useState([ 'values', 'etc' ])

and then logging it in the useEffect and it should work. Or alternatively because I assume you would want to set your state using useEffect. You could try adding an onl oad={console.log(value)}.. to one of your components to see this value once the page has loaded and the useEffect has been executed.

CodePudding user response:

The reason why you are getting an empty state when you

console.log(appointmentTaken);

is because react is picking the value of appointments taken from this code, which is an empty array

const [appointmentTaken, setAppointmentTaken] = useState([]);

Now when you run this line, it prints you the array you expected that's correct

console.log(array);

But that doesn't mean react will update the state of appointmentTaken variable immediately by running the

setAppointmentTaken(array);

React batches the update, so what happens every state has a queue to which your actions are being added and it is when the component re-executes this queue gets executed. so it is then when your state is updated and react will figure out that the state has changed so it'll trigger a re-render

Now if you want to check whether the state has changed or not, you can do a console.log(appointmentTaken) after

const [appointmentTaken, setAppointmentTaken] = useState([]);
console.log(appointmentTaken)
  • Related