在Redux Thunk中使用getState是一个好的实践吗?

41
我曾在这里的其他问题中看到了关于是否可以在操作内部使用 getState 的相互矛盾(或只是令我困惑)的答案,我也多次看到将其称为反模式。对我来说,它似乎很好用,但如果我们不使用 getState,那么如何做才是最佳实践呢?
我在一个thunk中使用getState来过滤一个连接到一些模拟数据并被拉入应用程序状态的用户数组。
这是我的操作代码:
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);
        });
    }
);

而我的Reducer:

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;
    }
}

我 reducer 中使用的帐户的初始状态只是:

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

accountCheck操作会通过getStatefindByUID函数找到用户,并将其传递给accountLogInSuccess,在那里reducer使用Object.assign将其值添加到当前账户状态中。

在Redux中,不想通过props从应用程序的根组件获取用户并传递下去,有什么最佳实践方法可以在状态中使用用户数据?目前,在thunk中使用getState对我来说已经很好了,但是是否有更好的解决方案,而又不被认为是反模式呢?

1个回答

46
我写了一篇扩展博客文章,名为《通俗易懂的 Redux:关于 Thunks、Sagas、抽象和可重用性的思考》,详细讨论了这个主题。在文章中,我回应了几个对 Thunks 和使用 getState 的批评(包括 Dan Abramov 在 《如何在 action creator 中访问 Redux state?》 中的评论)。事实上,我的文章是特别受到像你这样的问题启发的。
作为我的文章的 TL;DR:我认为 Thunks 是在 Redux 应用中完全可行的工具,并鼓励它们的使用。虽然在使用 Thunks 和 Sagas 以及在其中使用 getState/select 时有一些需要注意的有效问题,但这些问题不应该让你远离使用 Thunks。

24
在中间件中使用 getState 是一种不好的做法吗?这个答案似乎回答了使用 thunk 是否是好的做法。 - JBaczuk
3
不,正如我的博客文章所说的那样,并不是一种不好的做法。 - markerikson
37
很酷,把它放在答案中会更好,这样就不是仅有链接的答案了。 - JBaczuk
5
这是一个糟糕的回答,因为内容只存在于短暂的链接中。 - FlavorScape
1
@JCraine:不确定你在这里抱怨什么。值得一提的是,虽然Dan创建了Redux,但自2016年中期以来,我一直是主要的维护者。今天,我们仍然将thunks作为异步逻辑的默认方法进行教学,并且getState是thunk API的标准部分。如果它不应该被使用,那么它就不会存在 :) - markerikson
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接