如何使用 react-redux 存储令牌并在多个 axios 请求上使用它?

Fan*_*ang 7 javascript api react-native redux-thunk react-redux

我正在使用 react native 构建一个应用程序,它要求我get request使用令牌在同一个 API 上执行多个操作。

假设网址是这样的

令牌 URL = https://test.co/v1/tokens、API URL 1 =https://test.co/v1/students和 API URL 2 =https://test.co/v1/cars

首先,为了从任一 API URL 获取数据,我是这样写的

示例 students_actions.js

import axios from 'axios';
import { FETCH_STUDENT } from './types';

const TOKEN_URL = '...'
const STUDENT_URL = '...'

export const fetchStudent = (callback) => async (dispatch) => {
    axios.post(TOKEN_URL, {
        email: 'email',
        password: 'password',
        role: 'user'
    })
    .then((response) => {
        const accessToken = response.data.token;
        //console.log(accessToken);
        axios.get(STUDENT_URL, {
            headers: { 'Authorization': 'Bearer '.concat(accessToken) }
        })
        .then((studentResponse) => {
            dispatch({ type: FETCH_STUDENT, payload: studentResponse.data });
            callback();
        })
        .catch((e) => {
            console.log(e);
        });
    })
    .catch((error) => {
        console.log(error);
    });
};
Run Code Online (Sandbox Code Playgroud)

示例 students_reducers.js

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

const INITIAL_STATE = {
    data: []
};

export default function (state = INITIAL_STATE, action) {
    switch (action.type) {
        case FETCH_STUDENT:
            return action.payload;
        default:
            return state;
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样在渲染函数中调用它

//some code
import { connect } from 'react-redux';

import * as actions from '../actions';

onButtonPressProfile = () => {
    this.props.fetchStudent(() => {
        this.props.navigation.navigate('Profile');
    });
}
class StudentProfile extends Component {
    render() {
        return(
            <View><Text>{this.props.students.name}</Text></View>
        );
    }
}

function mapStateToProps({ students }) {
    return { students: students.data };
}

export default connect(mapStateToProps, actions)(StudentProfile);
Run Code Online (Sandbox Code Playgroud)

虽然这是所有运行没有任何问题,我觉得students_actions.js可以通过编写代码检索令牌在其他文件中进一步简化和调用值回场内students_actions.js进行GET request

原因是我不必每次想访问students或 时都请求令牌cars。比方说,我确实请求过一次,我可以使用相同的令牌在大约 24 小时内访问 API。一旦它过期,那么我必须再次请求令牌以再次访问 API。

我已经为token_actions.jswith编写了代码token_reducer.js。下面是两个代码。

token_actions.js

//import library
// this code works
const TOKEN_URL = apiConfig.url + 'tokens';
const auth = {
    email: 'email',
    password: 'password',
    role: 'user'
};

export const fetchToken = () => async (dispatch, getState) => {
        axios.post(TOKEN_URL, auth)
        .then((response) => {

            dispatch({ type: FETCH_TOKEN, payload: response.data.token });
        })
        .catch((error) => {
            console.log(error);
        });
};
Run Code Online (Sandbox Code Playgroud)

token_reducer.js

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

const INITIAL_STATE = {
    data: []
};

export default function (state = INITIAL_STATE, action) {
    switch (action.type) {
        case FETCH_TOKEN:
            return action.payload;
        default:
            return state;
}
Run Code Online (Sandbox Code Playgroud)

}

students_actions.js

axios.get(STUDENT_URL, { headers: {
                           'Authorization': 'Bearer '.concat(here is the value from token_actions)}})
Run Code Online (Sandbox Code Playgroud)

现在我被困在如何从token_actions.jsinto调用/导入有效负载students_actions.js?我应该使用mapStateToProps还是有其他方法可以做到这一点?

目前,这个应用程序还没有任何身份验证功能。它基本上是一个显示从 API 获取的数据的应用程序。

我主要根据我在网上找到的示例编写了这个应用程序,对于这种情况,我找到了这个示例,但似乎并不是我真正想要实现的。

我不太了解 javascript,所以如果有人能指出与此案例相关的任何链接或 Stackoverflow 上的相同问题以及一些建议,我将非常高兴。

谢谢你。

Enr*_*Dev 8

我要做的合乎逻辑的事情是创建类似 AuthReducer 的东西,您可以在其中存储您的令牌和刷新令牌。这是我的基本 AuthReducer 示例:

export const INITIAL_STATE = {
  oAuthToken: '',
  refreshToken: '',
};

export default AuthReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case REFRESH_OAUTH_DATA:
      const { oAuthToken, refreshToken } = action.payload;
      return { ...state, oAuthToken, refreshToken };

    case LOGOUT:
      return INITIAL_STATE;

    case LOGIN_FETCH_SUCCESS:
      const { oAuthToken, refreshToken } = action.payload;
      return { ...state, oAuthToken, refreshToken };

    default:
      return state;
  }
};
Run Code Online (Sandbox Code Playgroud)

现在您可以使用 getState 方法在您的操作中获取您的令牌,执行如下操作:

export const fetchStudent = (callback) => async (dispatch, getState) => {
    const token = getState().AuthReducer.oAuthToken;
    ....
};
Run Code Online (Sandbox Code Playgroud)

请记住,如果您使用的是 ES6,您可能还想使用 await:

export const fetchStudent = (callback) => async (dispatch, getState) => {
    try {
        const accessToken = getState().AuthReducer.oAuthToken;

        let response = await axios.get(STUDENT_URL, {
            headers: { 'Authorization': 'Bearer '.concat(accessToken) }
         })

         dispatch({ type: FETCH_STUDENT, payload: response.data });
         callback();
    } catch(e) {
        console.log(e);
    }
};
Run Code Online (Sandbox Code Playgroud)

这样你的代码更容易阅读和维护。