mobx-state-tree
mobx-state-tree copied to clipboard
Using detach with an array, it cannot be reattached to the tree
Bug report
- [ X ] I've checked documentation and searched for existing issues
- [ X ] I've made sure my project is based on the latest MST version
- [ X ] Fork this code sandbox or another minimal reproduction.
Sandbox link or minimal reproduction code https://codesandbox.io/s/cool-lake-w7co5?file=/src/App.tsx
Describe the expected behavior
const detachedArray = detach(self.myArray); self.someOtherArray = cast(detachedArray);
should detach myArray
and its contents then reattach it at someOtherArray
.
Describe the observed behavior
[mobx-state-tree] Cannot add an object to a state tree if it is already part of the same or another state tree. Tried to assign an object to '/drawPile/0', but it lives already at '/3'
It appears that the contents of the array are not marked as detached properly.
I'm modeling a card game where I want to shuffle the "discard pile" and replace the "draw pile" with the shuffled cards. If I do it as above by detaching the array MST throws the "already lives" error. To work around this I must individually detach each element of an array instead of detaching the whole array.
See this codesandbox: https://codesandbox.io/s/cool-lake-w7co5?file=/src/App.tsx
I expected the reshuffleBad
and reshuffleGood
actions to be identical, but reshuffleBad
throws the above error.
Here's a code snippet from the sandbox
const CardsModel = t
.model({
discardPile: t.array(CardModel),
drawPile: t.array(CardModel)
})
.actions((self) => ({
reshuffleBad() {
//Crashes!
const discards = detach(self.discardPile);
const draws = detach(self.drawPile);
const shuffled = _.shuffle([...discards, ...draws]);
self.drawPile = cast(shuffled);
},
reshuffleGood() {
//No problem
const discards = self.discardPile.map(detach);
const drawDeck = self.drawPile.map(detach);
const shuffled = _.shuffle([...discards, ...drawDeck]);
self.drawPile = cast(shuffled);
}
}));