FAQ: Managing Promise Lifecycle Actions - Using createSlice() with Async Action Creators

This community-built FAQ covers the “Using createSlice() with Async Action Creators” exercise from the lesson “Managing Promise Lifecycle Actions”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Learn Redux

FAQs on the exercise Using createSlice() with Async Action Creators

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!
You can also find further discussion and get answers to your questions over in Language Help.

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head to Language Help and Tips and Resources. If you are wanting feedback or inspiration for a project, check out Projects.

Looking for motivation to keep learning? Join our wider discussions in Community

Learn more about how to use this guide.

Found a bug? Report it online, or post in Bug Reporting

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

Just curious why you are unable to use the push array method to update the recipes state in this example?

i.e.:

    [loadRecipes.fulfilled]: (state, action) => {
      state.recipes.push(action.payload);
      state.isLoading = false;
      state.hasError = false;
    },

If you do so it provides a type of undefined error even though the empty array was defined the same way as it was within the usersSlice.js . Was able to complete this by using state.recipes = action.payload but I imagine that there are scenarios where you might not want to ‘overwrite’ the value.

1 Like

In the usersSlice example, the extraReducers object is shown as a second argument to createSlice. Shouldn’t this instead be an extra property to the options object?

What’s up with the brackets? Why can’t we use just
fetchUserById.pending
instead of
[fetchUserById.pending] ?

 extraReducers: {
    [fetchUserById.pending]: (state, action) => ({
      state.isLoading = true;
      state.hasError = false;
    })
1 Like

could you please tell me why we use () before curly brackets?

1 Like

Hello,
I have the same question !

Hi,

In Redux documentation (createReducer | Redux Toolkit) I saw that

Action creators that were generated using createAction may be used directly as the keys here, using computed property syntax:

const increment = createAction('increment')
const decrement = createAction('decrement')

const counterReducer = createReducer(0, {
  [increment]: (state, action) => state + action.payload,
  [decrement.type]: (state, action) => state - action.payload
})

The computed property syntax is explained in MDN documentation (Object initializer - JavaScript | MDN)

Starting with ECMAScript 2015, the object initializer syntax also supports computed property names. That allows you to put an expression in brackets [] , that will be computed and used as the property name.

// Computed property names (ES2015)
let prop = 'foo';
let o = {
  [prop]: 'hey',
  ['b' + 'ar']: 'there'
}

Hope it helps :slight_smile:

Hello,

Yes it doesn’t make sense we can’t use push() here…

1 Like

I was wondering why in the usersSlice, the extra reducers, they were each wrapped in parantheses? But they weren’t in the favoriteRecipes Slice.

Ex: in usersSlice …

[fetchUserById.pending]: (state, action) => ({
state.isLoading = true;
state.hasError = false;
}),

this is wrapped in parantheses??

I was just wondering if someone could explain why there are parantheses around it and not that way in allRecipesSlice??

It is definitely confusing. From what I understood, parentheses are required in arrow functions when they implicitly return and object. Otherwise, the content in parentheses is interpreted as the body of the function.
In the @reduxjs/toolkit documentation, the body of the function doesn’t have parenthesis and is using explicit return:

const incrementBy = createAction('incrementBy')

createSlice({
  name: 'counter',
  initialState: 0,
  reducers: {},
  extraReducers: {
    [incrementBy]: (state, action) => {
      return state + action.payload
    },
    'some/other/action': (state, action) => {},
  },
})

I guess that it works in allRecipesSlice both with or without pharanthesis (I tested it) because the extraReducers action types are not returning anything, but reasigning values of properties inside the state object. So I think that, to be sintactically correct, those function bodies in both userSlice and allRecipesSlice shouldn’t be enclosed within parenthesis.

Question: Add two booleans — isLoading and hasError — to the initialState property passed to createSlice. What should their initial values be?
Answer: HONEY I AM DONE GUESSING WHAT YOU WANT.

Question: Using the extraReducers property, add reducers for each of the promise lifecycle action types generated by createAsyncThunk .
Answer: Intruction unclear, had to see hint to copy. In that case, why bother giving me long paragraphs everytime?

Why don’t you just simply teach me that: thunk as an action creator, needs a section in createSlice besides original reducer for its own reducer, it’s name is extraReducers, with it we are able to do something to manage recipe state, loading state and error state during 3 stage (pending fulfilled rejected).