eugenedrvnk
eugenedrvnk

Reputation: 483

Is it okay to dispatch slice's action from another action in redux-toolkit?

I'm using redux-toolkit and have 2 slices: "auth" and "profile"

auth => handle information about token
profile => handle information about user account

When user tries to login, I send request to api, that returns me the user token and account information. Then I need to save this information. I put token to corresponding field (in same slice). And I need to put my account information to "profile" slice (login processing takes place in the "auth" slice). Now i'm just dispatch setProfile action from 'auth' slice.

Is it anti-pattern to dispatch "profile" action from "auth" slice? Or I have to move this logic from redux to component? Or make "login" action outside of slice? Or do I need to keep it all in one slice?

// PROFILE SLICE | profile.js 

const initialState = {
  data: {},
  status: 'idle'
}

export const profileSlice = createSlice({
  name: 'profile',
  initialState,
  reducers: {
    setProfile(s, {payload: profile}) {
      s.profile = profile
    }
  }
})

export const {setProfile} = userSlice.actions;
export default profileSlice.reducer


// AUTH SLICE | auth.js

import {setProfile} from './profile' // import action creator from profile slice

const initialState = {
  token: null,
  status: 'idle'
}

export const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    setToken(s, {payload: token}) {
      s.token = token
    }
  }
})

export const login = ({email, password}) => dispatch => {
  return api.auth.login({
    email,
    password
  })
    .then(res => {
      const {token, ...profile} = res.data
      dispatch(setToken(token))
      dispatch(setProfile(profile)
    })
}

export const {setToken} = authSlice.actions;
export default authSlice.reducer

Upvotes: 10

Views: 17900

Answers (1)

markerikson
markerikson

Reputation: 67439

You can't dispatch actions inside of a slice / reducer, although you can certainly dispatch actions from within a thunk wherever it's written.

However, you can listen for another slice's actions in any other reducer, and in fact this is a pattern we encourage:

The one thing to be aware of when doing that is that if two different slices depend on each other, you can end up with a "circular import dependency" issue, in which case you need to extract some common functionality in order to break the import cycle:

https://redux-toolkit.js.org/usage/usage-guide#exporting-and-using-slices

In this specific case, I see that you're actually separating out the token value from the rest of the data. I would suggest dispatching a single action that has all the received login data, and let both slice reducers pick out the pieces that they care about.

Upvotes: 16

Related Questions