2

In my project I have implemented React Redux toolkit for 2 different states scenarios and they work perfectly. Now I needed to implement a 3rd state scenario for Redux, so I've followed the same pattern as for the first 2. Inspired from: https://react-redux.js.org/tutorials/quick-start

My 3rd state scenario has the following slice declaration:

import { createSlice } from "@reduxjs/toolkit";

export const betsSlice = createSlice({
  name: "bets",
  initialState: { value: { betsLeft: 0, betToBet: 0, usersBets: "" } },
  reducers: {
    updateBets: (state, action) => {
      state.value = action.payload;
    },
  },
});

export const { updateBets } = betsSlice.actions;

/**
 * Exporting to avoid boilerplate like:
 * const count = useSelector((state) => state.counter.value)
 */
export const getBets = (state) => state.bets.value;

export default betsSlice.reducer;

The store.js:

import { configureStore } from "@reduxjs/toolkit";
import themeModeReducer from "../features/themeMode/themeModeSlice";
import liveGeneralStatisticsReducer from "../features/liveGeneralStatistics/liveGeneralStatisticsSlice";
import betsReducer from "../features/bets/betsSlice";

export default configureStore({
  reducer: {
    themeMode: themeModeReducer,
    liveGeneralStatistics: liveGeneralStatisticsReducer,
    betsReducer: betsReducer,
  },
});

And in the component I'm calling at the beginning, as usually:

const betsRedux = useSelector(getBets);

But, unexpectedly, on render, I get: TypeError: Cannot read property 'value' of undefined

Pointing at:

  16 |  * Exporting to avoid boilerplate like:
  17 |  * const count = useSelector((state) => state.counter.value)
  18 |  */
> 19 | export const getBets = (state) => state.bets.value;
  20 | 
  21 | export default betsSlice.reducer;
  22 | 

I don't understand why is this happening, given that we have the initialState setup.

What would be the way to solve this, please?

3
  • 1
    Can you show your store setup file with the configureStore call? Commented Jun 3, 2021 at 17:31
  • 1
    You must be having a different key (not bets) for this reducer when configuring the store. Don't be confused with slice-name as it is the prefix value for the generated action types. See createSlice#name. You should write: bets: betsReducer instead of betsReducer: betsReducer. Commented Jun 3, 2021 at 17:35
  • 1
    Thanks a lot @markerikson and Ajeet Shah - yes, I had "betsReducer: betsReducer", as you can now see in the updated question. Thanks - all works now. :) Commented Jun 3, 2021 at 17:41

1 Answer 1

4

configureStore use combineReducers(reducers) underhood:

You can control state key names by using different keys for the reducers in the passed object. For example, you may call combineReducers({ todos: myTodosReducer, counter: myCounterReducer }) for the state shape to be { todos, counter }.

In your case, you should replace the betsReducer key with bets like this:

export default configureStore({
  reducer: {
    themeMode: themeModeReducer,
    liveGeneralStatistics: liveGeneralStatisticsReducer,
    bets: betsReducer,
  },
});

The state shape will be: { themeMode, liveGeneralStatistics, bets }

Then, the export const getBets = (state) => state.bets.value; selector will work.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.