Home > Software design >  Update state dynamically with nested levels of objects and array
Update state dynamically with nested levels of objects and array

Time:09-23

This is the problem

I'm trying to update the state of this object called singleCarers

I have the index of the roster in the rosters array i need to update

but the The key monday: needs to be dynamic & the key start: & finish: also needs to dynamic

const indexOfRoster = index;

const dayOfRoster = day;

const { value, name } = e.target;  // name represents either start: or finish: & value is the value of start or finish eg. name:value === start: "09:10"



{
  "rosters": [
    {
       
        "schedule": {

            "monday": {

                "start": "",
                "finish": "",

            },
        },

    },
]
}


CodePudding user response:

You have two problems:

  1. You need reference the object using Computed property names
  2. using a callback in set state requires you to return a new state from the function.
setSingleCarers((prevState) => {
  const updatedRosters = prevState.rosters.map((roster, index) => (
    index === indexOfRoster
      ? {  // update the target roster
          ...roster,
          schedule: {
            ...roster.schedule,
            [dayOfRoster]: {
              ...roster.schedule[dayOfRoster],
              [name]: value,
            },
          },
        }
      : roster,
  ));

  return {  // return the new State
    ...prevState,
    rosters: updatedRosters,
  };
}

this may seem excessive in which case you can look into solutions like immer or other libraries that make this sort of object manipulation easier instead of having to remember to do deep object copying

CodePudding user response:

Do not over think it, if you don't use complex data types this is the best option

JSON.parse(JSON.stringify(object))

const auxState = JSON.parse (JSON.stringify(reactState))

// now modify auxState
auxState[index][day]={
 start:"val",
 end:"val"
}

setReactState(auxState)

If you want to get fancy

function clone(obj) {
    if (obj === null || typeof (obj) !== 'object' || 'isActiveClone' in obj)
        return obj;

    if (obj instanceof Date)
        var temp = new obj.constructor(); //or new Date(obj);
    else
        var temp = obj.constructor();

    for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            obj['isActiveClone'] = null;
            temp[key] = clone(obj[key]);
            delete obj['isActiveClone'];
        }
    }
    return temp;
}

const auxState = clone(reactState)
// Modify auxState

setReactState (auxState)
  • Related