web-dev-qa-db-fra.com

setTimeout dans React Native

J'essaie de charger un écran de démarrage pour une application iOS intégrée à React Native. J'essaie d'accomplir cela par le biais d'états de classe, puis d'une fonction setTimeout comme suit:

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',
          }}/>
      );
    }
  }
}

La page de chargement fonctionne pendant une seconde, puis j'imagine que, lorsque setTimeout tente de remplacer l'état par true, mon programme se bloque: 'undefined n'est pas un objet (évaluation this.setState)' J'y vais depuis deux heures, des idées sur la façon de le réparer?

47
Phil

Erreur javascript classique.

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

Lorsque setTimeout exécute this.setState, this n'est plus CowtanApp, mais window. Si vous définissez la fonction avec la notation =>, es6 liera automatiquement this.

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

Vous pouvez également utiliser un let that = this; en haut de votre render, puis changer vos références pour utiliser la variable locale.

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

Ecrire une nouvelle fonction pour settimeout. Pls essayer ceci. 

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',
      }}/>
  );
}
}
}
12
Phyo

Sur ReactNative .53, ce qui suit fonctionne pour moi:

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

'setTimeout' est la fonction de bibliothèque ReactNative.
'this.timeoutCheck' est ma variable pour contenir l'objet de délai d'expiration.
'this.setTimePassed' est ma fonction à appeler à l'expiration du délai.

4
david m lee

Vous pouvez lier this à votre fonction en ajoutant .bind(this) directement à la fin de la définition de votre fonction. Vous réécririez votre bloc de code comme suit:

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

Changer ce code:

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

à ce qui suit:

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

Il semble y avoir un problème lorsque l'heure du téléphone/émulateur est différente de celle du serveur (où le conditionneur natif de react-native est en cours d'exécution). Dans mon cas, il y avait une différence d'une minute entre l'heure du téléphone et celle de l'ordinateur. Après les avoir synchronisés (je n'ai rien fait de fantaisie, le téléphone était réglé sur l'heure manuelle et je viens de le configurer pour utiliser l'heure réseau (sim) fournie), tout a bien fonctionné. This Le problème de github m'a aidé à trouver le problème.

1
Alex Buicescu
const getData = () => {
// some functionality
}

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

La fonction Settimeout simple se déclenche après 6000 millisecondes

0
krishnazden

N'appelez jamais setState dans la méthode render

Vous devriez jamais jamais appeler setState dans la méthode render. Pourquoi? appeler setState déclenche à nouveau la méthode render. Cela signifie que vous appelez setState (mentionné dans votre bloc render) dans une boucle qui ne se terminerait jamais. La bonne façon de faire est d'utiliser componentDidMount hook dans React, comme suit:

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 Utilisez des opérateurs ternaires pour un code plus propre, plus court et lisible.

0
UtkarshPramodGupta

Comme ci-dessus, pourrait aider certaines personnes. 

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);
0
Dunken_sai