Redux: вызов одного и того же API, но отправка разных действий

#javascript #reactjs #redux

#javascript #reactjs #redux

Вопрос:

В настоящее время у меня есть действия redux, которые getUsers() должны получить все пользователи.

 export function getUsers (params) {
    return async dispatch => { 
        await dispatch({ type: 'GET_USERS_REQUEST' });

        const urlParams = params ? new URLSearchParams(Object.entries(params)) : null;

        return axios({
            method: 'get',
            url: Environment.GET_USERS  `?${urlParams}`,
            headers: { 'Content-Type': 'application/json' },
        }).then (async res => {
            await dispatch({ type: 'GET_USERS_SUCCESS', allUsers: res.data.Data });
        }).catch (err => {
            dispatch({ type: 'GET_USERS_FAILURE', error: err.toString() });
        });
    }
}
  

Теперь я хочу использовать то же getUsers() самое, но с параметром id (например. getUsers({ UserId: 'jamesbond007' }) ),
И в действии я хочу dispatch({ type: 'GET_USER_BY_ID_SUCCESS', user: res.data.Data })

Как я могу отправлять разные действия с одним и тем же вызовом api? Должен ли я дублировать тот же код, но изменять отправку действий? При этом он становится повторяющейся функцией.

Ответ №1:

Вы можете определить действие по параметру id, например

 // all users, paramId is null
// a user, paramId is xxxx
const action = paramId ?
     { type: 'GET_USER_BY_ID_SUCCESS', user: res.data.Data } :
     { type: 'GET_USERS_SUCCESS', allUsers: res.data.Data };
dispatch(action);
  

Но, я думаю, ваша идея не очень хороша. Лучше выполнить логику в 2 методах. Он читаем.

Ответ №2:

Я нашел способ сделать это. Я объявляю переменные REQUEST, SUCCESS, FAILURE и проверяю, содержит ли объект param UserId . Если да, он отправит GET_USER_BY_ID вместо GET_USERS .

 export function getUsers (params) {
    let REQUEST, SUCCESS, FAILURE;

    if (!_.isEmpty(params) amp;amp; params.UserId) {
        REQUEST = 'GET_USER_BY_ID_REQUEST';
        SUCCESS = 'GET_USER_BY_ID_SUCCESS';
        FAILURE = 'GET_USER_BY_ID_FAILURE';
    } else {
        REQUEST = 'GET_USERS_REQUEST';
        SUCCESS = 'GET_USERS_SUCCESS';
        FAILURE = 'GET_USERS_FAILURE';
    }

    return async dispatch => { 
        await dispatch({ type: REQUEST });

        const urlParams = params ? new URLSearchParams(Object.entries(params)) : null;

        return axios({
            method: 'get',
            url: Environment.GET_USERS  `?${urlParams}`,
            headers: { 'Content-Type': 'application/json' },
        }).then (async res => {
            await dispatch({ type: SUCCESS, payload: res.data.Data });
        }).catch (err => {
            dispatch({ type: FAILURE, error: err.toString() });
        });
    }
}
  

Обратите внимание, что в моем редукторе я использую только action.payload . Например:

 case 'GET_USERS_SUCCESS':
    return { ...state, isFetching: false, userList: action.payload };

case 'GET_USER_BY_ID_SUCCESS':
    return { ...state, isFetching: false, user: action.payload };