Error message: Trying to modify state using Redux Thunk resulted in an unhandled promise rejection with the following error: [Immer] Immer can only set array indices and the 'length' property

When developing a React Native application with a persistent Redux store written in TypeScript, I encountered an issue:

I created a Thunk function that queries an API and receives question data in a fetch. The fetch operation works well, but when attempting to save data to the Redux Store using extraReducers, errors occur.

This is how my code looks:

First, I dispatch the Thunk in my page:

questionpage.tsx

-stuff-

    useEffect(() => {
        console.log('dispatching fetch')
        dispatch(fetchQuestions())

    }, []);

-render stuff-

The actual Thunk function makes a fetch call to the API:

export const fetchQuestions = createAsyncThunk('questions/fetchquestions', async () =>{
    let headers = new Headers();
    headers.append('Authorization', 'Basic ' + Base64.btoa(email + ":" + password))
    
    const response = await fetch(api + "/api/questions", {
            headers: headers,
            method: 'GET'
        })
    const stuff = await response.json();
    console.log(stuff)
    return stuff;

})

Then:

questionSlice

    extraReducers: (builder) => {
        builder.addCase(fetchQuestions.pending, (state, action) => {
          state.status = 'loading' // < when I comment this the console.log works
          console.log('pending')
        }),
        builder.addCase(fetchQuestions.fulfilled, (state, action) => {
          state.status = 'succeeded'
          // Add any fetched posts to the array
          state.questions = state.questions.concat(action.payload) // < comment this, console.log works
          console.log('fulfilled')
        })
        builder.addCase(fetchQuestions.rejected, (state, action) => {
          state.status = 'failed' // < when I comment this the console.log works
          state.error = action.error.message // < when I comment this the console.log works
          console.log('rejected')
        })
      } 

In the reducer, I use extraReducers to handle the different outcomes of the Thunk function. However, I face an error when trying to update the state:

[Unhandled promise rejection: Error: [Immer] Immer only supports setting array indices and the 'length' property]

This error occurs even when modifying non-array variables like state.status and also affects state.error and state.questions. The last one is an array, but the others are not.

I have tried troubleshooting based on Phry's comment about the state being treated as an array, but I couldn't find any indication of that in my code. It's a challenging situation for me, especially considering my level of experience.

Answer №1

After encountering an error related to Immer, I delved into the Redux documentation to understand why I couldn't modify state inside the Reducer as expected. Despite following the guidelines outlined in this section, my code still didn't function as intended.

I suspect that the issue lies with the implementation of extraReducers triggering the Immer error. To resolve this, I sought to achieve immutable updates in my code instead.

builder.addCase(fetchQuestions.fulfilled, (state, action) => {
            // Incorporate fetched questions into the existing array
            console.log('fulfilled')
            
            return state = {
                ...state,
                status: 'succeeded',
                questions: action.payload
            }
        })

Answer №2

When working with reducers, it's important to remember that you must copy your state since it is immutable. You cannot simply change a property on it directly.

Discover more information here

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

Can TypeScript verify the types of string aliases during typing?

Consider the following code snippet: type Firstname = string type Surname = string const firstname: Firstname = "John"; const surname:Surname = "Smith" function print(name: Firstname) { console.log(name) } /* * This should give a compile error * ...

Angular 2 Observables consistently deliver undefined results

I keep encountering an issue where I am always receiving 'undefined' in my component code. Any assistance on this matter would be greatly appreciated. When I attempt to write to the console, it consistently returns 'undefined'. I am c ...

Using Angular material to display a list of items inside a <mat-cell> element for searching

Can I use *ngFor inside a <mat-cell> in Angular? I want to add a new column in my Material table and keep it hidden, using it only for filtering purposes... My current table setup looks like this: <ng-container matColumnDef="email"> < ...

Enter the text within the TypeScript file where the cursor is positioned

I am interested in exploring certain inferred types within TypeScript code. This would be particularly beneficial for ensuring that the inferred types are precise, specific, and accurate in correct files. Is there a way to retrieve the type at a specific ...

What is the best way to ensure that consecutive if blocks are executed in sequence?

I need to run two if blocks consecutively in TypeScript, with the second block depending on a flag set by the first block. The code below illustrates my scenario: export class Component { condition1: boolean; constructor(private confirmationServic ...

In Visual Studio Code, the auto-import feature is limited to providing only absolute paths when using Lerna subpackages in TypeScript

Recently, I encountered a strange issue with my Visual Studio Code where it started suggesting only absolute imports from the sub-package level in my Lerna packages. For instance: https://i.sstatic.net/fr7FW.png The auto import is recommending the path @ ...

Tips for Simplifying Complex Switch Cases with Object Literals in TypeScript

I have a unique situation where I need to switch between two functions within an object literal. One function takes two numerical arguments, "A" and "B", while the other function only takes a single string argument, "C". My TypeScript code showcases my di ...

Solving Testing Flaws within React Native

I keep encountering the following testing errors: console.warn err! at node_modules/react-query/lib/core/mutation.js:115:32 at tryCallOne (node_modules/react-native/node_modules/promise/lib/core.js:37:12) at node_modules/react- ...

Ways to Resolve the "TS2533: Object May Be Either 'Null' or 'Undefined'" Error on a Dynamic Object

I'm encountering an issue with the following code snippet: interface Schema$CommonEventObject { formInputs?: { [key: string]: Schema$Inputs; } | null; } interface Schema$Inputs { stringInputs?: Schema$StringInp ...

The function this.listCatModel.push is not a valid operation

I have a dropdown that I want to populate using the following code: this.categoryService.GetListItem(this.GetAllcatListUrl).subscribe(data=>{ this.listCatModel=data, this.listCatModel.push({ id:0, name:'Main Category', parent ...

Is it possible to access the line number of a node using the TypeScript compiler API?

Is there a method to retrieve the line number of a node besides using node.pos? For example, something like node.lineNumber? ...

Is it possible to determine the type of a class-type instance using class decorators?

Explore this example of faltering: function DecorateClass<T>(instantiate: (...params:any[]) => T){ return (classTarget:T) => { /*...*/ } } @DecorateClass((json:any) => { //This is just an example, the key is to ensure it returns ...

How to build a customizable independent (No dependencies) service using Angular 15?

An injection token can be utilized to configure Angular services in a similar fashion. Nonetheless, it currently relies on the Module with Providers methodology for injecting configuration. Are there alternative methods available for configuring services ...

receiving an error message due to attempting to access an

I'm facing an issue with replacing objects in an array using JavaScript. I tried to use indexOf and splice methods, but it's not working as expected. The value returned by indexOf is '-1', indicating that the object is not found in the ...

Retrieve all the items listed in the markdown file under specific headings

Below is an example of a markdown file: # Test ## First List * Hello World * Lorem Ipsum * Foo ## Second List - Item 1 ## Third List + Item A Part of Item A + Item B ## Not a List Blah blah blah ## Empty ## Another List Blah blah blah * ITEM # ...

Accessing property values from a map in Angular

Is there a way to retrieve a property from a map and display it in a table using Angular? I keep getting [object Object] when I try to display it. Even using property.first doesn't show anything. //model export interface UserModel { room: Map ...

While using Angular CLI on GitLab CI, an error occurred indicating that the custom rule directory "codelyzer" could not be

ng lint is throwing an error on Gitlab CI stating: An unhandled exception occurred: Failed to load /builds/trade-up/trade-up/common/projects/trade-up-common/tslint.json: Could not find custom rule directory: codelyzer. The strange thing is that ng lint ru ...

What is the process for assigning a serial number to each row in the MUI DataGrid?

Initially, the server is accessed to retrieve some data. After that, additional data is added. While the data does not contain an ID, the form must still display a serial number. const columns: GridColDef[] = [ { field: 'id' ...

How can I exclude *.d.ts files from tslint checking?

Recently, I decided to integrate tslint into my workflow. Following the installation steps, I used the command: npm install tslint tslint-config-ms-recommended --save-dev My configuration file tslint.json now looks like this: { "extends": "tslint-co ...

Performing multiple ajax calls simultaneously in JavaScript using the React framework

Within my React application, I am faced with the challenge of handling an array of parameters (such as IDs) that need to be passed as parameters in a queue of ajax calls. The issue arises when this array exceeds 1000 items, causing the browser page to beco ...