#mobx-react #mobx-state-tree
#mobx-реагировать #mobx-state-tree
Вопрос:
У меня есть следующий фрагмент модели:
nodeOrigin: types.maybe(types.reference(nodeState)),
node: types.maybe(nodeState),
И я начинаю редактировать узел с помощью следующей функции (исходный узел, который я сохранил, чтобы его можно было использовать в функции отмены ()):
startEditing(node) {
self.nodeOrigin = node;
self.node = clone(node);
}
И в моем методе рендеринга узел редактирования используется следующим образом:
<form className="form">
<TextField margin='dense' value={getStore().node["name"]} />
</form>
Но когда я меняю имя и печатаю содержимое как узла, так и исходного узла, у них обоих измененное имя. Исходный узел должен содержать исходное имя. Что я делаю не так?
Комментарии:
1. Рассмотрите возможность создания интерактивного элемента на codesandbox.io/dashboard
Ответ №1:
types.reference
привязано к types.identifier
. То, что вы, вероятно, неправильно понимаете здесь, это то, что types.reference
ссылается types.identifier
на свойство данного узла, а не на сам узел.
Когда вы clone
не изменяете id
исходный узел. types.reference
разрешается «на лету» из кэша идентификаторов с помощью заданного id
, поэтому он всегда будет ссылаться на узел с заданным id
.
Более того, учитывая, что идентификатор не может быть изменен после инициализации и что он должен быть уникальным во всем дереве узлов, я бы сделал вывод, что узлы, обладающие types.identifier
свойством, не предназначены для клонирования с помощью clone
утилиты.
В качестве альтернативы вы могли бы сделать снимок узла, который хотите клонировать, вручную обновить types.identifier
свойство и создать из него новый узел. Что-то вроде:
const cloneWithNewId = (node, id) =>
getType(node).create(Object.assign({}, getSnapshot(node), { id }));
Комментарии:
1. Хммм, ваше последнее предложение не работает, что я делаю: получаю snapshot(self.node).id = 123 и это приводит к: Не удается присвоить свойству ‘id’ объекта ‘#<Object>’ только для чтения. Есть идеи, что идет не так?
2.
getSnapshot
создает замороженный объект, поэтому вместо того, чтобы изменять его напрямую, создайте новый:Object.assign({}, getSnapshot(node), { id: 'new id })