Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is using getState in a Redux Thunk good practice?

I have seen conflicting (or just confusing, to me) answers in other questions here regarding whether using getState within an action is acceptable, or not, and I have seen quite a few times it being called an anti-pattern. For me, it seems to work great but what is the best practice for doing this if we are not to use getState?

I am using getState within a thunk to filter through an array of users that is currently connected to some mock data and being pulled into the state of the application.

Here is the code for my action:

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

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

The initial state of account used in my reducer is just:

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

The accountCheck action passes the user (found using getState and the findByUID function) into accountLogInSuccess where the reducer adds its values to the current state of account via Object.assign.

Preferring to not have to get the user at the root of my application and then passing it down via props, what is the best practice to accomplish this within Redux and having the user data be available in state? Again, using getState within the thunk works great for me thus far, but is there a better solution to this that is not considered an anti-pattern?

like image 556
spunge Avatar asked Apr 06 '17 06:04

spunge


People also ask

What is getState in redux-thunk?

If you pass a function into dispatch , the thunk middleware sees that it's a function instead of an action object, intercepts it, and calls that function with (dispatch, getState) as its arguments. If it's a normal action object (or anything else), it's forwarded to the next middleware in the chain.

Is redux-thunk necessary?

A very common pattern in Redux is to use things called a Thunks, which are a way of wrapping up certain logic of a subroutine in a single function.

Why is redux-thunk better than Redux?

But on the other hand, for bigger projects, Redux-Thunk may sometimes get you in trouble, as it can be hard to scale if your side effect or asynchronous logic increases, whereas in the case of Redux-Saga, it comes power-packed with some amazing things such as concurrent side effects, canceling side effects, debouncing ...


1 Answers

I wrote an extended blog post called Idiomatic Redux: Thoughts on Thunks, Sagas, Abstraction, and Reusability, which addresses this topic in detail. In it, I respond to several critiques of thunks and use of getState (including Dan Abramov's comments in Accessing Redux state in an action creator?). In fact, my post was specifically inspired by questions like yours.

As a TL;DR of my post: I believe that thunks are a completely viable tool for use in Redux applications, and encourage their use. While there are some valid concerns to be aware of when using thunks and sagas, and using getState/select inside of them, these concerns should not scare you away from using thunks.

like image 140
markerikson Avatar answered Sep 22 '22 13:09

markerikson