Узел не может существовать дважды в дереве состояний (mobx-state-tree) - PullRequest
0 голосов
/ 24 марта 2019

Я получаю сообщение об ошибке Error: [mobx-state-tree] A node cannot exists twice in the state tree. Failed to add SearchModel@/results/0 to path '/selectedItem' при назначении значения selectedItem в следующей модели с помощью действия setSelectedItem.Я проверил документацию, и я не уверен, что является причиной этой проблемы.

Ценю любую помощь.спасибо!

const SearchModel = types
  .model({
    results: types.array(ItemModel, []),
    selectedItem:types.maybeNull(ItemModel,{ id: 0 })
  })
  .actions(self => ({   
    setSelectedItem(selItem) {
      console.log( 'typeof(selItem)', typeof(selItem));
      self.selectedItem=selItem;
    }
  }));

export default SearchModel;

Ответы [ 2 ]

1 голос
/ 17 июня 2019

Другое решение заключается в использовании _.deepCopy из библиотеки Lodash. Он более универсален, чем оператор распространения, поскольку он будет рекурсивно идти по всему дереву, а не на один уровень. Это полезно для больших деревьев, так что вам не нужно удваивать, увеличивать или увеличивать в четыре или четыре раза, и иметь трудно читаемый код.

Вот как вы будете использовать его с простым хранилищем дерева состояний mobx. Это очень элегантно, легко в использовании.

Имейте в виду: это рекурсивная функция передачи по копированию, поэтому производительность может быть плохой, если объект слишком велик.

import _ from 'lodash';
import { types, getRoot, destroy, flow } from "mobx-state-tree";
            
const SearchModel = types
  .model({
    results: types.array(ItemModel, []),
    selectedItem:types.maybeNull(ItemModel,{ id: 0 })
  })
  .actions(self => ({   
    setSelectedItem(selItem) {
      self.selectedItem = _.deepCopy(selItem);
    }
  }));

export default SearchModel;
1 голос
/ 27 марта 2019

Для тех, кто ищет решение для такого типа ошибок в будущем, я использовал оператор распространения, чтобы назначить мелкую копию selItem для self.selectedItem, и проблема исчезла.

Код должен был выглядеть следующим образом:

const SearchModel = types
  .model({
    results: types.array(ItemModel, []),
    selectedItem:types.maybeNull(ItemModel,{ id: 0 })
  })
  .actions(self => ({   
    setSelectedItem(selItem) {
      self.selectedItem = { ...selItem };
    }
  }));

export default SearchModel;
...