Redux: Combining reducers

Viewed 883

I am following the Redux tutorials on the Redux site and I am having difficulty using combine reducers. If I run my code without combine reducers, it works fine. As soon as I put the single reducer into the combined reducers function. I get this: Error: "reducer" is a required argument, and must be a function or an object of functions that can be passed to combineReducers. What am I doing wrong?

Here is the store before using combine reducers:

import { configureStore } from "@reduxjs/toolkit";
import CoinsAllReducer from "./slices/CoinsAll";
export const store = configureStore({
reducer: {
   coinsAll: CoinsAllReducer,
  },
});

and here is the slice:

import axios from "axios";
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";

const initialState = {
  coinsAll: [],
  status: "idle",
  error: null,
};

export const fetchAllCoins = createAsyncThunk(
  "coinsAll/fetchAllCoins",
  async () => {
    const res = await axios.get(
      `https://api.coingecko.com/api/v3/coins/markets/?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=false`
    );
    return res.data;
  }
);

export const coinsAll = createSlice({
  name: "coinsAll",
  initialState,
  reducers: {},
  extraReducers(builder) {
    builder
      .addCase(fetchAllCoins.pending, (state) => {
        state.status = "loading";
      })
      .addCase(fetchAllCoins.fulfilled, (state, action) => {
        state.status = "succeeded";
        state.coinsAll = action.payload;
      })
      .addCase(fetchAllCoins.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.error.message;
      });
  },
});

export const selectCoinsAll = (state) => state.coinsAll.coinsAll;
export const selectStatus = (state) => state.coinsAll.status;
export default coinsAll.reducer;

The above code works and gets the data from the endpoint.

Here is the store modified to use the combined reducer:

import { configureStore } from "@reduxjs/toolkit";
import reducer from "./rootReducer";

export const store = configureStore(reducer);

Here is the rootReducer:

import { combineReducers } from "redux";
import coinsAllReducer from "./slices/coinsAll";

const reducer = combineReducers({
  coinsAll: coinsAllReducer,
});

export default reducer;

I changed nothing in the slice. Any help would be appreciated, thanks.

2 Answers

configureStore takes an object with a reducer key.

It should be

export const store = configureStore({
  reducer, // <-- object shorthand for the imported root reducer
  // other configurations, etc...
});

You have to pass the combined reducer inside the configuration object to the configureStore method

export const store = configureStore({
  reducer:combinedReducer
});

Hence, your updated code should be

import { configureStore } from "@reduxjs/toolkit";
import reducer from "./rootReducer";

export const store = configureStore({reducer:reducer});

And since key and value is same, you can simply go with

import { configureStore } from "@reduxjs/toolkit";
import reducer from "./rootReducer";

export const store = configureStore({reducer});
Related