【问题标题】:Use AsyncStorage to store token globally使用 AsyncStorage 全局存储令牌
【发布时间】:2019-04-20 02:29:00
【问题描述】:

我从一周开始就开始学习 react-native,但我对某些事情感到困惑。

以下是内容: 我正在开发一个解析 Imgur API 的应用程序,我以某种方式通过 Webview 进行管理以验证我自己并获取我本地存储在我的 webview 组件中的 accessToken、refreshToken 等。

现在我想将这个令牌全局存储在应用程序上,所以我做了一些研究并发现了 AsyncStorage(存储令牌显然不安全,但它只是一个可以练习的应用程序很好)。

这就是我的理解:

  • 您通过 setItem 提供键和值,它们以某种方式将其包装在 Promise 中(我需要对这些东西进行一些研究)
  • 然后您可以在另一个异步函数中取回它。

以下是我在登录组件中设置项目的操作:

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

所以现在我在我的主屏幕上,我想取回这个 accessToken 以便我现在可以进行我的 API 调用!!

// 索引.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>
    )
}

}

但是...它根本不起作用。实际上,我确实在 console.log 中获得了令牌,但它没有保存在我的 this.accessToken 中。

有人有想法吗?会很有帮助的...enter image description here

【问题讨论】:

    标签: javascript react-native async-await


    【解决方案1】:

    await AsyncStorage.getItem(key); 是异步的:需要一段时间才能获得结果。 render() 几乎立即运行,所以当时 this.accessToken 尚未设置。

    显示访问令牌的一个选项是将其存储组件的状态。当你调用this.setState({ accessToken: value })时,会再次调用render(),所以一旦结果可用,值就会被渲染。

    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>
        )
    }
    

    【讨论】:

    • 非常感谢工作的人 :-) !!!但是将我的令牌放在状态中不是很残酷吗?我的意思是我不在渲染函数中使用它,而只是在 API 相关函数中使用它。你有没有我可以使用的解决方案?非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 2018-07-03
    • 2010-09-27
    • 2019-07-15
    • 2012-09-11
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    相关资源
    最近更新 更多