jhnxx
jhnxx

Reputation: 111

How can I merge this object into another one to update in React?

Let's suppose I have the following object in React:

{
  name: 'John Max',
  plan: { active: true }
}

And then, I have the following object:

{ fields: { "plan.active": false } }

How can I adapt this object in order to replace with the current object?

So, in this example, the plan[active] would become false instead of true. That would be the only change.

Upvotes: 2

Views: 321

Answers (3)

Rodrigo Rodrigues
Rodrigo Rodrigues

Reputation: 8546

You can implement a simple function that traverses the object by passing a path, that you can take from splitting your object key on the dots.

Something like this:

setpath = ([p,...ps], v, o) => ps.length ? setpath(ps, v, o[p]) : o[p] = v


const data = { name: "John Max", plan: { active: true } }
const input = { fields: { "plan.active": false } }

let [path, val] = Object.entries(input.fields)[0]  // path="plan.active", val=false

setpath(path.split("."), val, data)
console.log(data)  // {name: "John Max", plan: {active: false}}

If you plan to have multiple path-like fields in under fields, and want to update all of them in the object, you can use Array.foreach:

Object.entries(input.fields).forEach(([p,v]) => setpath(p.split("."), v, data))

Upvotes: 2

Rajneesh
Rajneesh

Reputation: 5308

In case if you have multiple properties to modify in the object then you can create two reduce loops & modify the source data. Something like this:

const source =   {name: 'John Max', plan: {active: true}, newObj: {testObj: {name: 'Old name'}}};

const target = { fields: { "plan.active": false, "newObj.testObj.name": 'New Name' } };

const modify = (source, target) => {
    return Object.entries(target.fields).reduce((acc, [k, v]) => {
        k.split('.').reduce((a, e, i) => {
            a[e] = i == k.split('.').length - 1 ? v : {};
            return a[e];
        }, acc);
        return acc;
    }, source);
};
console.log(modify(source, target));

As you can see there are multiple nested objects & modify method will mutate & return the source object.

Upvotes: 1

Gajanan Ambekar
Gajanan Ambekar

Reputation: 1

Note Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:

 setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

Upvotes: -1

Related Questions