'Update a react-redux state too fast does not take the modification into account

I have an object stored in react-redux which contains multiple sub-objects, like:

MyObject =
{
  { id: 1, name: "object 1"}
  { id: 2, name: "object 2"}
  ...
}

This object can be updated very quickly multiple times, for example with a function like this:

function modifyMyObject() {
  //Load the object from Redux and create a clone to be modified
  let myObject = JSON.parse(JSON.stringify(this.props.myObject))

  //Change the properties of my object
  ...

  //Update the object on Redux
  this.props.setMyObject(myObject)
}

However I noticed that if I call modifyMyObject() very quickly with different modifications, the object is not updated properly. I guess that the state in redux does not have time to be updated before I try to make a new modification.

Here is the object slice :

import {createSlice} from '@reduxjs/toolkit'

const initialState = {
    value: {},
}

export const myObjectSlice = createSlice({
    name: 'object',
    initialState,
    reducers: {
        setMyObject: (state, action) => {
            state.value = action.payload
        },
    },
})

// Action creators are generated for each case reducer function
export const { setMyObject } = myObjectSlice.actions

export default myObjectSlice.reducer

Is there a better way to handle these quick changes? Or do you have a suggestion to improve this code? Thank you!



Solution 1:[1]

I'm posting here the solution to this problem which was suggested by HÄkenLid:

Method which is NOT working: in App.js, create a copy of the slice.state, modify it and save it to Redux:

function modifyMyObject() {
  //Load the object from Redux and create a clone to be modified
  let myObject = JSON.parse(JSON.stringify(this.props.myObject))

  //Change the properties of my object
  ...

  //Update the object on Redux
  this.props.setMyObject(myObject)
}

The problem: the object is out of date when saved.

The solution: In app.js:

function modifyMyObject(newObject) {
  this.props.updateMyObject(newObject) //call the function from the slice
}

In MyObjectSlice.js:

import {createSlice} from '@reduxjs/toolkit'

const initialState = {
    value: {},
}

export const myObjectSlice = createSlice({
    name: 'object',
    initialState,
    reducers: {
        updateMyObject: (state, action) => {
        let newObject = action.payload
        //-> insert here the logic to update the object <-    
        ...
        state.value = newObject
        },
    },
})

// Action creators are generated for each case reducer function
export const { updateMyObject } = myObjectSlice.actions

export default myObjectSlice.reducer

Solution 2:[2]

Are you trying try/catch block to handle JSON.parse? I hope this below can help you:

    function modifyMyObject() {
        function parseJSONSafely(str) {
            try {
                return JSON.parse(str);
            }
            catch (e) {
                console.err(e);
                // Return a default object, or null based on use case.
                return {}
            }
        }
        //Load the object from Redux and create a clone to be modified
        editedObject = parseJSONSafely(JSON.stringify(this.props.myObject))
        if (editedObject !== {}) {
            //Change the properties of my object
            editedObject['proterty'] = /* ... */
    
                //Update the object on Redux
            this.props.setMyObject(editedObject)
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Charles
Solution 2 VMT