setTimeout in React Native

JavascriptIosSettimeoutReact Native

Javascript Problem Overview


I'm trying to load a splash screen for an iOS app built in React Native. I'm trying to accomplish this through class states and then a setTimeout function as follows:

class CowtanApp extends Component {
  constructor(props){
    super(props);
    this.state = {
      timePassed: false
    };
  }

  render() {
    setTimeout(function(){this.setState({timePassed: true})}, 1000);
    if (!this.state.timePassed){
      return <LoadingPage/>;
    }else{
      return (
        <NavigatorIOS
          style = {styles.container}
          initialRoute = {{
            component: LoginPage,
            title: 'Sign In',
          }}/>
      );
    }
  }
}

The loading page works for a second, and then I guess when setTimeout tries to change the state to true, my program crashes: 'undefined is not an object (evaluating this.setState)'. I've been going at this for a couple of hours, any ideas on how to fix it?

Javascript Solutions


Solution 1 - Javascript

Classic javascript mistake.

setTimeout(function(){this.setState({timePassed: true})}, 1000)

When setTimeout runs this.setState, this is no longer CowtanApp, but window. If you define the function with the => notation, es6 will auto-bind this.

setTimeout(() => {this.setState({timePassed: true})}, 1000)

Alternatively, you could use a let that = this; at the top of your render, then switch your references to use the local variable.

render() {
  let that = this;
  setTimeout(function(){that.setState({timePassed: true})}, 1000);

If not working, use bind.

setTimeout(
  function() {
      this.setState({timePassed: true});
  }
  .bind(this),
  1000
);

Solution 2 - Javascript

Write a new function for settimeout. Pls try this.

class CowtanApp extends Component {
  constructor(props){
  super(props);
  this.state = {
  timePassed: false
  };
}

componentDidMount() {
  this.setTimeout( () => {
     this.setTimePassed();
  },1000);
}

setTimePassed() {
   this.setState({timePassed: true});
}


render() {

if (!this.state.timePassed){
  return <LoadingPage/>;
}else{
  return (
    <NavigatorIOS
      style = {styles.container}
      initialRoute = {{
        component: LoginPage,
        title: 'Sign In',
      }}/>
  );
}
}
}

Solution 3 - Javascript

const getData = () => {
// some functionality
}

const that = this;
   setTimeout(() => {
   // write your functions    
   that.getData()
},6000);

Simple, Settimout function get triggered after 6000 milliseonds

Solution 4 - Javascript

Change this code:

setTimeout(function(){this.setState({timePassed: true})}, 1000);

to the following:

setTimeout(()=>{this.setState({timePassed: true})}, 1000); 

Solution 5 - Javascript

On ReactNative .53, the following works for me:

 this.timeoutCheck = setTimeout(() => {
   this.setTimePassed();
   }, 400);

'setTimeout' is the ReactNative library function.
'this.timeoutCheck' is my variable to hold the time out object.
'this.setTimePassed' is my function to invoke at the time out.

Solution 6 - Javascript

In case anyone wants it, you can also make the timer async and await it:

export const delay = (ms) => new Promise((res) => setTimeout(res, ms));

Usage:

// do something
await delay(500); // wait 0.5 seconds
// do something else

Solution 7 - Javascript

You can bind this to your function by adding .bind(this) directly to the end of your function definition. You would rewrite your code block as:

setTimeout(function () {
  this.setState({ timePassed: true });
}.bind(this), 1000);

Solution 8 - Javascript

> Never call setState inside render method

You should never ever call setState inside the render method. Why? calling setState eventually fires the render method again. That means you are calling setState (mentioned in your render block) in a loop that would never end. The correct way to do that is by using componentDidMount hook in React, like so:

class CowtanApp extends Component {
  state = {
     timePassed: false
  }

  componentDidMount () {
     setTimeout(() => this.setState({timePassed: true}), 1000)
  }

  render () {
    return this.state.timePassed ? (
        <NavigatorIOS
          style = {styles.container}
          initialRoute = {{
            component: LoginPage,
            title: 'Sign In',
        }}/>
    ) : <LoadingPage/>
  }
}

PS Use ternary operators for cleaner, shorter and readable code.

Solution 9 - Javascript

There looks to be an issue when the time of the phone/emulator is different to the one of the server (where react-native packager is running). In my case there was a 1 minute difference between the time of the phone and the computer. After synchronizing them (didn't do anything fancy, the phone was set on manual time, and I just set it to use the network(sim) provided time), everything worked fine. This github issue helped me find the problem.

Solution 10 - Javascript

import React, {Component} from 'react';
import {StyleSheet, View, Text} from 'react-native';

class App extends Component {
  componentDidMount() {
    setTimeout(() => {
      this.props.navigation.replace('LoginScreen');
    }, 2000);
  }

  render() {
    return (
      <View style={styles.MainView}>
        <Text>React Native</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  MainView: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

Solution 11 - Javascript

Same as above, might help some people.

setTimeout(() => {
  if (pushToken!=null && deviceId!=null) {
    console.log("pushToken & OS ");
    this.setState({ pushToken: pushToken});
    this.setState({ deviceId: deviceId });
    console.log("pushToken & OS "+pushToken+"\n"+deviceId);
  }
}, 1000);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPhilView Question on Stackoverflow
Solution 1 - JavascriptoliversissonView Answer on Stackoverflow
Solution 2 - JavascriptPhyoView Answer on Stackoverflow
Solution 3 - JavascriptkrishnazdenView Answer on Stackoverflow
Solution 4 - Javascriptwandhi ZakariView Answer on Stackoverflow
Solution 5 - Javascriptdavid m leeView Answer on Stackoverflow
Solution 6 - JavascriptEric WienerView Answer on Stackoverflow
Solution 7 - JavascriptScott CarpenterView Answer on Stackoverflow
Solution 8 - JavascriptUtkarshPramodGuptaView Answer on Stackoverflow
Solution 9 - Javascriptim-a-teapotView Answer on Stackoverflow
Solution 10 - JavascriptYasir MunirView Answer on Stackoverflow
Solution 11 - JavascriptDunken_saiView Answer on Stackoverflow