最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - clearTimeout is not working in React Native - Stack Overflow

programmeradmin0浏览0评论

I have four screens A (HomePage), B, C, D

Each of screens have a function that will be triggered when the screen onStart or onResume, I achieve it by react-redux.

countdownToFirstScreen = () => {
    this.timeOut = setTimeout(()=> {
      clearTimeout(this.timeOut); // clearTimeout before navigate next screen
      this.props.leaveTheScreenTime(); // change for some redux store boolean
      this.props.navigation.navigate('A');
    }, 9000);    
  }

If user click <Button /> before countdown finish, I set the clearTimeout too.

<Button 
  onPress={() => { 
    clearTimeout(this.timeOut);
    this.props.navigation.navigate('nextScreen');
  }
/>

It is working when I just navigate between A and B and C.

My issue happens when I try to navigate from C to D.

C screen function countdownToFirstScreen will be triggered eventhough I click the <Button /> on C screen.

Any one knows what happened with my setTimeout and clearTimeout?

I have four screens A (HomePage), B, C, D

Each of screens have a function that will be triggered when the screen onStart or onResume, I achieve it by react-redux.

countdownToFirstScreen = () => {
    this.timeOut = setTimeout(()=> {
      clearTimeout(this.timeOut); // clearTimeout before navigate next screen
      this.props.leaveTheScreenTime(); // change for some redux store boolean
      this.props.navigation.navigate('A');
    }, 9000);    
  }

If user click <Button /> before countdown finish, I set the clearTimeout too.

<Button 
  onPress={() => { 
    clearTimeout(this.timeOut);
    this.props.navigation.navigate('nextScreen');
  }
/>

It is working when I just navigate between A and B and C.

My issue happens when I try to navigate from C to D.

C screen function countdownToFirstScreen will be triggered eventhough I click the <Button /> on C screen.

Any one knows what happened with my setTimeout and clearTimeout?

Share Improve this question edited Jan 28, 2019 at 3:07 Spencer Wieczorek 21.6k7 gold badges46 silver badges56 bronze badges asked Jan 28, 2019 at 2:51 MortonMorton 5,76023 gold badges71 silver badges127 bronze badges 5
  • Is this referencing the same object? – Spencer Wieczorek Commented Jan 28, 2019 at 3:07
  • You most likely unmount your component and when you route back you create new reference on mount and you never point to an same object again. – Jimi Pajala Commented Jan 28, 2019 at 3:09
  • Hmm... I use the same name this.timeout in all screens. It may be this problem ? – Morton Commented Jan 28, 2019 at 3:10
  • @JimiPajala I can not understand your meaning, because C countdownToFirstScreen will be triggered if I just navigate A -> B -> C -> D. It doesn't route back any screen in this case. – Morton Commented Jan 28, 2019 at 3:18
  • Share simplified structure and code example. It is very hard to grasp your situation otherwise, example in codesandbox.io – Jimi Pajala Commented Jan 28, 2019 at 6:57
Add a comment  | 

2 Answers 2

Reset to default 10

Using React-Hooks and Functional Components ... things are alot easier...

An effect with empty-deps [] simulates componentDidMount, and its cleanUp-callback simulates componentWillUnmount

  const timerRef = useRef(null);

  useEffect(() => {
    timerRef.current = setTimeout(() => {
      /** Your logic goes here */
    }, 9000);

    return () => {
      if (timerRef.current) {
        clearTimeout(timerRef.current);
      }
    };
  }, []);

It looks like you may run into scoping issues as this in the setTimeout callback may have a different context than this.timeOut and thus the timer is not being cleared. Ideally you want a setup where you track the timer in some global component like your AppComponent which is on every screen, with a setup like:

componentWillMount () {
   // Add your listener
   DeviceEventEmitter.addListener('timer', this.clearTimer.bind(this));
}

componentDidMount () {
  startTimer()
}

componentWillUnMount () {
  clearTimer()
}

startTimer () {
 this.timer = this.setTimeout(() => {
   this.props.navigation.navigate('A');
 },9000);

clearTimer () {
 // Handle an undefined timer rather than null
 this.timer !== undefined ? this.clearTimeout(this.timer) : null;
}
发布评论

评论列表(0)

  1. 暂无评论