Reputation: 111
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
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
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
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