2015-07-23 11 views
9

Sono abituato alle proprietà calcolate in Ember Object Model. È un modo conveniente per specificare proprietà calcolate che dipendono da altre proprietà.Come impostare le proprietà calcolate di Ember in Immutablejs e Redux e Flux e React

Say fullName dipende firstName e lastName, posso impostazione proprietà calcolato come funzione computeProperties e chiamare computeProperties ogni volta faccio un cambiamento.

Esempio:

function computeFullName(state) { 
    const fullName = state.get('firstName') + state.get('lastName'); 
    const nextState = state.set('fullName', fullName); 
    return nextState; 
} 

function computeProperties(state) { 
    const nextState = computeFullName(state); 
    return nextState; 
} 

// store action handler 
[handleActionX](state) { 

    let nextState = state.set('firstName', 'John'); 
    nextState = state.set('lastName', 'Doe'); 

    nextState = computeProperties(nextState); 

    return nextState; 
} 

Esiste un modo per automaticamente l'installazione calcolato proprietà in modo che non devo chiamare funzioni extra ogni volta. In Redux o in ImmutableJS.

risposta

11

Redux autore qui!

Using reselect as suggested by WildService è la strada da percorrere. Penso che non includeremo questo nel core perché reselect fa bene il suo lavoro e stiamo bene con esso essendo una libreria separata.

ho voluto sottolineare un paio di cose:

  • Anche con Riseleziona, non si vuole per calcolare i dati all'interno del vostro riduttore. I selezionatori dovrebbero operare su lo stato gestito da riduttori. In altre parole, i selettori sono il passaggio tra lo stato del negozio Redux e i componenti: non sono all'interno dei riduttori. È essenziale mantenere lo stato di Redux normalizzato in modo che sia facile da aggiornare.

  • Noi in realtà vi incoraggio a definire selettori fianco i riduttori pertinenti, in modo che quando si cambia la forma dello stato, non si dispone di cambiare i componenti -hanno sarebbe utilizzando i selettori invece. Potete vedere un esempio di questo nel Redux folder of Flux Comparison

  • Abbiamo un documentation page introducing reselect and describing how to use it for computing derived data. Controlla.

1

Per creare proprietà calcolate è possibile utilizzare la libreria osservabile standalone mobservable.

var user = mobservable.props({ 
    firstName: 'John', 
    lastName: 'Doe', 
    fullName: function() { 
    return this.firstName + this.lastName 
    } 
}); 

var nameViewer = mobservable.ObservingComponent(React.createClass({ 
    render: function() { 
     return (<span>{user.fullName}</span>) 
    } 
}); 

che dovrebbe essere l'essenza di esso, ora qualsiasi modifica o user.firstName lastName sarà rerender il componente nameViewer. È possibile combinare ulteriormente questo con le implementazioni di flusso come redux per modificare i dati e spingere l'utente stesso attraverso l'albero dei componenti. Si noti che l'oggetto utente stesso è non immutabile (in tal caso non sarebbe più osservabile dopotutto ;-)) Vedi anche questi violini trivial e slightly more interesting per alcuni esempi.

+0

Ho bisogno di una soluzione tra cui biblioteca Immutabile – eguneys

+0

In questo caso penso che bisogna codificare manualmente tale logica nei vostri negozi, o, che è più del reagiscono modo, come funzioni (utilità) che vengono utilizzati dai componenti , in base ai dati reali, in modo che durante ogni rendering il valore sia aggiornato. – mweststrate

+0

dovrei mantenere lo stato calcolato nei negozi o nello stato del componente di reazione? @mweststrate – eguneys

4

Check out reselect. Funzioni pure componibili per il calcolo efficiente dei dati derivati ​​dai negozi. Afaik ci sono piani per far sì che i selettori di Riseleziona nel core Redux ad un certo punto se si rivelano popolari. C'è un esempio per l'utilizzo di ImmutableJS nella parte inferiore del readme.

0

E qualcosa di simile?

export const getWidgetsWithComputedProps = widgets => { 
    return widgets.map(w => getWidgetWithComputedProps(w)); 
}; 

export const selectWidgetType = widget => { 
    switch (widget.type) { 
    case 'line': 
     return 'time-series'; 
    case 'pie': 
    case 'bar': 
     return 'cross-sectional'; 
    default: 
     console.warn('Back up: that type of widget does not exist!', widget.type); 
     return null; 
    } 
}; 

export const getWidgetWithComputedProps = createSelector(
    widget => widget, 
    selectWidgetType, 
    (widget, _type) => { 
    return {...widget, _type} 
    } 
); 
Problemi correlati