无法使用React Redux存储数据?

时间:2018-09-16 14:02:53

标签: javascript reactjs redux

我已经创建了Login.js组件,并且有2个动作,一个是loginAction.js,第二个是logoutAction.js和一个userReducer.js,我在控制台中获取的访问令牌未定义。单击登录按钮后,如何将accessToken存储在异步存储中。注意:我正在使用redux thunk中间件。

我无需使用redux和asyncstorage就实现了登录功能,即使用内部状态变量,请参见下面的原始代码:(但是我现在想使用redux和asyncstorage来实现它)

原始代码:

constructor(props) {
    super(props);
    this.state = { accessToken: null };
  }

  _onLogin = () => {
    auth0.webAuth
      .authorize({
        scope: 'openid profile',
        audience: 'https://' + credentials.domain + '/userinfo'
      })
      .then(credentials => {
        Alert.alert(
          'Success',
          'AccessToken: ' + credentials.accessToken,
          [{ text: 'OK', onPress: () => console.log('OK Pressed') }],
          { cancelable: false }
        );
        this.setState({ accessToken: credentials.accessToken });
      })
      .catch(error => console.log(error));
  };

Login.js:

    import React, { Component } from 'react';
    import { Button, StyleSheet, Text, View } from 'react-native';
    import { connect } from 'react-redux';
    import { loginUser } from '../actions/loginAction';
    import { logoutUser } from '../actions/logoutAction';

    class Login extends Component {

      render() {

        console.log(this.props)

        return (
          <View style={styles.container}>
            <Button
            onPress={loginUser}
            title="Click to Login"
            ></Button>
          </View>
        );
      }
    }

const mapStateToProps = state => ({
  accessToken: state.accessToken
})

export default connect (mapStateToProps, { loginUser })(Login);

loginAction.js:

import { LOGIN_USER } from './types';
import Auth0 from 'react-native-auth0';
import { AsyncStorage } from 'react-native';

var credentials = require('./auth0-credentials');
const auth0 = new Auth0(credentials);

export const loginUser = () => dispatch => {
    auth0.webAuth
    .authorize({
      scope: 'openid profile',
      audience: 'https://' + credentials.domain + '/userinfo'
    })
    .then(credentials =>

        _storeData = async () => {
            try {
                await AsyncStorage.setItem('accessToken', credentials.accessToken);
            } catch (error) {
                console.log(error)
            }
        },

        dispatch({
            type: LOGIN_USER,
            payload: credentials.accessToken
        })
    )
    .catch(error => console.log(error));
}

userReducer.js:

import { LOGIN_USER } from '../actions/types';

const initialState = {
    accessToken: null
}

export default function (state = initialState, action) {
    switch (action.type) {

        case LOGIN_USER:

            return {
               ...state,
               accessToken:action.payload
            };

        default:
            return state;
    }
}

已将原始代码转换为动作和化简器,但未定义accessToken。

1 个答案:

答案 0 :(得分:1)

从所发布的代码中(至少对我而言),您不清楚要做什么,但是我将尝试提出解决方案。

首先,您永远不会调用_storeData函数,这意味着未存储令牌。

import React, { Component } from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import { connect } from 'react-redux';
import { loginUser } from '../actions/loginAction';
import { logoutUser } from '../actions/logoutAction';

    class Login extends Component {

      // Monitor props changes
      componentDidUpdate(prevProps){
          // Token was changed
          if(prevProps.accessToken !== this.props.accessToken){
             if(this.props.accessToken){
                 Alert.alert(
                   'Success',
                   'AccessToken: ' + credentials.accessToken,
                   [{ text: 'OK', onPress: () => console.log('OK Pressed') 
                   }],
                   { cancelable: false }
                 );
                 this.setState({ accessToken: credentials.accessToken });
             }
          }
      }

      render() {

        console.log(this.props)

        return (
          <View style={styles.container}>
            <Button
            onPress={loginUser}
            title="Click to Login"
            ></Button>
          </View>
        );
      }
    }

const mapStateToProps = state => ({
  accessToken: state.accessToken
})

export default connect (mapStateToProps, { loginUser, logoutUser })(Login);

loginAction.js:

import { LOGIN_USER } from './types';
import Auth0 from 'react-native-auth0';
import { AsyncStorage } from 'react-native';

var credentials = require('./auth0-credentials');
const auth0 = new Auth0(credentials);

export const loginUser = () => dispatch => {
    auth0.webAuth
    .authorize({
      scope: 'openid profile',
      audience: 'https://' + credentials.domain + '/userinfo'
    })
    .then(credentials =>

        _storeData = async () => {
            try {
                await AsyncStorage.setItem('accessToken', credentials.accessToken);
            } catch (error) {
                console.log(error)
            }
        };
        // Call the function to store the token
        _storeData();

        dispatch({
            type: LOGIN_USER,
            payload: credentials.accessToken
        })
    )
    .catch(error => console.log(error));
}