web-dev-qa-db-fra.com

Moyen de navigation correct avec React Native, Redux et Navigator

J'ai une application React Native utilisant le framework Redux et j'utilise le composant Navigator pour gérer la navigation. J'ai eu un peu de difficulté à faire fonctionner la navigation et je ne suis pas en mesure de trouver de bons exemples sur la façon de le faire correctement. Je cherche donc de l'aide et des éclaircissements.

Voici l'essentiel de ce que j'ai actuellement, qui fonctionne, mais je ne sais pas si je le fais bien:

Composant racine

...
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 }} />
    )
}

Composant de connexion

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

Des questions:

1: Ma première pensée ici est que je devrais probablement déplacer le code navigator.Push dans une action. Cependant, componentWillReceiveProps est-il le bon endroit pour appeler l'action? Lorsque le composant Signin est chargé, il déclenche une action permettant de connecter l'utilisateur s'il a déjà une session active. Par défaut, ils ne sont pas connectés. Ainsi, lorsque les accessoires suivants apparaissent, je vérifie si cela a changé, puis Push to Main.

2: Dans le journal de ma console immédiatement après la journalisation de "Push To Main", je vois deux journaux "RENDER SCENE":

[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] }

Je suis curieux de savoir pourquoi RENDER SCENE est appelé deux fois (le premier étant le composant Signin) si je ne pousse que le composant Main.

Également à l'origine dans la méthode componentWillReceiveProps, je vérifiais seulement:

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

mais cela a entraîné le fait que le composant Main soit poussé deux fois.

29
DennyFerra

NOTE: Le lien GitHub ci-dessous est maintenant obsolète, dans les commentaires le auteur suggéré react-native-router-flux qui est identique auteur.

Je viens d'ajouter le support pour Redux, avec mon nouveau composant https://github.com/aksonov/react-native-redux-router avec la navigation est très facile, comme appeler Actions.login

10
aksonov

Ce n’est pas une implémentation redux, mais pour le routage, j’ai trouvé très utile de réagir-native-router-flux.

Vous pouvez faire des choses comme appeler 

Actions.login 

pour accéder à la vue de connexion. Les itinéraires sont définis dans votre fichier d'index et disposent de schémas facultatifs pour définir les éléments de la barre de navigation.

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

3
ithinkiknowruby

1) Oui, déplacez-le en méthode, componentWillReceiveProps n'est probablement pas correct. Il est difficile de reformuler cette partie pour vous car je n’aurais pas cette logique de cette méthode sur ce composant, c’est-à-dire que signinComp devrait recevoir l’état de savoir s’il a une session d’authentification ou non (et ne pas le comprendre lui-même). Cela conduit à un traitement sans raison; puisque s'il est connecté, vous redirigez. Personnellement, je ferais cette vérification dans renderScene, puisque la navigation est transmise, vous pouvez simplement créer un push/pop sur des composants enfants et gérer toute votre logique dans un renderScene.

2) Voir la pile de navigation comme un jeu de cartes. Lorsque vous définissez la scène, il s'agit d'une carte, mais lorsque vous le poussez, une autre carte est ajoutée à la pile. Ainsi, lorsque vous appuyez et que vous avez deux cartes, il vérifie que toutes les cartes sont face visible et rendues de sorte que lorsque vous appuyez en arrière ou que vous les pressez, elles reviennent à une carte ou à une scène terminée. Imaginez que vous mettiez immédiatement 5 scènes sur la pile. Ainsi, lorsque vous modifiez la pile, il vérifie que tout est bien rendu et prêt pour le bouton Précédent. Personnellement, je ne trouve pas cela optimal (mais il le faut, car vous pouvez transmettre différentes propriétés à chaque scène que vous poussez).

Vous pouvez probablement changer cette ligne en:

    renderScene={this.renderScene}
2
Tjorriemorrie

Question 1:
Je vous recommande de traiter la logique du navigateur dans la méthode shouldComponentUpdate, comme ci-dessous,

   shouldComponentUpdate(nextProps, nextState){

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

        return false;
    }

    return true;
}

La question 2:
Je pense que c'est le bogue de react-native.

0
deju