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
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 = () => {
const [isLoading, setIsLoading] = useState(true);
const [auth, setAuth] = useState(false);
useEffect(() => {
setTimeout(async () => {
setIsLoading(!isLoading);
setAuth(false);
}, 2000)
}, []);
return (
<Provider store={store}>
<NavigationContainer>
<StatusBar backgroundColor={isLoading ? '#000000' : '#F3F3F3'} />
{isLoading ?
<SplashScreen/>:
auth ?
<MainNavigator/>
:
<MainStack />
</NavigationContainer>
</Provider>
);
//}
}
export default App;
MainStack.js File
export default ({navigation}) => {
return (
<Stack.Navigator initialRouteName="Login" screenOptions={{
headerShown: false
}}>
<Stack.Screen name="Login" component={Login}/>
<Stack.Screen name="ForgotPassword" component={ForgetPassword}/>
<Stack.Screen name="VerifyOTP" component={VerifyOTP} />
<Stack.Screen name="ResetPassword" component={ResetPassword} />
</Stack.Navigator>
);
};
MainNavigator.js
const DashboardStackScreen = ({ navigation }) => {
return (
<DashboardStack.Navigator screenOptions={{
headerTitle: 'Good Morning, John',
header: props => <GradientHeader {...props} />,
headerLeft: () => (
<TouchableOpacity onPress={navigation.openDrawer} style={{padding: 20}}>
<Image source={require('../assets/images/menu_bar.png')} style={{width:18, height:12}}/>
</TouchableOpacity>
),
headerTransparent: true,
headerStyle: {
backgroundColor: 'transparent'
},
headerTintColor: '#fff',
headerTitleStyle: { fontFamily: 'OpenSans-SemiBold', fontSize: 20},
}}>
<DashboardStack.Screen name="Dashboard" component={Dashboard} />
</DashboardStack.Navigator>
);
}
export default({navigation}) =>{
return (
<Drawer.Navigator initialRouteName="Dashboard" drawerContent={(props) => <DrawerContent {...props} />} hideStatusBar={false} focused={true} labelStyle={{ fontSize: 14, fontFamily: 'OpenSans-SemiBold' }} drawerContentOptions={{ activeBackgroundColor: "#F1F1F1", activeTintColor: "#000000", inactiveTintColor: "#818181",itemStyle: { marginLeft:0, paddingHorizontal: 10,width:'100%', borderRadius: 0}}}
>
<Drawer.Screen name="Dashboard" component={DashboardStackScreen} options={{
drawerIcon: ({ focused, size }) => (
<Image source={require('../assets/images/dashboard.png')} style={{ height: 17.78, width: 16}} resizeMode="contain"/>
),
}}
/>
<Drawer.Screen name="My Profile" component={MyProfileStackScreen} options={{
drawerIcon: ({ focused, size }) => (
<Image source={require('../assets/images/profile.png')} style={{ height: 16, width: 16 }} resizeMode="contain"/>
),
}} />
<Drawer.Screen name="LMS" component={LmsStackScreen} options={{
drawerIcon: ({ focused, size }) => (
<Image source={require('../assets/images/lms.png')} style={{ height: 14.46, width: 16 }} resizeMode="contain"/>
),
}} />
<Drawer.Screen name="Change Password" component={ChangePasswordStackScreen} options={{
drawerIcon: ({ focused, size }) => (
<Image source={require('../assets/images/key.png')} style={{ height: 8.73, width: 16 }} resizeMode="contain"/>
),
}} />
</Drawer.Navigator>
);
};
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: "#ffffff",
isSelected: false,
isPasswordHidden: true,
employeeId: '',
employeeIdError: '',
password: '',
passwordError: ''
}
}
handleValidation(type) {
let obj = this.state;
switch (type) {
case 'employeeId':
obj.employeeIdError = this.state.employeeId.trim() == "" ? "Employee ID is required" : "";
break;
case 'password':
obj.passwordError = this.state.password.trim() == "" ? "Password is required" : ""
break;
default:
break;
}
this.setState({ obj });
}
handleChange(type, text) {
if (type == 'employeeId') {
this.setState({ employeeId: text.trim() }, () => {
this.handleValidation(type);
});
} else {
this.setState({ password: text.trim() }, () => {
this.handleValidation(type);
});
}
}
handlePasswordToggle = () => {
console.log('handlePasswordToggle called');
this.setState({ isPasswordHidden: !this.state.isPasswordHidden })
}
handleRememberMe = () => {
console.log('handleRememberMe called');
this.setState({ isSelected: !this.state.isSelected }, () => {
if (this.state.isSelected == true) {
this.setState({ color: "red" });
} else {
this.setState({ color: "black" });
}
console.log('remember me--->', this.state.isSelected);
})
}
handleLogin = () => {
console.log('handleLogin called')
this.props.dispatch(thunk_login_creator({ 'empId': this.state.employeeId, 'password': this.state.password, 'isRemembered': this.state.isSelected },/* ()=>{
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: ''
}, () => {
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: ''
}, () => {
//this.props.navigation.navigate('Dashboard')
})
}
}
render() {
return (
<SafeAreaView style={styles.baseContainer}>
<KeyboardAvoidingView behaviour="padding" style={styles.baseContainer} >
<TouchableWithoutFeedback style={styles.baseContainer} onPress={Keyboard.dismiss}>
<View style={styles.baseContainer} >
<View style={styles.ovalContainer}>
<View style={styles.oval1} />
<View style={styles.oval2} />
<View style={styles.logoContainer}>
<Image source={require('../assets/images/MJB_Logo.png')} style={styles.logo} />
</View>
</View>
<View style={styles.formContainer}>
<View style={styles.loginTextContainer}>
<Text style={styles.loginText}>Login</Text>
</View>
<View style={styles.loginFormContainer}>
<View>
<Text style={styles.labelText}>Employee ID</Text>
<TextInput style={styles.inputField} value={this.state.employeeId} placeholder="" onBlur={() => this.handleValidation('employeeId')} keyboardType="email-address" returnKeyType="next" autoCorrect={false} onSubmitEditing={() => this.refs.txtPassword.focus()} onChangeText={(text) => this.handleChange('employeeId', text)} />
<Text style={styles.errorText} >{this.state.employeeIdError}</Text>
</View>
<View>
<Text style={styles.labelText}>Password</Text>
<View>
<TextInput style={styles.inputField} value={this.state.password} onBlur={() => this.handleValidation('password')}
placeholder="" returnKeyType="go" secureTextEntry={this.state.isPasswordHidden} autoCorrect={false} ref={"txtPassword"} onChangeText={(text) => this.handleChange('password', text)} />
<TouchableWithoutFeedback onPress={this.handlePasswordToggle} style={styles.eyeIconContainer}>
<Image source={this.state.isPasswordHidden
? require('../assets/images/eye_on.png')
: require('../assets/images/eye_off.png')} style={styles.eyeIcon} resizeMode="contain" />
</TouchableWithoutFeedback>
</View>
<Text style={styles.errorText} >{this.state.passwordError}</Text>
</View>
{/*
<View style={styles.rememberMeContainer}>
<CheckBox
value={this.state.isSelected}
onValueChange={this.handleRememberMe}
style={styles.checkbox}
tintColors={{ true: '#6CCFF6', false: '#CED4DA' }}
onFillColor="#6CCFF6"
onTintColor="#6CCFF6"
/>
<Text style={styles.rememberMeText}>Remember Me</Text>
</View>
*/}
<View style={styles.rememberMeContainer}>
{/* <CheckBox
isChecked={this.state.isSelected}
onClick={this.handleRememberMe}
style={styles.checkbox}
checkBoxColor="#CED4DA"
checkedCheckBoxColor="#6CCFF6"
/> */}
<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} />
<Text style={styles.rememberMeText}>Remember Me</Text>
</View>
<TouchableOpacity disabled={this.state.employeeId == '' || this.state.password == '' ? true : false} onPress={this.handleLogin} >
<LinearGradient start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} colors={['#6CCFF6', '#596AB2']} style={styles.linearGradient}>
<Text style={styles.buttonText}>
Login
</Text>
</LinearGradient>
</TouchableOpacity>
<View style={styles.forgetPasswordTextContainer} >
<Text style={styles.forgetText}>Forgot password? <Text style={styles.resetText} onPress={() =>
this.props.navigation.navigate('ForgotPassword')
}> Reset</Text></Text>
</View>
</View>
{/* <View style={styles.forgetPasswordTextContainer}>
<Text style={styles.forgetText}>Forgot password? <Text style={styles.resetText} onPress={() =>
this.props.navigation.navigate('ForgotPassword')
}> Reset</Text></Text>
</View> */}
</View>
</View>
</TouchableWithoutFeedback >
</KeyboardAvoidingView>
</SafeAreaView>
)
}
};
const mapStateToProps = state => {
console.log('login state===>', state)
return {
data: state
};
};
export default connect(mapStateToProps)(Login);
Any help is appreciated.