3
votes

Utilisation de Redux pour créer des routes protégées avec React-Navigation (v.3 ou v.4)

Comment pouvons-nous utiliser redux pour créer des routes protégées dans react-navigation?

Considérez que j'ai un magasin redux contenant l'état suivant

const loginNavigation = createStackNavigator(
  {
    login: {
      screen: Login
    },
    signup: {
      screen: Signup
    }
  },
  {
    headerMode: "none"
  }
)

const allRoutes = createSwitchNavigator(
  {
    home: {
      screen: loginNavigation
    },
    user: {
      screen: user

  },
  {
    initialRouteName: "home"
  }
);

const App = createAppContainer(allRoutes);

Et j'utilise React-navigation pour naviguer dans l'utilisateur.

const mapStateToProps = state => {
  return {
    isAuthenticated: state.profileInfo.isAuthenticated,
    isLoaded: state.profileInfo.isLoaded,
    googleProfileLoading: state.profileInfo.googleProfileLoading
  }
};

Maintenant, si l'utilisateur n'est pas connecté, je veux être redirigé vers l'écran de connexion.

Dans un simple react-redux, voici ce que j'avais l'habitude de faire: https://github.com/irohitb/SelfieApp/blob/master/client/src/routes.js

Quelqu'un peut-il m'aider à comprendre comment pouvons-nous créer des routes protégées dans react-native, redux et react-navigation


0 commentaires

3 Réponses :


3
votes

Vous avez donc une variable d'état redux isAuthenticated .

Dans chaque écran, vous devrez vérifier cet état, s'il n'est pas connecté, puis que l'utilisateur doit ouvrir l'écran de connexion et réinitialiser la pile de navigation.

vous pouvez vérifier n'importe quelle méthode de cycle de vie qui sera appelée lors de la première exécution,

par exemple, constructeur , componentWillMount , componentDidMount , etc ...

pour la vérification de l'état de redux,

const appReducer = combineReducers({
  loginReducers: LoginReducers,
  ...
  ...
});

export default (rootReducer = (state, action) => {
  if (action.type == LOGOUT_SUCCESS) {
    state = undefined;
  }
  return appReducer(state, action);
});

et pour effacer toute la pile, vous vous devez créer une action que nous avons appelée dans la section ci-dessus.

export const logoutAction = () => {
  return dispatch => dispatch({ type: LOGOUT_SUCCESS });
};

et vous devez changer une certaine logique dans le fichier où vous avez écrit le code du réducteur de combinaison,

if(!this.props.isAuthenticated){
 this.props.logoutAction();
 this.props.navigation.navigate("Login");//Login or whatever your first screen is...
}

cela réinitialisera tout le réducteur.

Maintenant, si vous voulez créer un bouton de déconnexion, onPress du bouton changez simplement isAuthenticated à false et lancez la méthode de navigation et l'action de déconnexion, c'est tout.


0 commentaires

0
votes

vous pouvez utiliser le flux de routeur natif de réaction pour la navigation

https: //www.npmjs.com/package/react-native-router-flux

sample:

<Text
    style={alerts.btn}
    onPress={
        () => Actions.question(
            // send data 
            {
                'code': data_1,
            })}>
    Go to Home
</Text>


0 commentaires

8
votes

react-navigation a createSwitchNavigator exactement pour des cas comme celui-ci Authentification Flux .

Vous devez regrouper vos itinéraires protégés dans un seul MainStack. Utilisez createStackNavigator:

class InitialLoadingScreen extends React.Component {
    constructor(props) {
        super(props);
        this.bootstrapAsync();
    }

    bootstrapAsync = async () => {
        // Load the home screen for the logged in users 
        if (this.props.isAuthenticated) {
            return this.props.navigation.navigate('home');
        }

        // load the Auth screen if the user is NOT logged in
        this.props.navigation.navigate('login');
    }

    // Render any loading content that you like here
    render() {
        return (
            <View style={styles.container}>
                <ActivityIndicator />
            </View>
        );
    }
}

const mapStateToProps = ({ settings }) => ({
    isAuthenticated: state.profileInfo.isAuthenticated,
    isLoaded: state.profileInfo.isLoaded,
    googleProfileLoading: state.profileInfo.googleProfileLoading
});

export default connect(mapStateToProps)(InitialLoadingScreen);

Ensuite, configurez votre pile d'authentification, à nouveau en utilisant createStackNavigator:

const Routes = createSwitchNavigator({
    initialLoading: InitialLoadingScreen,
    auth: AuthStack,
    all: MainStack,
}, {
    initialRouteName: 'initialLoading',
});

export default createAppContainer(Routes);

Et maintenant vient le createSwitchNavigator - pour charger la pile MainStack ou la AuthStack :

XXX

Le createSwitchNavigator chargera InitialLoadingScreen qui contient la logique si l'utilisateur est authentifié ou non:

const AuthStack = createStackNavigator({
    login: { screen: LoginScreen },
    register: { screen: RegisterScreen },
    forgot: { screen: ForgottenPasswordScreen },
    ...
});


5 commentaires

En outre, il est bon de noter que l'utilisation du navigateur de commutation est en fait meilleure dans de nombreux cas. Parce qu'il démontera la route non focalisée, ce qui libère de la mémoire.


@Hristo, chaque fois que mon état de redux change, ma classe InitialLoadingScreen ne serait-elle pas restituée? par conséquent, à chaque changement d'état, ne redirigerait-il pas vers retourner this.props.navigation.navigate ('home') ou this.props.navigation.navigate ('login'); < / code>, je veux dire, considérez const MainStack de votre exemple, ne redirigerait-il pas vers l'écran initial (c'est-à-dire la maison) chaque fois que mon état de redux change?


@Ziyo pouvez-vous s'il vous plaît parcourir le commentaire ci-dessus et voir si vous pouvez m'aider


Non, il ne devrait pas être rendu. Le composant de commutation le transporte pour ne se produire qu'une seule fois, lorsque vous le chargez


Dans chaque état de redux, vos méthodes render () sont appelées. Non, vous ne serez pas redirigé, car la méthode bootstrapAsync est appelée depuis le constructeur . Le constructeur est appelé lorsque le composant est instancié (une fois).