我正在使用react native构建一个应用程序,要求我在带有令牌的相同API上执行多个get request
。
假设网址是这样的
令牌网址= https://test.co/v1/tokens
,API网址1 = https://test.co/v1/students
,API网址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);
});
};
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;
}
}
并将其称为渲染函数,如此
//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);
虽然这一切都在没有任何问题的情况下运行,但我觉得students_actions.js
可以通过编写用于在其他文件中检索令牌的代码来进一步简化,并在students_actions.js
内调用值GET request
}。
原因是每次我想访问students
或cars
时,我都不必请求令牌。可以说,我曾经请求了一次,我可以使用相同的令牌24小时来访问API。一旦它过期,我就必须再次请求令牌来再次访问API。
我已经为token_actions.js
和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);
});
};
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;
}
}
students_actions.js
axios.get(STUDENT_URL, { headers: {
'Authorization': 'Bearer '.concat(here is the value from token_actions)}})
现在我陷入困境,我应该如何调用/导入token_actions.js
的有效负载到students_actions.js
?我应该使用mapStateToProps
还是有其他方法可以做到这一点?
目前,此应用尚未拥有任何身份验证功能。它基本上是一个应用程序,显示从API获取的数据。
我主要根据我在网上找到的例子编写了这个应用程序,对于这个案例,我发现了这个example但似乎并不是我想要达到的目的。
我真的不太了解javascript所以如果有人能指出任何与此案例相关的链接或者也许在Stackoverflow上有相同的问题,我也会很高兴,也许还有一些建议。
谢谢。
答案 0 :(得分:1)
我合乎逻辑的做法是创建类似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;
}
};
现在,您可以使用getState方法在您的操作中获取令牌,例如:
export const fetchStudent = (callback) => async (dispatch, getState) => {
const token = getState().AuthReducer.oAuthToken;
....
};
请记住,如果您使用的是ES6,您可能还想使用等待:
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: studentResponse.data });
callback();
} catch(e) {
console.log(e);
}
};
这样,您的代码便于阅读和维护。