Sto lavorando a un'applicazione React/Redux che consente di aggiungere "widget" a una pagina e manipolati nello spazio 2D. È necessario che più widget possano essere selezionati e manipolati contemporaneamente. Una versione semplificata del mio albero dello stato attuale sembra qualcosa di simile a quanto segue ...Come comporre riduttori di ridondanza con stato dipendente
{
widgets: {
widget_1: { x: 100, y: 200 },
widget_2: { x: 300, y: 400 },
widget_3: { x: 500, y: 600 }
},
selection: {
widgets: [ "widget_1", "widget_3" ]
}
}
Io attualmente ho questo albero di proprietà di 2 riduttori uno gestire widgets
Stato e l'altro la gestione di selection
statali. Il riduttore di stato di selezione può essere semplificata come (nota: sto usando Immutable.js troppo) ...
currentlySelectedWidgets(state = EMPTY_SELECTION, action) {
switch (action.type) {
case SET_SELECTION:
return state.set('widgets' , List(action.ids));
default:
return state
}
}
Tutto questo sembra funzionare abbastanza bene, ma ora ho un requisito che Ho difficoltà a inserirsi in questo modello ...
Ai fini dell'interfaccia utente, è necessario che la selezione corrente abbia una proprietà x/y che riflette l'angolo in alto a sinistra delle coordinate x/y dei widget attualmente selezionati. Uno stato di esempio potrebbe sembrare ...
{
widgets: {
widget_1: { x: 100, y: 200 },
widget_2: { x: 300, y: 400 },
widget_3: { x: 500, y: 600 }
},
selection: {
x: 100,
y: 200,
widgets: [ "widget_1", "widget_3" ]
}
}
La logica qui è abbastanza semplice, ad es. trovare lo min()
di tutti i valori selezionati x
e ma non sono sicuro di come dovrei gestirlo in termini di composizione del riduttore poiché il riduttore currentlySelectedWidgets
non ha accesso alla parte dello stato dell'albero widgets
. Ho considerato ...
- unione dei riduttori in un riduttore: questa non sembra una soluzione scalabile.
- passando l'elenco corrente di widget in giro con l'azione: questo sembra particolarmente cattivo.
- trovare un modo migliore per modellare l'albero di stato: ho pensato, ma le versioni alternative sembrano avere altri svantaggi.
- Creazione di una personalizzata
combineReducers()
che può alimentare l'elenco di widget nel mio riduttorecurrentlySelectedWidgets()
come argomento aggiuntivo: Penso che questa potrebbe essere la mia migliore scommessa.
Sono ansioso di ascoltare altri suggerimenti su come gli altri gestiscono situazioni simili, sembra che gestire una "selezione corrente" debba essere un problema di stato comune che altri devono aver dovuto risolvere.
Dopo aver tentato di implementare l'approccio basato su thunk di Hummlas e questo approccio basato su reselect, mi sembra che questo approccio si adattasse meglio al mio modello e fornisse una soluzione più pulita e più manutenibile. Immagino che la regola generale che sto lentamente imparando non sia quella di memorizzare qualcosa nell'albero dello stato che può essere ricalcolato dall'albero esistente. – andykent
Ho dimenticato di menzionare, c'è un piccolo errore in questa risposta di esempio, l'ultimo 'minSelector (widget, selezionato)' dovrebbe leggere 'minCoordinateSelector (widget, selezionato)' è improbabile che qualcuno possa copiare questo codice così com'è, ma nel caso loro fanno. – andykent