2015-10-10 23 views
27

Ho un'app React Native che utilizza il framework Redux e sto utilizzando il componente Navigator per gestire la navigazione. Ho avuto un po 'di problemi nel far funzionare la navigazione e non sono in grado di trovare alcun buon esempio di come farlo correttamente, quindi sto cercando aiuto e chiarimenti.Modo corretto per navigare con React Native, Redux e Navigator

Ecco il succo di quello che ho attualmente, che sta lavorando, ma non so se sto facendo bene:

Root componente

... 
renderScene(route, navigator) { 
    console.log('RENDER SCENE', route); 
    const Component = route.component; 
    return (
     <Component navigator={navigator} route={route} {...this.props} /> 
    ) 
} 

render() { 
    return (
     <Navigator 
      renderScene={(route, nav) => this.renderScene(route, nav)} 
      initialRoute={{ name: 'Signin', component: Signin }} /> 
    ) 
} 

Signin Componente

... 
componentWillReceiveProps(nextProps) { 
    if (!this.props.signedIn && nextProps.signedIn) { 
     console.log('PUSHING TO MAIN'); 
     nextProps.navigator.push({ name: 'Main', component: Main }); 
    } 
} 

Domande:

1: Il mio primo pensiero è che probabilmente dovrei spostare il codice navigator.push in un'azione. Tuttavia è componentWillReceiveProps il posto giusto per chiamare l'azione? Quando viene caricato il componente Signin, viene eseguita un'azione per accedere all'utente se ha già una sessione attiva. Per impostazione predefinita non sono registrati, quindi quando passano i prossimi oggetti di scena, controllo se è cambiato e quindi spingo a Main.

2: Nel mio log della console subito dopo 'PUSH TO MAIN' viene registrato Vedo due 'renda scena' tronchi:

[info] 'RENDER SCENE', { name: 'Signin', component: [Function: Signin] } (EXPECTED) 
[info] 'PUSHING TO MAIN' 
[info] 'RENDER SCENE', { name: 'Signin', component: [Function: Signin] } (WHY?) 
[info] 'RENDER SCENE', { name: 'Main', component: [Function: Main] } 

Sono curioso di sapere perché renda scena viene chiamato due volte (la prima uno è il componente Signin) se sto solo spingendo il componente Main.

Anche in origine nel metodo componentWillReceiveProps Stavo solo controllando:

if (nextProps.signedIn) { 
    nextProps.navigator.push({ name: 'Main', component: Main }); 
} 

ma questo ha causato la componente Main di essere spinto due volte.

+0

Facebook sta passando da Navigator a [NavigationExperimental] (https://github.com/ericvicenti/navigation-rfc), che sarà la libreria di navigazione supportata in futuro. –

+0

Facebook sta ora passando a [react-navigation] (https://reactnavigation.org/) – edmofro

risposta

10

NOTA: Il collegamento GitHub sotto è ormai deprecato, nei commenti del autore ha suggerito react-native-router-flux che è per lo stesso autore.

Ho appena aggiunto il supporto per Redux, con il mio nuovo componente https://github.com/aksonov/react-native-redux-router con rende la navigazione piuttosto facile, come chiamare Actions.login

+1

Lo sviluppo dei componenti è stato interrotto - purtroppo. L'alternativa non è molto buona e qualsiasi altra risorsa di navigazione è mal documentata o esemplificata. Il peggior caso 'Navigator' è difficile da legare ai negozi redux. – jsdario

+2

@aksonov La lib che hai menzionato è superba, o probabilmente la migliore. Ma nessuno qui sarà pronto per iniziare il loro nuovo progetto con una deprecata lib. quindi ti consiglio vivamente di aggiornare la risposta. :-) –

+0

Grazie. react-native-router-flux ha ora il supporto per il redux, per favore usalo :) – aksonov

2

1) Sì, spostarlo sul metodo, componentWillReceiveProps probabilmente non è corretto. È difficile refactoring quella parte per te in quanto non avrei quella logica da quel metodo su quel componente, vale a dire il signinComp dovrebbe ricevere lo stato di se ha una sessione di autenticazione o meno (e non capire per sé). Ne consegue che viene elaborato senza motivo; dal momento che se si è loggato si reindirizza. Effettuerò personalmente il controllo in renderScene, dato che il nav viene tramandato puoi semplicemente fare un push/pop sui componenti figlio e gestire tutta la tua logica in un renderScene.

2) Vedere la pila di navigazione come un mazzo di carte. Quando si imposta la scena è una carta, ma quando si spinge si aggiunge un'altra carta alla pila. Quindi, quando spingi e hai due carte, controlla che tutte le carte siano a faccia in su e rese in modo tale che quando premi indietro o fai il pop torna a una carta o scena completata. Immagina di spingere immediatamente 5 scene in pila. Quindi quando cambi lo stack controlla che tutto sia pronto e pronto per quel pulsante. Personalmente non lo trovo ottimale (ma deve, dal momento che è possibile passare diverse proprietà con ogni scena che si spinge).

probabilmente si può cambiare questa linea a:

renderScene={this.renderScene} 
+0

Ho trovato un progetto Redux che esegue il routing: https://github.com/soliury/noder-react-native e come ho refactored il mio codice la tua risposta al punto n. 1 era corretta. Dopo il refactoring, i miei componenti erano molto più puliti e non necessitavano di 'componentWillReceiveProps'. Anche il numero 2 è andato via come risultato del refactoring. Grazie! – DennyFerra

+0

@DennyFerra Come rifattorizzare il codice? Ho bisogno di risolvere anche il problema. – deju

+0

@DennyFerra Ho letto il codice che hai dato e non ne avevo idea. – deju

3

Questa non è un'implementazione redux ma per il routing ho trovato reagire-native-router-flux per essere veramente utile.

si possono fare cose come chiamata

Actions.login 

per passare alla visualizzazione di login. I percorsi sono definiti nel tuo file di indice e hanno schemi opzionali per definire gli elementi della barra di navigazione.

https://github.com/aksonov/react-native-router-flux

+2

Come fai a consegnare cose stateful? Ad esempio, nelle azioni di caricamento, il mio applicaton è in LOGIN_STATE, quindi voglio caricare la pagina di accesso. –

+0

Basta chiamare Actions.login() all'interno del tuo codice nativo reattivo. – aksonov

0

Question1:
vi consiglio di processo logico navigatore metodo shouldComponentUpdate, come qui di seguito,

shouldComponentUpdate(nextProps, nextState){ 

    if(nextProps.isLoggedIn != this.props.isLoggedIn && nextProps.isLoggedIn === true){ 
     //will redirect 
     // do redirect option 

     return false; 
    } 

    return true; 
} 

la domanda 2:
credo che questo sia il bug di reagire-native.

Problemi correlati