Я создаю приложение, использующее реакцию native, которое требует, чтобы я выполнял несколько get request
на получение одного API с токеном.
Скажем, URL-адрес подобен этому
URL-адрес токена = https://test.co/v1/tokens
, URL-адрес API 1 = https://test.co/v1/students
и URL-адрес API 2 = https://test.co/v1/cars
Прежде всего, чтобы получить данные из URL-адресов API, я написал это следующим образом
Пример для 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.
Я написал это приложение в основном на основе примеров, которые я нашел в Интернете, и для этого случая я нашел этот пример, но, похоже, не совсем то, чего хочу достичь.
Я не совсем понимаю javascript, поэтому я буду очень рад, если кто-нибудь сможет указать любую ссылку, связанную с этим делом, или, возможно, такие же вопросы здесь, на Stackoverflow, а также, возможно, на некоторые предложения.
Спасибо.
Логичным было бы создать нечто вроде 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);
}
};
Таким образом, ваш код легче читать и поддерживать.
AuthReducer
? Это какimport { AuthReducer } from './AuthReducer';
на вершинеstudents_actions.js
?