0

I've redux store which looks like below.

store = {
    a: {
        b: { value: "" }
    },
    c: { 
        d: { value: "" }
    }
};

From my component, I want to pass like below to minipulate value of b.

dispatch(doSomething({ value: 'my-value', place: "a.b" });

And, in my reducers, I want to handle like below.

doSomething: (state, action) => {
    const { value, place } = action.payload;
    state[place].value = value; // here, i want to refere -> state.a.b.value = value;
}

I don't want to handle like this:

doSomething: (state, action) => {
    const { value, place } = action.payload;

    if (place === 'a.b') state.a.b.value = value;
    else if (place === 'c.d') state.c.d.value = value;
}

How can I achieve it?

Siri
  • 79
  • 1
  • 15
  • Reducer should return a new object. So `{ ...state, {...state[place], value}}` – Rajesh Jan 04 '23 at 05:06
  • sorry for confusion. just updated the question. @Rajesh – Siri Jan 04 '23 at 05:12
  • 1
    There are many variations of this question [Accessing nested JavaScript objects and arrays by string path](https://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-and-arrays-by-string-path) – Andy Ray Jan 04 '23 at 05:15
  • Can you check this : https://jsfiddle.net/fc139sn8/ @Siri, let me know is this helpful or not – Mohammed Jan 04 '23 at 05:29
  • Thank you, all. I found an elegant solution provided by lodash `_.get` https://lodash.com/docs/4.17.15#get, from @AndyRay's comment. – Siri Jan 04 '23 at 06:53

2 Answers2

1

What you're trying to do is access/modify the object by string path. Maybe you can do something like this.

let store = {
    a: {
        b: { value: "" }
    },
    c: {}
};

console.log(store)

function setNestedValue(obj, path, value) {
    let i;
    path = path.split('.');
    for (i=0;i<path.length-1;i++) obj = obj[path[i]];
    obj[path[i]] = value
}

setNestedValue(store,"a.b", "xx")

console.log(store)
Mehul Thakkar
  • 2,177
  • 13
  • 22
1
const {value, place } = payload
let cur=state;
place.split(".").forEach((key, idx)=> {
 if(idx < place.length -1) {
cur[key] =value;
} else{
 cur=cur[key];
}
});

sent via mobile.. couldn't format much.. you can improvise this..

Karthikeyan
  • 406
  • 3
  • 14