2015-10-30 11 views
11

Sto utilizzando React con Redux e l'interfaccia utente materiale per creare una webapp. La webapp è composta da diverse pagine e componenti. So che uno snack bar o una finestra di dialogo dovrebbero essere collegati direttamente a ciò che l'utente sta facendo. Tuttavia, mi piacerebbe rendere lo snackbar e il dialogo indipendenti sulle pagine e sui componenti. Un caso d'uso quindi sta visualizzando un messaggio come background synchronization of your data failed e un'azione retry now. La mia idea era di rendere lo snack bar su una pagina denominata RootFrame, che viene utilizzata per avvolgere tutte le altre pagine e per inviare il testo dello snackbar come carico utile di un'azione.Invia un'azione a Redux con l'azione successiva come payload per mostrare una barra di snack o una finestra di dialogo dell'IU materiale

azione Mio Redux per mostrare snack bar:

export function showSnackbar(message: string) { 
    return { 
    type: SHOW_SNACKBAR, 
    payload: message 
    }; 
} 

Naturalmente potrebbe anche essere buona per specificare il messaggio nell'azione invece di prendere il messaggio come argomento, ma non è questo il mio problema in questo momento. Il problema è: come posso usare questo sistema e visualizzare uno snack bar con un'azione? Posso cambiare la mia azione a

export function showSnackbar(message, action) { 
    return { 
    type: SHOW_SNACKBAR, 
    payload: { 
     message, 
     action 
    } 
    }; 
} 

e rendere il mio snack nel RootFrame come

<Snackbar 
    message={this.props.message} 
    ref='snackbar' 
    onDismiss={() => this.props.dispatch(dismissSnackbar())} 
    action='retry now' 
    onActionTouchTap={() => this.props.dispatch(this.props.action)} 
/>; 

Quando lo snack bar è respinto, l'azione cambia una variabile nello stato: snackbar.visible = false. Questo è usato per attivare lo snackbar (è reso quando snackbar.visible === true). Quando l'utente fa clic su retry now, l'azione per avviare la sincronizzazione (che viene passata al componente come oggetti di scena) deve essere inviata. Il problema è molto simile quando si usano i dialoghi. Quindi, non solo il testo da visualizzare, ma anche le prossime azioni possibili devono essere passati al componente.

Pensi che l'uso di Redux sia ok o che ci sia una soluzione migliore?

risposta

4

In realtà, adesso usign redux è stato modificato un po '. Usiamo createAction da redux-act, correttamente usiamo createReducer ulteriormente. In un componente usiamo connect decorator o class da react-redux. Il connettore fornisce stato redux, azioni inviate, oggetti di scena principali. Così per il nostro snack abbiamo:

  1. azioni:

    export const showMessageTop = createAction(); 
    export const closeMessageTop = createAction(); 
    
  2. Reducer:

    import {createReducer} from 'redux-act'; 
    import * as ac from '../actionCreators/messageTop'; 
    export default createReducer(
        { 
        [ac.showMessageTop]: (state, messageText) => ({messageText}), 
        [ac.closeMessageTop]:() => ({messageText: ''}), 
        }, 
        { 
        messageText: window.location.search === '?login=1' 
           ? 'Welcome' 
           : '', 
        } 
    ) 
    
  3. e un componente (uso decoratore al posto di classe):

    import {closeMessageTop} from '../../actionCreators/messageTop'; 
    import MessageTop from './MessageTop'; 
    @connect(state => ({ 
        // gettext: gettext(state.locale.messages), 
        messageText: state.messageTop.messageText, 
    })) 
    export default class MessageTopContainer extends React.Component { 
    ... 
    <button onClick={...bindActionCreators({onClose: closeMessageTop}, dispatch)}/> 
    

Quindi negli oggetti di scena attuali abbiamo this.props.messageText. E possiamo mostrare questa barra se abbiamo un messaggio, oppure possiamo invocare closeAction che imposta messageText nella stringa vuota.

+0

Penso che questo sia esattamente come sto usando Redux. Ma la mia domanda è: se voglio mostrare uno snack bar con un messaggio e un'azione (come 'undo' negli esempi su http://material-ui.com/#/components/snackbar), come posso passare il' annulla l'azione attraverso redux. Sarà una specie di azioni concatenate. – nightlyop

+1

Per passare qualsiasi azione tramite redux, è necessario associare l'invio a tale azione. Quindi in quell'esempio c'è un gestore che gestisce il tocco. 'OnActionTouchTap = {} this._handleAction'. la linea di fondo è: 'onActionTouchTap = {...bindActionCreators ({undo: this.undo}, dispatch)} '. Ti ho capito bene? – Errorpro

+0

Sì, sembra interessante. Lo proverò. Grazie. – nightlyop

Problemi correlati