简体   繁体   中英

Redirect user after login with react-navigation and redux

I have a login component in React Native.

I use use react-navigation and redux to store isLoggedIn in my authReducer .

I want the user to be sent away from the login component if he/she is logged in. So it should never be possible to see the login page if you are already logged in.

I guess I have to setup the navReducer as they do at https://github.com/react-community/react-navigation/blob/master/examples/ReduxExample/src/reducers/index.js . I am just not sure what is meant by

// Start with two routes: The Main screen, with the Login screen on top.
const firstAction = AppNavigator.router.getActionForPathAndParams('Main');
const tempNavState = AppNavigator.router.getStateForAction(firstAction);
const secondAction = AppNavigator.router.getActionForPathAndParams('Login');
const initialNavState = AppNavigator.router.getStateForAction(
  secondAction,
  tempNavState
);

How would you normally protect some routes and force the user to log in and after he/she is successfully logged in, he/she should be sent to another route?

I have had this same problem with a current project of mine. Here is how I found a good solution. I am sure that some of my code could be refactored better...but it should help give you an idea. Basically, I am using token-based authentication and I check when the app renders if there is a token in local storage and if so, then the user is "authenticated". Any request this user makes to the server will have this token attached to it and the backend can verify if the token is valid, and if it is not, then I can return an action to remove the token, which will then log them out.

I have an index page like this:

import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import reducers from './reducers';
import ReduxThunk from 'redux-thunk';
import Content from './app';

class App extends Component {
  render() {
    const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));

    return(
      <Provider store={store}>
        <Content />
      </Provider>
    );
  }
}

export default App;

This allows me to use redux with my store in place...then I get my actual App content from my app.js file which looks like this:

import React, { Component } from 'react';
import { View, StatusBar, Platform, AsyncStorage, ActivityIndicator } from 'react-native';
import { Tabs, Drawer, LoginStack } from './config/router';
import { connect } from 'react-redux';
import { checkLogin } from './actions';

class Content extends Component {
  componentWillMount() {
    this.props.checkLogin();
  }

  render() {
    if (this.props.checkingUser) {
      return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <ActivityIndicator size="large" />
        </View>
      );
    }
    if (this.props.token) {
      if (Platform.OS === 'ios') {
        return <View><StatusBar barStyle="light-content" /><Tabs /></View>;
      }

      return <Drawer />;
    }

    return <View><StatusBar barStyle="light-content" /><LoginStack /></View>;
  }
}

const mapStateToProps = ({ auth }) => {
  const { token, checkingUser } = auth;

  return { token, checkingUser };
}

export default connect(mapStateToProps, { checkLogin })(Content);

Then I have my checkLogin action that looks like this:

export const checkLogin = () => {
  return (dispatch) => {
    doCheck(dispatch);
  }
}

const doCheck = async dispatch => {
  let token = await AsyncStorage.getItem('token');

  if (token) {
    dispatch({ type: LOGGED_IN, payload: token });
  } else {
    dispatch({ type: LOGGED_OUT });
  }
}

Make this in your Login, it will redirect you to Home

 componentWillReceiveProps(nextProps) { if(nextProps.checkingUser) { this.props.navigation.navigate('Home'); } } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM