title: Authentication and authorization in react-native using redux and asyncStorage
body: <p>I am a newbie in react-native and react-redux. I am working on a react native project in which i wanted to implement authentication and authorization. For some miliseconds, i wanted to show splashscreen, if user is not logged in then redirect to login page else redirect to dashboard page. If user logged out, then navigate to login screen. i am using react-native 0.62, react-navigation 5.x and redux 7.2. i have created one stacknavigator for login screen, forgot password screen, otp screen and reset password screen. and one drawernavigator for drawer which contains dashboard screen, lms screen, my profile screen and logout. i have implemented the api using redux-thunk. i am not able to redirect to dashboard. Currently, i have checked the condition using static value with UseStatic. i don't know whether it is correct or not. i have remember me checkbox in the login screen. so if the user check that checkbox then the necxt the user wont need to enter the credentials until user logs out.
  I exhausted as i am not getting what is redux and asyncStorage and how to use it</p>
  <pre><code>App.js file
  import 'react-native-gesture-handler';
  enableScreens();
  import React, { useState, useEffect } from 'react';
  import { enableScreens } from 'react-native-screens';
  import { StatusBar } from 'react-native';
  import { Provider, connect } from 'react-redux';
  import { NavigationContainer } from '@react-navigation/native';
  import { createStackNavigator } from '@react-navigation/stack';
  
  import store from '../store/store';
  import SplashScreen from '../screens/splashScreen';
  import MainStack  from '../routes/MainStack';
  import MainNavigator  from '../routes/MainNavigator';
  
  
  const RootStack = createStackNavigator();
  
  const App = () =&gt; {
    const [isLoading, setIsLoading] = useState(true);
    const [auth, setAuth] = useState(false);
  
    useEffect(() =&gt; {
      setTimeout(async () =&gt; {
        setIsLoading(!isLoading);
        setAuth(false);  
      }, 2000)
    }, []);
  
  
  
    return (
      &lt;Provider store={store}&gt;
        &lt;NavigationContainer&gt;
          &lt;StatusBar backgroundColor={isLoading ? '#000000' : '#F3F3F3'} /&gt;
                  {isLoading ?
            
              &lt;SplashScreen/&gt;:
              auth ?
              &lt;MainNavigator/&gt;
             
                :
                &lt;MainStack /&gt;
               
        &lt;/NavigationContainer&gt;
      &lt;/Provider&gt;
    );
    //}
  }
  
  
  export default App;
  
  MainStack.js File
  
  export default ({navigation}) =&gt; {
    return (
      &lt;Stack.Navigator initialRouteName=&quot;Login&quot; screenOptions={{
        headerShown: false
      }}&gt;
        &lt;Stack.Screen name=&quot;Login&quot; component={Login}/&gt;
        &lt;Stack.Screen name=&quot;ForgotPassword&quot; component={ForgetPassword}/&gt;
        &lt;Stack.Screen name=&quot;VerifyOTP&quot; component={VerifyOTP} /&gt;
        &lt;Stack.Screen name=&quot;ResetPassword&quot; component={ResetPassword} /&gt;      
      &lt;/Stack.Navigator&gt;
    );
  };
  
  MainNavigator.js
  const DashboardStackScreen = ({ navigation }) =&gt; {
    return (
      &lt;DashboardStack.Navigator screenOptions={{
        headerTitle: 'Good Morning, John',
        header: props =&gt; &lt;GradientHeader {...props} /&gt;,
       
        headerLeft: () =&gt; (
          &lt;TouchableOpacity onPress={navigation.openDrawer} style={{padding: 20}}&gt;
            &lt;Image source={require('../assets/images/menu_bar.png')} style={{width:18, height:12}}/&gt;
          &lt;/TouchableOpacity&gt;
        ),
        headerTransparent: true,
        headerStyle: {
          backgroundColor:  'transparent' 
        },
        headerTintColor: '#fff',    
        headerTitleStyle: { fontFamily: 'OpenSans-SemiBold', fontSize: 20},
      }}&gt;
        &lt;DashboardStack.Screen name=&quot;Dashboard&quot; component={Dashboard} /&gt;
      &lt;/DashboardStack.Navigator&gt;
    );
  }
  
  export default({navigation}) =&gt;{
    return (
      &lt;Drawer.Navigator initialRouteName=&quot;Dashboard&quot; drawerContent={(props) =&gt; &lt;DrawerContent {...props} /&gt;} hideStatusBar={false} focused={true} labelStyle={{ fontSize: 14, fontFamily: 'OpenSans-SemiBold' }} drawerContentOptions={{ activeBackgroundColor: &quot;#F1F1F1&quot;, activeTintColor: &quot;#000000&quot;, inactiveTintColor: &quot;#818181&quot;,itemStyle: { marginLeft:0, paddingHorizontal: 10,width:'100%',  borderRadius: 0}}} 
      
     &gt;
        &lt;Drawer.Screen name=&quot;Dashboard&quot; component={DashboardStackScreen} options={{
          drawerIcon: ({ focused, size }) =&gt; (
            &lt;Image source={require('../assets/images/dashboard.png')} style={{ height: 17.78, width: 16}}  resizeMode=&quot;contain&quot;/&gt;
          ),
        }}
        
        /&gt;
        &lt;Drawer.Screen name=&quot;My Profile&quot; component={MyProfileStackScreen} options={{
          drawerIcon: ({ focused, size }) =&gt; (
            &lt;Image source={require('../assets/images/profile.png')} style={{ height: 16, width: 16 }}  resizeMode=&quot;contain&quot;/&gt;
          ),
        }} /&gt;
       
        &lt;Drawer.Screen name=&quot;LMS&quot; component={LmsStackScreen} options={{
          drawerIcon: ({ focused, size }) =&gt; (
            &lt;Image source={require('../assets/images/lms.png')} style={{ height: 14.46, width: 16 }}  resizeMode=&quot;contain&quot;/&gt;
          ),
        }} /&gt;
        &lt;Drawer.Screen name=&quot;Change Password&quot; component={ChangePasswordStackScreen} options={{
          drawerIcon: ({ focused, size }) =&gt; (
            &lt;Image source={require('../assets/images/key.png')} style={{ height: 8.73, width: 16 }}  resizeMode=&quot;contain&quot;/&gt;
          ),
        }} /&gt;
      &lt;/Drawer.Navigator&gt;
    );
  };
  
  Login.js 
  import React from 'react';
  import { connect } from 'react-redux';
  import LinearGradient from 'react-native-linear-gradient';
  import { ScrollView, KeyboardAvoidingView, View, Text, Image, TextInput, TouchableOpacity, SafeAreaView, Keyboard, TouchableWithoutFeedback } from 'react-native';
  import Toast from 'react-native-simple-toast';
  /* import CheckBox from '@react-native-community/checkbox'; */
  /* import CheckBox from 'react-native-check-box'; */
  import Checkbox from 'react-native-custom-checkbox';
  
  import styles from '../utility/styles';
  import { thunk_login_creator } from '../actions/login';
  
  class Login extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        color: &quot;#ffffff&quot;,
        isSelected: false,
        isPasswordHidden: true,
        employeeId: '',
        employeeIdError: '',
        password: '',
        passwordError: ''
      }
    }
  
    handleValidation(type) {
      let obj = this.state;
      switch (type) {
        case 'employeeId':
          obj.employeeIdError = this.state.employeeId.trim() == &quot;&quot; ? &quot;Employee ID is required&quot; : &quot;&quot;;
          break;
        case 'password':
          obj.passwordError = this.state.password.trim() == &quot;&quot; ? &quot;Password is required&quot; : &quot;&quot;
          break;
        default:
          break;
      }
      this.setState({ obj });
    }
  
    handleChange(type, text) {
      if (type == 'employeeId') {
        this.setState({ employeeId: text.trim() }, () =&gt; {
          this.handleValidation(type);
        });
      } else {
        this.setState({ password: text.trim() }, () =&gt; {
          this.handleValidation(type);
        });
      }
    }
  
    handlePasswordToggle = () =&gt; {
      console.log('handlePasswordToggle called');
      this.setState({ isPasswordHidden: !this.state.isPasswordHidden })
    }
  
    handleRememberMe = () =&gt; {
      console.log('handleRememberMe called');
      this.setState({ isSelected: !this.state.isSelected }, () =&gt; {
        if (this.state.isSelected == true) {
          this.setState({ color: &quot;red&quot; });
        } else {
          this.setState({ color: &quot;black&quot; });
        }
        console.log('remember me---&gt;', this.state.isSelected);
      })
    }
  
    handleLogin = () =&gt; {
      console.log('handleLogin called')
      this.props.dispatch(thunk_login_creator({ 'empId': this.state.employeeId, 'password': this.state.password, 'isRemembered': this.state.isSelected },/* ()=&gt;{
        if (this.props.data.login.loading) {
          Toast.show('Loading...');
        } else if (this.props.data.login.error) {
          Toast.show('Invalid Credentials');
        } else {
          this.setState({
            employeeId: '',
            employeeIdError: '',
            password: '',
            passwordError: ''
          }, () =&gt; {
             this.props.navigation.navigate('Dashboard') 
          })
        }
      } */));
       if (this.props.data.login.loading) {
        Toast.show('Loading...');
      } else if (this.props.data.login.error != '') {
        Toast.show(this.props.data.login.error);
      } else {
        this.setState({
          isSelected: false,
          employeeId: '',
          employeeIdError: '',
          password: '',
          passwordError: ''
        }, () =&gt; {
          //this.props.navigation.navigate('Dashboard')
        })
      } 
    }
  
    render() {
      return (
  
        &lt;SafeAreaView style={styles.baseContainer}&gt;
  
          &lt;KeyboardAvoidingView behaviour=&quot;padding&quot; style={styles.baseContainer} &gt;
            &lt;TouchableWithoutFeedback style={styles.baseContainer} onPress={Keyboard.dismiss}&gt;
  
              &lt;View style={styles.baseContainer} &gt;
                &lt;View style={styles.ovalContainer}&gt;
                  &lt;View style={styles.oval1} /&gt;
                  &lt;View style={styles.oval2} /&gt;
                  &lt;View style={styles.logoContainer}&gt;
                    &lt;Image source={require('../assets/images/MJB_Logo.png')} style={styles.logo} /&gt;
                  &lt;/View&gt;
                &lt;/View&gt;
                &lt;View style={styles.formContainer}&gt;
                  &lt;View style={styles.loginTextContainer}&gt;
                    &lt;Text style={styles.loginText}&gt;Login&lt;/Text&gt;
                  &lt;/View&gt;
                  &lt;View style={styles.loginFormContainer}&gt;
                    &lt;View&gt;
                      &lt;Text style={styles.labelText}&gt;Employee ID&lt;/Text&gt;
                      &lt;TextInput style={styles.inputField} value={this.state.employeeId} placeholder=&quot;&quot; onBlur={() =&gt; this.handleValidation('employeeId')} keyboardType=&quot;email-address&quot; returnKeyType=&quot;next&quot; autoCorrect={false} onSubmitEditing={() =&gt; this.refs.txtPassword.focus()} onChangeText={(text) =&gt; this.handleChange('employeeId', text)} /&gt;
                      &lt;Text style={styles.errorText} &gt;{this.state.employeeIdError}&lt;/Text&gt;
                    &lt;/View&gt;
                    &lt;View&gt;
                      &lt;Text style={styles.labelText}&gt;Password&lt;/Text&gt;
                      &lt;View&gt;
                        &lt;TextInput style={styles.inputField} value={this.state.password} onBlur={() =&gt; this.handleValidation('password')}
                          placeholder=&quot;&quot; returnKeyType=&quot;go&quot; secureTextEntry={this.state.isPasswordHidden} autoCorrect={false} ref={&quot;txtPassword&quot;} onChangeText={(text) =&gt; this.handleChange('password', text)} /&gt;
                        &lt;TouchableWithoutFeedback onPress={this.handlePasswordToggle} style={styles.eyeIconContainer}&gt;
                          &lt;Image source={this.state.isPasswordHidden
                            ? require('../assets/images/eye_on.png')
                            : require('../assets/images/eye_off.png')} style={styles.eyeIcon} resizeMode=&quot;contain&quot; /&gt;
                        &lt;/TouchableWithoutFeedback&gt;
                      &lt;/View&gt;
                      &lt;Text style={styles.errorText} &gt;{this.state.passwordError}&lt;/Text&gt;
                    &lt;/View&gt;
                    {/* 
                    &lt;View style={styles.rememberMeContainer}&gt;
                        &lt;CheckBox 
                          value={this.state.isSelected}
                          onValueChange={this.handleRememberMe}
                          style={styles.checkbox}
                          tintColors={{ true: '#6CCFF6', false: '#CED4DA' }}
                          onFillColor=&quot;#6CCFF6&quot;
                          onTintColor=&quot;#6CCFF6&quot;
                        /&gt;
                        &lt;Text style={styles.rememberMeText}&gt;Remember Me&lt;/Text&gt;
                      &lt;/View&gt;
                    */}
  
                    &lt;View style={styles.rememberMeContainer}&gt;
                      {/*  &lt;CheckBox 
                          isChecked={this.state.isSelected}
                          onClick={this.handleRememberMe}
                         style={styles.checkbox}
                          checkBoxColor=&quot;#CED4DA&quot;
                          checkedCheckBoxColor=&quot;#6CCFF6&quot;
                         
                        /&gt; */}
                      &lt;Checkbox
                        checked={this.state.isSelected}
                        style={{/* backgroundColor: (this.state.isSelected ? 'green':'black'), */ color: '#000000', borderRadius: 3, borderColor: '#CED4DA', borderWidth: 1 }}
                        size={25}
                        onChange={this.handleRememberMe} /&gt;
                      &lt;Text style={styles.rememberMeText}&gt;Remember Me&lt;/Text&gt;
                    &lt;/View&gt;
  
                    &lt;TouchableOpacity disabled={this.state.employeeId == '' || this.state.password == '' ? true : false} onPress={this.handleLogin} &gt;
                      &lt;LinearGradient start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} colors={['#6CCFF6', '#596AB2']} style={styles.linearGradient}&gt;
                        &lt;Text style={styles.buttonText}&gt;
                          Login
                        &lt;/Text&gt;
                      &lt;/LinearGradient&gt;
                    &lt;/TouchableOpacity&gt;
                    &lt;View style={styles.forgetPasswordTextContainer} &gt;
                      &lt;Text style={styles.forgetText}&gt;Forgot password? &lt;Text style={styles.resetText} onPress={() =&gt;
                        this.props.navigation.navigate('ForgotPassword')
                      }&gt; Reset&lt;/Text&gt;&lt;/Text&gt;
                    &lt;/View&gt;
                  &lt;/View&gt;
                  {/* &lt;View style={styles.forgetPasswordTextContainer}&gt;
                    &lt;Text style={styles.forgetText}&gt;Forgot password? &lt;Text style={styles.resetText} onPress={() =&gt;
                      this.props.navigation.navigate('ForgotPassword')
                    }&gt; Reset&lt;/Text&gt;&lt;/Text&gt;
                  &lt;/View&gt; */}
                &lt;/View&gt;
              &lt;/View&gt;
  
            &lt;/TouchableWithoutFeedback &gt;
          &lt;/KeyboardAvoidingView&gt;
  
        &lt;/SafeAreaView&gt;
  
      )
    }
  };
  
  const mapStateToProps = state =&gt; {
    console.log('login state===&gt;', state)
    return {
      data: state
    };
  };
  export default connect(mapStateToProps)(Login);
  
  
  Any help is appreciated. 
  </code></pre>