2015-11-05 19 views
25

Sto utilizzando AsyncStorage in ComponentWillMount per ottenere memorizzato localmente accessToken, ma restituisce la promessa dopo l'esecuzione della funzione render(). Come posso fare in modo che render() attenda fino al completamento della promessa? Grazie.React Native AsyncStorage recupera i dati dopo il rendering

+1

Che cosa stai cercando di fare con i dati? Un modo per ovviare a questo problema consiste nel memorizzare una variabile vuota nella funzione getInitalState, quindi quando AsyncStorage restituisce il valore, impostare lo stato con il nuovo valore. –

+0

Grazie per la domanda, sto recuperando localmente accessToken da AsyncStorage per impostare lo stato. Ma dal momento che restituisce una promessa, la funzione render() viene eseguita prima, quindi lo stato viene impostato immediatamente dopo. Quindi vedo brevemente la pagina di accesso (~ 0.1s) ogni volta che visito l'app dal momento che render() controlla lo stato e restituisce la pagina di accesso o l'app principale. – skleest

+1

Oh, ok. Non sei sicuro di come correggerlo, se non quello di mostrare un caricatore/messaggio di caricamento, quindi sostituirlo con la vista di accesso o la vista di accesso. –

risposta

43

Non è possibile effettuare render attendere per quanto ne so. Quello che ho fatto nell'app a cui sto lavorando è aggiungere una schermata di caricamento finché non si risolve quella promessa da AsyncStorage. Vedere l'esempio di seguito:

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/>; 
    } 

} 

impostazione della proprietà isLoading sull'oggetto Stato causerà una ri-renderizzare e quindi è possibile mostrare il contenuto che si basa sul access token.

In una nota a margine, ho scritto una piccola libreria denominata react-native-simple-store che semplifica la gestione dei dati in AsyncStorage. Spero che tu lo trovi utile

+4

Funziona ancora nell'ultima versione di React Native? Ho implementato questo codice esattamente, ma rimane bloccato su "Caricamento in corso ..." per sempre. Se eseguo un log di console su render per mostrare isLoading (senza il metodo if) restituisce, false e quindi true, quindi teoricamente dovrebbe funzionare. Ma con il metodo if abilitato rimane bloccato su "Caricamento" per sempre e il log restituisce solo false. – Hasen

+0

Sto avendo lo stesso problema di Hasen sopra. La mia funzione render() non viene mai chiamata una seconda volta, dopo che lo stato è stato aggiornato. Quindi la mia schermata di caricamento mostra solo indefinitamente ... – Dygerati

+0

Ho avuto lo stesso problema, continuo a rimanere bloccato sullo schermo di caricamento. Qualcuno ha avuto un modo per risolvere questo? – DsEsteban

-3

React-native è basato su Javascript che non supporta le funzioni di blocco. Inoltre, questo ha senso perché non vogliamo che l'interfaccia utente rimanga bloccata o non risponda. Ciò che puoi fare è gestirlo nella funzione di rendering. Ho una schermata di caricamento ri-renderlo così come si ottiene le informazioni da AsyncStorage

+1

L'aggiornamento di una variabile di stato verrà "ri-renderizzato", ovvero richiamerà nuovamente la funzione di rendering –

5

Sulla base di reagire nativo doc, si può fare qualcosa di simile:

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> 
    ); 
    } 
} 
Problemi correlati