Aggiornamenti locali in strutture dati persistenti / immutabili

4

Sto entrando in ReactJS e sono intrigato ma anche confuso sulle strutture dati persistenti. Mi piace l'idea, ma non sono sicuro di come prendere la mia esperienza MV *, Mutevole, Osservabile sui binding nel progettare i componenti della vista e applicarla in modo sano.

Ad esempio, supponiamo di avere una struttura profondamente annidata:

Foo
  Bar
     Baz
      someValue
  Qux
  Quxx

Nella mia interfaccia utente, ho un componente che è un editor per someValue . In un paradigma di osservazione mutata farei qualcosa di simile a:

Baz.setSomeValue(newValue)  // trigger observers, etc...

Per quanto posso dire, l'equivalente con strutture di dati persistenti è qualcosa del tipo:

Foo = extend(Foo, { Bar:{ Baz:{ someValue: newValue } } });
// recompute with new value of Foo

Qual è il modello normale per incapsulare un componente che si occupa di Baz in modo che non debba conoscere l'intera struttura?

    
posta noah 01.04.2014 - 03:05
fonte

2 risposte

1

Quello che stai cercando è un "obiettivo" - è una funzione che ottiene o imposta una proprietà di un oggetto nidificato e genera una nuova versione dell'intero oggetto.

Ci sono alcune buone librerie di obiettivi in JS e, dopo aver familiarizzato con il concetto, non è difficile da implementare da solo.

    
risposta data 03.03.2016 - 12:59
fonte
0

Parte del tuo problema è che stai usando JavaScript e non un linguaggio di programmazione funzionale come ClojureScript. In ClojureScript avresti l'aiuto di atomi e update-in e assoc-in per aiutare con questi aggiornamenti strutturali annidati. Le lingue che non enfatizzano il fare tutto con strutture dati persistenti non sono ottimizzate per questo caso d'uso.

Tuttavia, detto questo, c'è un altro modo. Una cosa che ho preso è la modellazione di oggetti complessi (qualsiasi cosa composta da coppie chiave / valore) come entità. A ogni oggetto alla creazione verrebbe assegnato un ID immutabile (io ho usato gli ID BSON ma i GUID lo faranno). Quindi in questo modo puoi eliminare tutto il nidificazione:

function Entities(state){
  this.state = state || {}; //never mutated
}
Entities.prototype.update = function(id, immutableData){...};
Entities.prototype.get = function(id){...};

function Ref(id){
  this.id = id; //never mutated
}

var entities = new Entities();
entities = entities.update(1, {id: 1, name: 'Foo'});
entities = entities.update(2, {id: 2, name: 'Bar', children: [new Ref(1)]});
entities = entities.udpate(3, {id: 3, name: 'Baz', children: [new Ref(2)]});
entities = entities.update(3, entities.get(3).set('name', "Bazooka"))

Il metodo update non si modifica, ma restituisce una nuova rappresentazione dell'oggetto modificato dello stato dell'entità;

Usando Oggetti di riferimento, hai eliminato del tutto l'annidamento. Puoi usare gli interi effettivi invece di Ref s; tuttavia, ciò non chiarisce che ciò che hai nella tua matrice children è in realtà un riferimento ad un'altra entità. Il wrapping trasforma in modo efficace il numero intero in un tipo Ref . Spetta a te interpretare il tipo di riferimento come puntatore all'entità.

    
risposta data 15.09.2014 - 21:46
fonte

Leggi altre domande sui tag