I'm learning react-native since one week and i'm confused about something.
Here is the stuff: I'm developing an app parsing Imgur API, I somehow managed via a Webview to authenticate myself and get an accessToken, refreshToken etc which I stored locally on my webview component.
Now I want to store this token globally on the app so I did some research and found about AsyncStorage (visibly not secure to store tokens but it's fine it's just an app to practice).
So here is what I understood:
So here is what I did to set my item in my Login component:
//login.js
import React from 'react'
import {AsyncStorage, StyleSheet, WebView} from 'react-native'
import { StackActions, NavigationActions } from 'react-navigation';
const webviewRef = 'webview';
const CLIENT_ID = 'xxxxxxx';
class LoginImgur extends React.Component {
accessToken : string;
expiresIn : string;
refreshToken : string;
userName : string;
constructor(props) {
super(props);
}
async storeItem(key, item) {
try {
let jsonOfItem = await AsyncStorage.setItem(key, JSON.stringify(item));
return jsonOfItem;
} catch (error) {
console.log(error.message);
}
}
_resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'Index' })],
});
_changeNavigationState = async (webView) => {
if (this._splitUrl(webView.url) === true) {
console.log(this.accessToken);
let json = this.storeItem('ACCESS_TOKEN', this.accessToken);
this.props.navigation.dispatch(this._resetAction);
}
};
_splitUrl(url : String) {
if (url.search("access_token=") > 0) {
let array = url.split("=");
this.accessToken = array[2].split('&')[0];
this.expiresIn = array[3].split('&')[0];
this.refreshToken = array[5].split('&')[0];
this.userName = array[6].split('&')[0];
return (true);
}
return (false);
}
webviewProps = {
style: styles.webview_container,
ref: webviewRef,
javaScriptEnabled: true,
onNavigationStateChange: this._changeNavigationState.bind(this),
source: {
uri: 'https://api.imgur.com/oauth2/authorize?client_id=' + CLIENT_ID + '&response_type=token&state=APPLICATION_STATE',
}
};
render() {
return (
<WebView {...this.webviewProps}/>
)
}
}
const styles = StyleSheet.create({
main_container: {
backgroundColor: 'black'
},
webview_container: {
flex: 1
}
});
export default LoginImgur
So now I'm in my homescreen and I want to get this accessToken back so I can now make my API calls !!
// Index.js
class Index extends React.Component {
accessToken : string;
async retrieveItem(key) {
try {
const retrievedItem = await AsyncStorage.getItem(key);
const item = JSON.parse(retrievedItem);
return item;
} catch (error) {
console.log(error.message);
}
}
constructor(props) {
super(props);
}
componentDidMount() {
this.retrieveItem('ACCESS_TOKEN').then((value) => {
console.log(value);
this.accessToken = value;
}).catch((error) => {
console.log('Promise is rejected with error: ' + error);
});
}
_displayAccessToken() {
console.log(this.accessToken);
}
render() {
return (
<View>
{this._displayAccessToken()}
<Text>Lol</Text>
</View>
)
}
}
But... It's not working at all. I do get the token in the console.log actually but it doesn't get save in my this.accessToken.
Someone have an idea to pull it of ? Would be a great help... enter image description here
await AsyncStorage.getItem(key);
is async: it takes a while before the result is available. render()
runs almost immediately, so at that time this.accessToken
is not set yet.
One option to display the accesstoken is to store it the component's state. When you call this.setState({ accessToken: value })
, render() is called again, so then the value will be rendered as soon as the result is available.
componentDidMount() {
this.retrieveItem('ACCESS_TOKEN').then((value) => {
console.log(value);
this.setState({accessToken: value }); // cause re-rendering
}).catch((error) => {
console.log('Promise is rejected with error: ' + error);
});
}
render() {
return (
<View>
<Text>{this.state.accessToken}</Text>
<Text>Lol</Text>
</View>
)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.