react-native icon indicating copy to clipboard operation
react-native copied to clipboard

`setInterval` (and `setTimeout`) is called way more frequent than it suppose to be

Open StephenChips opened this issue 3 years ago • 3 comments

Description

I was writing a page where the app counts 1000 to 0, decreasing the value by one for every second. It should be very simple to write, but to my suprise, the number dropped crazily fast.

I tested on Snack but nothing went wrong. My testing phone is Xiaomi K40 (Android 11), and this problem does keep occuring on my phone for most of the time.

There was a time I reloaded the app, and the problem suddenly disappeared. I saved the code a copy, and I rewrited the code using hooks, but some other unrelative problems occured, so I recovered the code to the copy, then the problem was shown again.

Version

0.69.6

Output of npx react-native info

info Fetching system and libraries information...
System:
    OS: Windows 10 10.0.19043
    CPU: (6) x64 AMD Ryzen 5 3500X 6-Core Processor
   
    Memory: 6.84 GB / 15.94 GB
  Binaries:
    Node: 16.17.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 8.15.0 - C:\Program Files\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK: Not Found
    Windows SDK: Not Found
  IDEs:
    Android Studio: AI-213.7172.25.2113.9014738
    Visual Studio: 17.3.32804.467 (Visual Studio Community 2022)
  Languages:
    Java: Not Found
  npmPackages:
    @react-native-community/cli: Not Found
    react: 18.0.0 => 18.0.0
    react-native: 0.69.6 => 0.69.6
    react-native-windows: Not Found
  npmGlobalPackages:
    *react-native*: Not Found
info React Native v0.70.3 is now available (your project is running on v0.69.6).
info Changelog: https://github.com/facebook/react-native/releases/tag/v0.70.3.
info Diff: https://react-native-community.github.io/upgrade-helper/?from=0.69.6.
info To upgrade, run "react-native upgrade".

Steps to reproduce

  1. Create a expo typescript blank project
  2. Paste the example code and run expo start
  3. Scan the QR code and run the App

Snack, code example, screenshot, or link to a repository

import React from "react";
import { Text, View } from "react-native";

export default function App() {
  return (
    <CountdownAnimation
      onCountdownFinished={() => console.log("done!")}
    ></CountdownAnimation>
  );
}

interface CountdownAnimationProps {
  onCountdownFinished: () => void;
}

type CountdownAnimationState = {
  count: number;
};

export class CountdownAnimation extends React.Component<
  CountdownAnimationProps,
  CountdownAnimationState
> {
  constructor(props: CountdownAnimationProps) {
    super(props);
    this.state = { count: 1000 };
  }

  componentDidMount() {
    let timerID = setInterval(() => {
      if (this.state.count === 0) {
        clearInterval(timerID);
      } else {
        this.setState({ count: this.state.count - 1 });
      }
    }, 1000);
  }

  render() {
    return (
      <View
        style={{
          justifyContent: "center",
          alignItems: "center",
          flex: 1
        }}
      >
        <Text style={{ fontSize: 128 }}>{this.state.count} </Text>
      </View>
    );
  }
}

https://user-images.githubusercontent.com/17926083/195996343-48c18f61-731c-4ba7-95aa-83d083795803.mp4

StephenChips avatar Oct 15 '22 16:10 StephenChips

Oddly, I remove Expo Go from my App and reinstall it from Play Store, the problem is gone again. (Not sure whether it will come up later again or not).

StephenChips avatar Oct 15 '22 16:10 StephenChips

This could be related to you not clearing your setInterval when the components unmounts, which in dev mode happens a bunch of times due to Fast Refresh.

Try adding something like this to your component

componentWillUnmount() {
   clearInterval(this.timerID);
}

gabrieldonadel avatar Oct 17 '22 20:10 gabrieldonadel

@StephenChips you are not cleaning up the when the component unmounts so its to be expected to be called way to many times for example in dev when react renders double or a parent component renders or when it gets hot reload.

philipheinser avatar Oct 24 '22 14:10 philipheinser

I ran into a similar issue and cleaned up. When using 1000ms my callback function is fired every millisecond. When using 10000ms my callback is called every 10 seconds. It's very odd and there is an issue with setInterval and setTimeout with react native.

alexrindone avatar Nov 14 '22 00:11 alexrindone

I ran into a similar issue and cleaned up. When using 1000ms my callback function is fired every millisecond. When using 10000ms my callback is called every 10 seconds. It's very odd and there is an issue with setInterval and setTimeout with react native.

Seeing the same thing - a 1000ms timer on Android fires immediately, 60000ms fires in ~60s, as expected. 1000ms works fine on iOS.

DavidKnight-Bluescape avatar Feb 22 '23 22:02 DavidKnight-Bluescape

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Aug 23 '23 05:08 github-actions[bot]

This issue was closed because it has been stalled for 7 days with no activity.

github-actions[bot] avatar Sep 03 '23 05:09 github-actions[bot]

I ran into a similar issue and cleaned up. When using 1000ms my callback function is fired every millisecond. When using 10000ms my callback is called every 10 seconds. It's very odd and there is an issue with setInterval and setTimeout with react native.

Seeing the same thing - a 1000ms timer on Android fires immediately, 60000ms fires in ~60s, as expected. 1000ms works fine on iOS.

@DavidKnight-Bluescape, is this happens in a debug mode? The reason could be the differ in the time of your android device and computer. According to the note in the docs https://reactnative.dev/docs/timers

MargaritaVacheva avatar Sep 28 '23 07:09 MargaritaVacheva