Использует getState в хорошей практике Redux Thunk?

Я видел противоречивые (или просто запутывающие, мне) ответы на другие вопросы здесь относительно того, является ли использование getState внутри действия приемлемым или нет, и я видел довольно много раз, когда он называется анти-шаблоном, Для меня это работает отлично, но для чего лучше всего это делать, если мы не будем использовать getState?

Я использую getState внутри thunk для фильтрации через массив пользователей, который в настоящее время подключен к некоторым макету данных и втягивается в состояние приложения.

Вот код для моего действия:

export const accountLogInSuccess = user => ({
    type: types.ACCOUNT_LOG_IN_SUCCESS,
    user,
});

export const accountLogOutSuccess = () => ({
    type: types.ACCOUNT_LOG_OUT_SUCCESS,
});

export const accountCheckSuccess = () => ({
    type: types.ACCOUNT_CHECK_SUCCESS,
});

export const accountCheck = () => (
    (dispatch, getState) => {
        dispatch(ajaxCallBegin());
        return apiAccount.accountCheck().then((account) => {
            if (account) {
                const user = findByUID(getState().users, account.uid);
                dispatch(accountLogInSuccess(user));
                toastr.success(`Welcome ${user.nameFirst}!`);
            } else {
                dispatch(accountLogOutSuccess());
            }
            dispatch(accountCheckSuccess());
        }).catch((error) => {
            dispatch(ajaxCallError(error));
            toastr.error(error.message);
            throw (error);
        });
    }
);

И мой редуктор:

export default function reducerAccount(state = initial.account, action) {
    switch (action.type) {
    case types.ACCOUNT_LOG_IN_SUCCESS:
        return Object.assign({}, state, action.user, {
            authenticated: true,
        });
    case types.ACCOUNT_LOG_OUT_SUCCESS:
        return Object.assign({}, {
            authenticated: false,
        });
    case types.ACCOUNT_CHECK_SUCCESS:
        return Object.assign({}, state, {
            initialized: true,
        });
    default:
        return state;
    }
}

Исходное состояние учетной записи, используемое в моем редукторе, справедливо:

account: {
    initialized: false,
    authenticated: false,
},

Действие accountCheck передает пользователю (найденный с использованием функции getState и findByUID) в accountLogInSuccess, где редуктор добавляет свои значения в текущее состояние учетной записи через Object.assign.

Предпочитаете, что вам не нужно вводить пользователя в корень моего приложения, а затем передавать его через реквизиты, какова наилучшая практика для этого в Redux и наличие пользовательских данных в состоянии? Опять же, использование getState внутри thunk отлично работает для меня до сих пор, но есть ли лучшее решение для этого, которое не считается анти-шаблоном?

Ответ 1

Я написал расширенный пост в блоге, названный Idiomatic Redux: Мысли о Thunks, Sagas, Abstraction и Reusability, в котором подробно рассматривается этот вопрос. В нем я отвечаю на несколько критических замечаний и использования getState (включая комментарии Дэн Абрамов в Доступ к состоянию Redux в создателе действия?). На самом деле, мой пост был специально вдохновлен такими вопросами, как ваш.

Как TL; DR моего сообщения: я считаю, что thunks - вполне жизнеспособный инструмент для использования в приложениях Redux и поощряют их использование. Несмотря на то, что существуют некоторые опасные проблемы, связанные с использованием thunks и sagas, и используя getState/select внутри них, эти проблемы не должны отпугивать вас от использования thunks.