【问题标题】:Not able to store data using react redux?无法使用 react redux 存储数据?
【发布时间】:2018-09-16 14:02:53
【问题描述】:

我已经创建了 Login.js 组件,并且有 2 个操作,一个是 loginAction.js,第二个是 logoutAction.js 和一个 userReducer.js,我在控制台中获得了未定义的 accessToken。如何在单击登录按钮时将 accessToken 存储在 asyncstorage 中。注意:我使用的是 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));
  };

登录.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;
    }
}

将原始代码转换为 action 和 reducer,但 accessToken 未定义。

【问题讨论】:

  • 你永远不会调用_storeData函数。
  • @Titus 我应该把它移到dispatch() 里面吗?如何将 accessToken 存储在 asyncstorage 中?
  • 只要调用函数(如:_storeData()
  • @Titus 我的原始代码运行完美,即没有 redux,但是当我尝试使用 redux 时,对我来说很困难,因为我是 redux 的新手。在原始代码中,即当我点击登录按钮时的内部状态变量,它会将用户重定向到 Web 浏览器 auth0 身份验证,但使用 redux 什么都没有发生
  • @Titus 检查原始代码是如何工作的 -> imgur.com/a/BWBTgQw

标签: javascript reactjs redux


【解决方案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));
}

【讨论】:

  • 我正在尝试使用 auth0 实现登录功能,请参阅此屏幕截图:imgur.com/a/BWBTgQw 屏幕截图是正在运行的原始代码。
  • @funjoker 看看我所做的更改,我还添加了 cmets 来解释它们的作用。
  • 我想使用 redux 实现登录屏幕,而不是使用内部状态,那么你为什么要在 Login.js 中使用 this.setState({ accessToken: credentials.accessToken }) 呢?原始代码是 github 上的 react native 示例代码 -> github.com/auth0-samples/auth0-react-native-sample/blob/master/…
  • @funjoker 我这样做是因为这是旧代码在设置令牌时所做的事情。目前尚不清楚设置令牌时会发生什么。 Redux 和内部状态不是相互排斥的
  • 但是上面的代码不起作用,即当我点击登录按钮时它没有导航到网络浏览器?我想在 mapStateToProps 中问你这个是否正确 -> accessToken: state.accessToken
猜你喜欢
  • 2018-08-13
  • 2021-05-06
  • 1970-01-01
  • 2018-09-24
  • 2017-12-19
  • 1970-01-01
  • 1970-01-01
  • 2020-10-15
  • 2017-07-10
相关资源
最近更新 更多