некоторое время go я использовал следующий способ:
Прежде всего, я создал некоторую папку API, где каждая функция возвращает данные для топора ios запросов
// /api.js
export function signIn (data) {
return {
method: 'post',
api: '/sign-in'
data: data
}
}
export function signUp (data) {
return {
method: 'post',
api: '/registration'
data: data
}
}
затем я сгенерировал тип действия по указанному c правилу, например: SIN_IN_REQUEST, где: SIGN_IN означает функцию входа в /api.js; ЗАПРОС означает, что вам нужно сделать запрос API. В результате мое промежуточное программное обеспечение выглядело следующим образом:
// request middleware
const instance = axios.create({
baseURL: '/api'
});
function camelize(str) {
return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) {
return index === 0 ? word.toLowerCase() : word.toUpperCase();
}).replace(/\s+/g, '');
}
const customMiddleWare = store => next => action => {
if (!action.type.endsWith('_REQUEST')) {
next();
return;
}
const methodName = action.type.replace('_REQUEST', ''); // removed _REQUEST from action type
const camelCaseMethodName = camelize(methodName); // the result is "signIn"
const method = api[camelCaseMethodName];
if (!method) {
next();
return;
}
const dataForRequest = method(action.payload);
try {
const response = await instance(dataForRequest);
const newActionType = action.type.replace('_REQUEST', '_SUCCESS');
dispatch({
type: newActionType,
payload: {
requestPayload: action.payload,
response: response,
}
})
} catch(error) {
if (error.status === '401') {
dispatch(refreshToken());
next();
return;
}
const newActionType = action.type.replace('_REQUEST', '_FAILURE');
dispatch({
type: newActionType,
payload: {
requestPayload: action.payload,
error: error,
}
})
}
next();
}
После этого вы можете легко управлять любым запросом API в вашем приложении следующим образом:
function someTHunkMethod(username, password) {
return (dispatch, getState) => {
dispatch({
type: 'SIGN_IN_REQUEST',
payload: {
username,
password
}
})
}
}
function oneMoreThunk(data) {
return (dispatch, getState) => {
dispatch({
type: 'GET_USERS_REQUEST',
payload: data
})
}
}
А в редукторе сделать что-то подобное
...
switch (action.type) {
case 'SIGN_REQUEST':
return {
isLoading: true,
user: null
}
case 'SIGN_SUCCESS':
return {
isLoading: false,
user: action.payload.response.data
}
case 'SIGN_FAILURE':
return {
isLoading: false,
user: null
}
default:
return state
}