0

I have a deeply nested redux state that looks like this:

{
    name: "Item One",
    children: [
    {
        name: "Item Two"
        children: [
            ....
        ]
    },
    {
        name: "Item Three",
        children: [
            ....
        ]
    }
    ]
}

I need to make it's copy, so that I could conveniently modify it, and then replace the state with it.

Unfortunately just using {...state} doesn't work, because all the nested children are not being copied, they still refer to the same objects. Is there a convenient workaround for this?

lumenwrites
  • 1,287
  • 4
  • 18
  • 35

2 Answers2

1

There are a couple of options:

  1. Use the update immutability helper which has some excellent docs on the React site,
  2. Use a package like clone which is optimised for this kind of thing.

I'd recommend the first as the syntax is particularly powerful, especially when dealing with large structures like a Redux store.

As an example from the docs:

import update from 'immutability-helper';

const newData = update(myData, {
  x: {y: {z: {$set: 7}}},
  a: {b: {$push: [9]}}
});

Allows you to modify deeply-nested properties without worrying about dangerous mutations on existing objects.

Tom Walters
  • 15,366
  • 7
  • 57
  • 74
0

The easiest shortcut for that is:

const clone = JSON.parse(JSON.stringify(state));

All in all that involves the problem of cloning an object, there are couple of answers on that topic out there, depending on stuff like:

  1. are there function references in the source object,
  2. are there dom elements involved,
  3. Date objects,
  4. and more…

But in that case, you are dealing with a »plain json Object«, since it is the redux state, so the method above will work.

Another way would be an recursive function which copies all the nested data, but as mentioned above, in this case you do not have to do it, since you dont have to worry about dom elements or other stuff alike.

philipp
  • 15,947
  • 15
  • 61
  • 106
  • I think Redux recommends the object be serializable in general. However, the one big caveat to `JSON.parse` (given that functions probably shouldn't be part of state) is `Date` (de)serialization. – CodingIntrigue Apr 26 '17 at 13:41
  • I updated my answer and added Date Objects to the list. However, this is definitely the »quick and dirty« approach, but in case you know that there aren't any »complicated« members, it will work without much code. – philipp Apr 26 '17 at 13:45