2015-11-05 18 views
25

Rendering ich AsyncStorage in ComponentWillMount bin mit lokal accessToken gespeichert werden, aber es kehrt das Versprechen nach render() Funktion ausgeführt wird. Wie kann ich render() warten bis das Versprechen abgeschlossen ist? Vielen Dank.Reagieren india AsyncStorage holt Daten nach

+1

Was genau mit den Daten zu tun versuchen? Eine Möglichkeit, dies zu umgehen, besteht darin, eine leere Variable in der Funktion getInitalState zu speichern. Wenn AsyncStorage den Wert zurückgibt, legen Sie den Status mit dem neuen Wert fest. –

+0

Danke für die Frage, ich erhalte Zugriff lokal von AsyncStorage, um den Status zu setzen. Aber da es eine Zusage zurückgibt, wird die render() - Funktion zuerst ausgeführt, dann wird der Status unmittelbar danach festgelegt. Daher sehe ich jedes Mal, wenn ich die App besuche, kurz die Anmeldeseite (~ 0.1s), da render() nach dem Status sucht und die Anmeldeseite oder die Haupt-App zurückgibt. – skleest

+1

Oh, ok. Ich bin mir nicht sicher, wie ich das beheben kann, außer vielleicht eine Loader-/Lade-Nachricht anzuzeigen und sie dann entweder durch die Login-Ansicht oder die eingeloggte Ansicht zu ersetzen. –

Antwort

43

Sie können nicht render warten, soweit ich weiß. In der App, an der ich gerade arbeite, habe ich einen Ladebildschirm hinzugefügt, bis das Versprechen von AsyncStorage verrechnet wird. Siehe nachstehendes Beispiel:

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

class Screen extends React.Component { 

    state = { 
    isLoading: true 
    }; 

    componentDidMount() { 
    AsyncStorage.getItem('accessToken').then((token) => { 
     this.setState({ 
     isLoading: false 
     }); 
    }); 
    }, 

    render() { 
    if (this.state.isLoading) { 
     return <View><Text>Loading...</Text></View>; 
    } 
    // this is the content you want to show after the promise has resolved 
    return <View/>; 
    } 

} 

Einstellen der isLoading Eigenschaft auf dem Statusobjekt verursacht eine erneute machen und dann können Sie den Inhalt anzeigen, die auf dem accessToken beruht.

Nebenbei habe ich eine kleine Bibliothek namens react-native-simple-store geschrieben, die die Verwaltung von Daten in AsyncStorage vereinfacht. Ich hoffe, Sie finden es nützlich.

+4

Funktioniert das immer noch in der neuesten Version von React Native? Ich habe diesen Code genau implementiert, aber er bleibt auf "Loading ..." für immer hängen. Wenn ich eine Konsole logon render ausführen, um isLoading (ohne die if-Methode) anzuzeigen, gibt es false und dann true zurück, also sollte es theoretisch funktionieren. Aber wenn die if-Methode aktiviert ist, bleibt sie beim Laden für immer hängen und das Protokoll gibt nur false zurück. – Hasen

+0

Ich habe das gleiche Problem wie Hasen oben. Meine render() -Funktion wird nie ein zweites Mal aufgerufen, nachdem der Status aktualisiert wurde. Also mein Ladebildschirm zeigt nur unbestimmt .... – Dygerati

+0

Ich hatte die gleichen Probleme, ich bleibe am Ladebildschirm hängen. Hat jemand einen Weg gefunden, das zu lösen? – DsEsteban

-3

React-native basiert auf Javascript, das Blockierungsfunktionen nicht unterstützt. Auch das macht Sinn, da wir nicht möchten, dass die Benutzeroberfläche hängen bleibt oder nicht reagiert. Was Sie tun können, ist dies in der Render-Funktion behandelt. d. h. Laden Sie den Bildschirm erneut, so wie Sie die Informationen aus dem AsyncStorage bekommen

+1

Das Aktualisieren einer Statusvariablen wird "neu gerendert", was bedeutet, dass es die Renderfunktion erneut aufruft. –

5

Basierend auf reagieren-native doc, können Sie etwas tun:

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

let STORAGE_KEY = '@AsyncStorageExample:key'; 

export default class MyApp extends Component { 

    constructor(props) { 
    super(props); 
    this.state = { 
     loaded: 'false', 
    }; 
    } 

    _setValue = async() => { 
    try { 
     await AsyncStorage.setItem(STORAGE_KEY, 'true'); 
    } catch (error) { // log the error 
    } 
    }; 

    _loadInitialState = async() => { 
    try { 
     let value = await AsyncStorage.getItem(STORAGE_KEY); 
     if (value === 'true'){ 
     this.setState({loaded: 'true'}); 
     } else { 
     this.setState({loaded: 'false'}); 
     this._setValue(); 
     } 
    } catch (error) { 
     this.setState({loaded: 'false'}); 
     this._setValue(); 
    } 
    }; 

    componentWillMount() { 
    this._loadInitialState().done(); 
    } 

    render() { 
    if (this.state.loaded === 'false') { 
     return (
     <View><Text>Loading...</Text></View> 
    ); 
    } 
    return (
     <View><Text>Main Page</Text></View> 
    ); 
    } 
} 
Verwandte Themen