使用Redux通过React-Navigation创建受保护的路由

问题描述 投票:3回答:3

我们如何使用redux在react-navigation中创建受保护的路由?

考虑我有一个包含以下状态的redux商店

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

我正在使用React-navigation来导航用户。

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);

现在,如果用户未登录,我想重定向到登录屏幕。

在简单的react-redux中,这就是我通常习惯做的事情:https://github.com/irohitb/SelfieApp/blob/master/client/src/routes.js

有人可以帮我弄清楚我们如何在react-native,redux和react-navigation中创建受保护的路由

javascript reactjs react-native redux react-navigation
3个回答
5
投票

react-navigation有createSwitchNavigator完全适合像这样的Authentication Flow

您必须将受保护的路由分组到一个MainStack中。使用createStackNavigator

const MainStack = createStackNavigator(
  {
    home: { screen: HomeScreen },
    events: { screen: EventsScreen },
    profile: { screen: ProfileScreen },
    ...
  {
    initialRouteName: "home"
  }
);

然后,再次使用createStackNavigator配置您的身份验证堆栈:

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

现在来了createSwitchNavigator - 加载MainStack堆栈或AuthStack

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

export default createAppContainer(Routes);

如果用户通过身份验证,createSwitchNavigator将加载保存逻辑的InitialLoadingScreen

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);

如您所见,您可以将InitialLoadingScreen连接到redux存储,访问任何数据并将其用于路由逻辑:)


2
投票

所以你有一个redux状态变量isAuthenticated

在每个屏幕中,您需要检查此状态,如果未登录,则将用户登录到登录屏幕并重置导航堆栈。

你可以检查在第一次运行时调用的任何生命周期方法,

例如,constructorcomponentWillMountcomponentDidMount等......

用于还原状态检查,

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

并且为了清除整个堆栈,您需要创建我们在上面部分中调用的操作。

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

并且您必须在文件中更改一些逻辑,其中您已经编写了合并reducer的代码,

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

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

这将重置整个减速器。

现在,如果你想要注销按钮,那么onPress的按钮只需将isAuthenticated更改为false并点火导航方法和注销操作即可。


0
投票

你可以使用react-native路由器通量进行导航

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

样品:

<Text
    style={alerts.btn}
    onPress={
        () => Actions.question(
            // send data 
            {
                'code': data_1,
            })}>
    Go to Home
</Text>
© www.soinside.com 2019 - 2024. All rights reserved.