Problem when using useEffect to store app's open time into an array

Viewed 57

I am having a problem that is when I change user's open time, the app works well in the first change, but from the second change, it will clear the array that store time data and then the process will restart from the beginning. If I don't put anything in useEffect dependency, the app works correctly, but I have to reload the app every time the date is changed.

Here is the code to deal with the open time data:

    curStreakUpdate = (date: string) => {
    const nearliestDateOpen = this.currentStreak[this.currentStreak.length - 1];
    const dateNear: any = new Date(nearliestDateOpen);
    const dateNow: any = new Date(date);
    if (this.currentStreak.length === 0) {
      this.currentStreak.push(date);
      this.setLongestStreak(this.currentStreak.length);
      this.totalPrays += 1;
    } else {
      this.checkNearliestOpenDate(dateNow, dateNear, date);
    }
    console.log(this.currentStreak);
    };
    checkNearliestOpenDate = (dateNow: any, dateNear: any, date: string) => {
      if (dateNow - dateNear !== 0) {
        if (dateNow - dateNear === 86400000) {
          if (!this.currentStreak.includes(date)) {
            this.currentStreak.push(date);
            this.setLongestStreak(this.currentStreak.length);
          }
        } else {
          this.currentStreak = [];
        }
        this.totalPrays += 1;
      }
    };

-Here is where I use useEffect hook to store open time whenever user open the app:

  const {curStreakUpdate} = useStore().streakStore;
  const dt = new Date('2022-09-14').toISOString().split('T')[0];

  useEffect(() => {
    AppState.addEventListener('change', (state) => {
      if (state === 'active') {
        curStreakUpdate(dt);
        // AsyncStorage.clear();
      }
    });
  }, [dt]);

Here is the output

Array [
  "2022-09-15",
]
Array [
  "2022-09-15",
]
Array [
  "2022-09-15",
  "2022-09-16",
]
Array []
Array [
  "2022-09-16",
]
1 Answers

If I don't put anything in useEffect dependency, the app works correctly, but I have to reload the app every time the date is changed.

You don't have to reload the app with cmd-r, I should be enough when you close/terminate the app.

The operating system iOS/Android usually kill an app which is in background for longer time. So there is no need to kill the app manually in the real world for most cases.

    checkNearliestOpenDate = (dateNow: any, dateNear: any, date: string) => {
  if (dateNow - dateNear !== 0) {
    if (dateNow - dateNear === 86400000) { // I think this should be >= or <=
      if (!this.currentStreak.includes(date)) {
        this.currentStreak.push(date);
        this.setLongestStreak(this.currentStreak.length);
      }
    } else {
      this.currentStreak = [];
    }
    this.totalPrays += 1;
  }
};

Additionally you should cleanup your listener otherwise you would add another listener the view get opened. And you have to ensure you haven't already added a listener currently you would add a listener each time dt changed. I don't care if you really need the useEffect at all for what you wanna implement.

  useEffect(() => {
    const listener = AppState.addEventListener('change', (state) => {
      if (state === 'active') {
        curStreakUpdate(dt);
        // AsyncStorage.clear();
      })
    return () =>
      listener.remove()
    });
  }, [dt]);
Related