Ich versuche, einen Begrüßungsbildschirm für eine in React Native integrierte iOS-App zu laden. Ich versuche dies durch Klassenzustände und dann eine setTimeout-Funktion wie folgt zu erreichen:
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',
}}/>
);
}
}
}
Die Ladeseite funktioniert eine Sekunde lang, und wenn setTimeout versucht, den Status auf true zu ändern, stürzt mein Programm ab: 'undefined ist kein Objekt (Auswertung dieses.setState)'. Ich bin schon seit ein paar Stunden dabei und habe Ideen, wie ich das beheben kann?
debug
stackoverflow.com/questions/51163349/…Antworten:
Klassischer Javascript-Fehler.
setTimeout(function(){this.setState({timePassed: true})}, 1000)
Wenn
setTimeout
läuftthis.setState
,this
ist nicht mehrCowtanApp
, aberwindow
. Wenn Sie die Funktion mit der=>
Notation definieren, wird es6 automatisch gebundenthis
.setTimeout(() => {this.setState({timePassed: true})}, 1000)
Alternativ können Sie ein
let that = this;
oben in Ihrem verwendenrender
und dann Ihre Referenzen ändern, um die lokale Variable zu verwenden.render() { let that = this; setTimeout(function(){that.setState({timePassed: true})}, 1000);
Wenn es nicht funktioniert, verwenden Sie
bind
.setTimeout( function() { this.setState({timePassed: true}); } .bind(this), 1000 );
quelle
Schreiben Sie eine neue Funktion für die Einstellung. Bitte versuchen Sie dies.
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', }}/> ); } } }
quelle
Ändern Sie diesen Code:
setTimeout(function(){this.setState({timePassed: true})}, 1000);
Zu dem Folgendem:
setTimeout(()=>{this.setState({timePassed: true})}, 1000);
quelle
Auf ReactNative .53 funktioniert Folgendes für mich:
this.timeoutCheck = setTimeout(() => { this.setTimePassed(); }, 400);
'setTimeout' ist die ReactNative-Bibliotheksfunktion.
'this.timeoutCheck' ist meine Variable, um das Timeout-Objekt zu halten.
'this.setTimePassed' ist meine Funktion, die ich beim Timeout aufrufe.
quelle
Sie können sich
this
an Ihre Funktion binden , indem Sie.bind(this)
direkt am Ende Ihrer Funktionsdefinition hinzufügen . Sie würden Ihren Codeblock wie folgt umschreiben:setTimeout(function () { this.setState({ timePassed: true }); }.bind(this), 1000);
quelle
const getData = () => { // some functionality } const that = this; setTimeout(() => { // write your functions that.getData() },6000);
Einfache Settimout-Funktion wird nach 6000 Millisekunden ausgelöst
quelle
setTimeout(()=>{this.setState({loaded: true})}, 1000);
Verwenden Sie dies einfach für eine Zeitüberschreitung.quelle
Es scheint ein Problem zu geben, wenn sich die Zeit des Telefons / Emulators von der des Servers unterscheidet (auf dem der reaktionsnative Packager ausgeführt wird). In meinem Fall gab es einen Unterschied von 1 Minute zwischen der Zeit des Telefons und des Computers. Nachdem ich sie synchronisiert hatte (nichts Besonderes, das Telefon wurde auf manuelle Zeit eingestellt und ich habe es einfach so eingestellt, dass es die vom Netzwerk (sim) bereitgestellte Zeit verwendet), funktionierte alles einwandfrei. Dieses Github-Problem hat mir geholfen, das Problem zu finden.
quelle
Sie sollten niemals
setState
innerhalb derrender
Methode aufrufen . Warum? Der AufrufsetState
löst dierender
Methode schließlich erneut aus. Das bedeutet, dass Sie setState (in Ihremrender
Block erwähnt) in einer Schleife aufrufen , die niemals enden würde. Der richtige Weg, dies zu tun, ist die Verwendung voncomponentDidMount
Hook in React, wie folgt :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 Verwenden Sie ternäre Operatoren für saubereren, kürzeren und lesbaren Code.
quelle
Falls es jemand möchte, können Sie den Timer auch asynchronisieren und darauf warten:
export const delay = (ms) => new Promise((res) => setTimeout(res, ms));
Verwendung:
// do something await delay(500); // wait 0.5 seconds // do something else
quelle
Das gleiche wie oben, könnte einigen Menschen helfen.
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);
quelle