Insanovation
Insanovation

Reputation: 345

React Redux Toolkit: TypeError: Cannot read property 'value' of undefined

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?

Upvotes: 2

Views: 5504

Answers (1)

Lin Du
Lin Du

Reputation: 102257

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.

Upvotes: 4

Related Questions