edbras
edbras

Reputation: 4404

Mobx-state-tree Clone also changes the original item?

I have the following model snippet:

nodeOrigin: types.maybe(types.reference(nodeState)),
node: types.maybe(nodeState),

And I start editing a node by the following function (the original node i saved so it can be used in a undo() function):

startEditing(node) {
    self.nodeOrigin = node;
    self.node = clone(node);
}

And in my render method the editing node is used like this:

<form className="form">
     <TextField margin='dense' value={getStore().node["name"]} />
</form>

But when I change the name and print the content of both the node and the original node, they have both the changed name. NodeOriginal should contain the original name. What am I doing wrong?

Upvotes: 1

Views: 1414

Answers (1)

jayarjo
jayarjo

Reputation: 16726

types.reference is tied to types.identifier. The thing you probably misunderstand here, is that types.reference references the types.identifier property of the given node and not the node itself.

When you clone you do not alter an id of the original node. types.reference is resolved on the fly from identifier cache by the given id, so it will always reference the node with the given id.

Moreover, given that id cannot be altered after initialization and that it should be unique across the whole node tree, I'd conclude that nodes having types.identifier property are not meant to be cloned with clone utility.

Alternatively, you could take a snapshot of the node you want to clone, manually update types.identifier property and create a new node from that. Something like:

const cloneWithNewId = (node, id) =>
      getType(node).create(Object.assign({}, getSnapshot(node), { id }));

Upvotes: 2

Related Questions