Error in Redux-tookit: The store is missing a valid reducer. Ensure that the argument provided to combineReducers is an object containing reducers as values

Uh oh! Looks like there's an error with the Store reducer. The argument passed to combineReducers needs to be an object with valid reducers.

I'm having trouble setting up a Store for my app and I can't figure out where I went wrong. Could someone help me identify the issue and suggest how to resolve it?

store

import { configureStore } from '@reduxjs/toolkit';
import rootReducers from './reducers';

const store = configureStore({
  reducer: rootReducers,
});

export default store;

reducer

import handleCart from './handleCart';
import { combineReducers } from 'redux';

const rootReducers = combineReducers({
  handleCart,
});

export default rootReducers;
const cart = [];

const handleCart = (state = cart, action) => {
  const product = action.payload;
  switch (action.type) {
    case ADDITEM:
      // Check if product already exists
      const exist = state.find(x => x.id === product.id);
      if (exist) {
        return state.map(x =>
          x.id === product.id ? {...x, qty: x.qty + 1} : x,
        );
      } else {
        const product = action.payload;
        return [
          ...state,
          {
            ...product,
            qty: 1,
          },
        ];
      }
      break;
    case REMOVEITEM:
      const exist1 = state.find(x => x.id === product.id);
      if (exist1.qty === 1) {
        return state.filter(x => x.id !== exist1.id);
      } else {
        return state.map(x =>
          x.id === product.id ? {...x, qty: x.qty - 1} : x,
        );
      }
      break;
    default:
      break;
  }
};

Answer №1

Upon reviewing the handleCart reducer function code, there are a few noticeable issues that may result in exceptions being thrown. One issue is the missing return of state in the default case of the handleCart reducer function. Additionally, the REMOVEITEM case assumes the existence of the variable exist, which could potentially lead to accessing a qty property of an undefined object. It's important to remember that Array.prototype.find returns undefined when no matching element is found in the array.

Ensure that the handleCart is exported as the default so it can be imported to create the root reducer.

const cart = [];

const handleCart = (state = cart, action) => {
  const product = action.payload;

  switch (action.type) {
    case ADDITEM: {
      // Check if product exists
      const exist = state.find(x => x.id === product.id);

      if (exist) {
        return state.map(x =>
          x.id === product.id ? { ...x, qty: x.qty + 1 } : x,
        );
      }
      return [...state, { ...product, qty: 1 }];
    }

    case REMOVEITEM: {
      const exist = state.find(x => x.id === product.id);

      if (exist) {
        // Item exists, update quantity
        if (exist.qty === 1) {
          return state.filter(x => x.id !== exist1.id);
        } else {
          return state.map(x =>
            x.id === product.id ? { ...x, qty: x.qty - 1 } : x,
          );
        }
      }
      // Item didn't exist, just return current state
      return state;
    }

    default:
      // No action required, return current state
      return state;
  }
};

export default handleCart;

Although you are using redux-toolkit, consider creating a state slice. Here's a similar implementation using createSlice. This approach allows for writing reducer functions with mutable updates instead of having to shallow copy all updated parts of the state.

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

const initialState = [];

const cartSlice = createSlice({
  name: "cart",
  initialState,
  reducers: {
    addItem: (state, action) => {
      const product = state.find(product => product.id === action.payload.id);

      if (product) {
        product.qty++;
      } else {
        state.push({ ...action.payload, qty: 1 });
      }
    },
    removeItem: (state, action) => {
      const product = state.find(product => product.id === action.payload.id);

      if (product) {
        product.qty--;
        if (product.qty === 0) {
          state.filter(product => product.id !== action.payload.id);
        }
      }
    },
  },
});

export const { addItem, removeItem } = cartSlice.actions;

export default cartSlice.reducer;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

javascript monitoring numerous socket channels for echoes

Currently, I am in the process of developing a chat application. On the server side, I am utilizing: php, laravel 5.4, and pusher. On the client side, I have incorporated vue.js along with laravel-echo. Initially, I successfully created a "public chat roo ...

Angucomplete Alternative solves the challenge of accessing remote URLs

I have been using the Angucomplete Alt directive for creating an autocomplete feature. It has been working well so far, but now I want to customize a specific request to be sent to my server. <div angucomplete-alt id="input-name" ...

Adding hidden elements with jQuery: A comprehensive guide

I need assistance with adding the "is-hidden" class at this specific spot <span class="tag is-danger is-rounded is-small is-bolded span_notif_count ... "></span> As a beginner in jQuery, I am unsure about how to proceed. Could someon ...

Tips for resolving the final item issue in Owl Carousel when using right-to-left (RTL)

Encountering a bug with the rtl setting in owl-carousel. When the rtl is applied to the slider and I reach the last item, the entire slider disappears! Here's the code snippet: var viewportWidth = $("body").innerWidth(); if (viewportWidth & ...

Develop a circular carousel using React JS from scratch, without relying on any third-party library

I am looking to replicate the carousel feature seen on this website. I want to mimic the same functionality without relying on any external libraries. I have found several resources explaining how to achieve this. Most suggest creating duplicate copies o ...

When JSON contains slashes, JSON.parse will trigger an error

I am struggling with a valid JSON generated using PHP like this: var json = <?php echo json_encode(['somearray']); ?>. Inside the array, there is an HTML string as shown below: $myArray = ['image' => '<img src="/img/f ...

I'm puzzled as to why my createDoorMethod is returning a string value instead of a number, even though I am passing it a number. Can someone help me

Currently enrolled in a web development course, I am diving into the world of Angular 2 and TypeScript. Despite following along with the video tutorial and using the same code, my implementation is not working as expected, leaving me puzzled. Here is the ...

What are the potential drawbacks of directly modifying the state in ReactJS?

According to the documentation, it is stated that An example provided explains how directly modifying state will not re-render a component: // Incorrect this.state.comment = 'Hello'; Instead, the correct way is to use setState(): // Correct ...

HtmlWebpackPlugin can cause issues with loading relative path files on websites that are not located in the root directory

I have set up webpack and the HtmlWebpackPlugin to automatically include bundled js and css files in an html template. new HtmlWebpackPlugin({ template: 'client/index.tpl.html', inject: 'body', filename: 'index.html' ...

Accessing new information seamlessly without the need for page refresh

For optimal mobile viewing of my website, I am considering implementing a select element. Here are the available options: HTML: <select name="select-choice-8" id="select-choice-nc"> <optgroup label="News"> & ...

Struggling with TypeScript and JsObservable? Let us assist you!

Having previous experience with JSRender, JSViews, and JSObservables, I recently embarked on a new project using TypeScript. Unfortunately, I am struggling to understand how to properly utilize TypeScript in my project, especially when it comes to referenc ...

An AngularJS-powered dynamic navbar

Apologies if my explanation is unclear, but I am struggling to find a simple way to convey the following information. I have set up a navigation bar that displays different categories of articles. These navigation items are pulled from a database and can ...

You can click on the link within the Leaflet Popup to trigger JavaScript functionality

My leaflet map is functioning with GeoJSON polygons and popups attached to each one. These popups display information about the polygon. I want a link inside the popup that, when clicked, triggers a JavaScript function to retrieve and display smaller polyg ...

Having Trouble with QR Code Generator Functionality

UPDATE: The initial code has been updated to implement the recommendations provided. I am currently working on a QR Code generator that updates every minute. Although I have developed the code below, I am encountering some errors and could use some assist ...

The AngularJS HTTP interceptor is a crucial component for handling

Is there a way to use an interceptor in AngularJS to log "finished AJAX request" when any request is completed? I've been exploring interceptors and currently have the following setup, but it triggers at the beginning of the request rather than the e ...

I encountered an issue while trying to integrate VideoJS with React

While using VideoJS, the video plays without any issues. However, I am facing an issue where the available source options are not being displayed as they should be. I attempted to use a plugin for the sources, but even then, the options didn't show u ...

Is OnPush Change Detection failing to detect state changes?

Curious about the issue with the OnPush change detection strategy not functioning properly in this demonstration. My understanding is that OnPush change detection should activate when a property reference changes. To ensure this, a new array must be set e ...

Checking the boxes in javascript

Hey there, I'm a JavaScript newbie and struggling to validate my check-boxes. Despite looking at multiple examples, the concept is still not sinking in for me. Could someone please provide guidance on how to properly validate my check-boxes? Additiona ...

Save the retrieved data in a variable and pass the entire JSON object as a prop to a React component

Having some trouble with my code. I need the app to fetch a JSON from an API and pass it as a prop so that each component file can use it and display the element on the screen. The issue is, I can't seem to figure out how to store the fetched informa ...

Missing ghost image appears when you drag and drop the file

New to JavaScript... As a rookie in coding, I often get interesting requests from my partner who is a kindergarten teacher. Recently, she asked me to create a "Function Machine" for her classroom activities. With some trial and error, I managed to put tog ...