I am a beginner with react-native/redux, could not find a simple to use example of how to use an api call to post data in a redux app.So I tried doing mySelf. For backend I'm using express,nodejs,mongodb. If possible then give some reference of example.
type.js
export const POST_BOOKS_SUCCESS = "POST_BOOKS_SUCCESS"
BookAction.js
import {
POST_BOOKS_SUCCESS
} from "./types";
export const postBooksSuccess = ({ prop, value}) => ({
type:POST_BOOKS_SUCCESS,
payload:{ prop, value}
});
export const createBooks = ({title,description}) => {
console.log(title,description)
return (dispatch) => {
fetch("http://localhost:3000/api/Books",{
method:"POST",
headers:{
"content-type":"application/json"
},
body:JSON.stringify({title,description})
})
.then(res=>res.json())
.then(post => dispatch(postBooksSuccess({title,description})))
}
}
AddBookReducer.js
import {
POST_BOOKS_SUCCESS
} from "../actions/types";
const INITIAL_STATE = {
title:"",
description:""
};
export default (state = INITIAL_STATE, action)=>{
console.log(action);
switch(action.type){
case POST_BOOKS_SUCCESS:
return { ...state, [action.payload.prop]: action.payload.value }
default:
return state;
}
};
Addbook.js
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
KeyboardAvoidingView,
ScrollView,
TextInput,
TouchableOpacity
} from 'react-native';
import { connect } from 'react-redux';
import createBooks from "../redux/actions/BooksActions";
class AddBooks extends Component {
static navigationOptions = ({navigation}) => ({
// title: 'Add books',
headerTintColor: '#ffffff',
headerStyle: {
backgroundColor: '#2F95D6',
borderBottomColor: '#ffffff',
borderBottomWidth: 3,
},
headerTitleStyle: {
fontSize: 18,
},
});
onButtonPress() {
const { title, description } = this.props;
this.props.createBooks({ title, description })
}
render() {
return (
<View style={styles.container}>
<KeyboardAvoidingView
behavior="padding"
style={styles.container}>
<ScrollView>
<View>
<TextInput style={styles.textInput}
placeholder="Title"
placeholderTextColor="black"
underlineColorAndroid="rgba(0,0,0,0)"
onChangeText={text => this.props.createBooks({
prop:"title", value: text })}
value={this.props.title}
/>
</View>
<View>
<TextInput style={styles.textInput}
placeholder="Description"
placeholderTextColor="black"
underlineColorAndroid="rgba(0,0,0,0)"
onChangeText={text => this.props.createBooks({ prop:"description", value: text })}
value={this.props.description}
/>
</View>
<TouchableOpacity
style={styles.button}
onPress={this.onButtonPress.bind(this)}
>
<Text style={styles.buttonText}>
Submit
</Text>
</TouchableOpacity>
</ScrollView>
</KeyboardAvoidingView>
</View>
);
}
}
mapStateToProps = (state) => {
const {title,description} = state.addBookReducers;
return {
title,
description
}
}
export default connect(mapStateToProps,{createBooks})(AddBooks)
const styles = StyleSheet.create({
container:{
backgroundColor:"#EBF5FB",
flex:1
},
textInput:{
marginTop: 10,
fontSize:20,
height:50,
borderColor:"black",
borderWidth: 1,
width:"100%"
},
button:{
width:"100%",
backgroundColor: "#19B5FE",
marginVertical: 10,
paddingVertical: 16,
borderRadius: 30,
},
buttonText:{
fontSize:16,
fontWeight:"500",
textAlign:"center",
color:"black"
},
})
reducer/index.js
import { combineReducers } from "redux";
import BookReducers from "./BooksReducers";
import AddBookReducers from "./AddBookReducers";
export default combineReducers({
bookReducers: BookReducers,
addBookReducers: AddBookReducers
})
Related
I have made a Login page in React Native with React hooks along with redux thunk connect.
In that Login Page, i have import a LoginForm as customComponent and I have properly export and import that component.But still it produce Element type error.
LoginPage
import React, { useState } from "react";
import {
View,
Text,
TouchableOpacity,
StyleSheet,
Dimensions,
} from "react-native";
import PropsType from "prop-types";
import { connect } from "react-redux";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scrollview";
import SimpleReactValidator from "simple-react-validator";
import Img from "../../common/Img";
import Loader from "../../common/Loader";
import styles from "../../globalStyle";
import * as theme from "../../theme";
import AxiosInstance from "../../helper/axios.interceptor";
import * as globalHelper from "../../helper/globalHelper";
import { setAuth } from "../../store/auth/auth.action";
import LoginForm from "./Component/LoginForm";
const { height } = Dimensions.get("screen");
const propsType = {
authAction: PropsType.func,
};
let request = { type: "mobile" };
const validator = new SimpleReactValidator();
const SignIn = ({ navigation, authAction }) => {
const [errors, setErrors] = useState({});
const [state, setState] = useState({ loader: false }),
updateState = (key, value) => {
setState((preState) => ({
...preState,
[key]: value,
}));
},
openLoader = (val) => {
updateState("loader", val);
};
const submit = async () => {
try {
openLoader(true);
let body = {
type: "mobile",
userName: request.userName,
password: request.password,
};
console.log("body", body);
const response = await AxiosInstance.post("auth/login", body);
console.log("loginresponse...", response);
if (response.status) {
await globalHelper.setAsyncStore("user", response);
await globalHelper.setAsyncStore(
"userpermission",
response.data.permissionJson
);
authAction(response);
navigation.replace("AppNavigation");
}
openLoader(false);
} catch (err) {
openLoader(false);
console.log("login error", err);
}
};
//
const ForgotPassword = () => (
<TouchableOpacity
onPress={() => {
validator.hideMessages();
setErrors("");
navigation.push("ForgotPassword");
}}
>
<Text style={[localStyle.forgotText]}>Forgot Password?</Text>
</TouchableOpacity>
);
return (
<>
<KeyboardAwareScrollView>
<View style={[styles.flexCenter, { height }]}>
<Img
src={require("../../assets/logo/logoNew.png")}
style={{ width: 237, height: 250, marginBottom: -20 }}
resizeMode="contain"
/>
<View style={localStyle.authButton}>
<LoginForm
validator={validator}
onTextChanging={(data) => {
request = { ...request, ...data };
}}
onSubmit={() => {
submit();
}}
errors={errors}
setErrors={setErrors}
/>
</View>
<View style={[styles.flexCenter]}>
<ForgotPassword />
</View>
</View>
</KeyboardAwareScrollView>
{state.loader && <Loader />}
</>
);
};
const { color } = theme;
const localStyle = StyleSheet.create({
authButton: {
width: "80%",
borderRadius: 5,
},
forgotText: {
marginTop: 20,
color: color.hashTextColor,
},
});
SignIn.propsType = propsType;
const mapDispatchToProps = {
authAction: setAuth,
};
export default connect(null, mapDispatchToProps)(SignIn);
and the customComponent LoginForm as
import React, { useState, useEffect, useRef } from "react";
import {
View,
Text,
TouchableOpacity,
ScrollView,
StyleSheet,
} from "react-native";
import { Form, Icon } from "native-base";
import PropsType from "prop-types";
import { has } from "lodash";
import RegularInput from "../../../common/Input";
import styles from "../../../globalStyle";
import AuthButton from "../../../common/Button/AuthButton";
const propsType = {
onTextChanging: PropsType.func.isRequired,
onSubmit: PropsType.func.isRequired,
};
// const validator = new SimpleReactValidator();
const LoginForm = ({
onTextChanging,
onSubmit,
validator,
errors,
setErrors,
}) => {
const [model, setModel] = useState({ focus: "username", secured: true });
const isValid = (key) => !!(has(errors, key) && errors[key]);
const [state, setState] = useState({
userName: "",
password: "",
});
const secondTextInput = useRef(null);
useEffect(() => {
onTextChanging(state);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [state]);
const updateState = (key, value) => {
setState((preState) => ({
...preState,
[key]: value,
}));
};
const submit = () => {
if (validator.allValid()) {
onSubmit();
} else {
console.log("getErrorMessages");
setErrors(validator.getErrorMessages());
validator.showMessages();
}
};
return (
<ScrollView keyboardShouldPersistTaps="handled">
<Form style={[styles.top50, { width: "100%" }]}>
<View style={{ width: "100%", paddingBottom: 15 }}>
<RegularInput
title="Email"
value={state.userName}
attri="userName"
placeHolder={"Email"}
keyboardType="ascii-capable"
updateStateFunc={updateState}
error={isValid("Username")}
isFocus={model.focus === "username"}
onFocusFun={() => setModel({ focus: "username" })}
otherProps={{
onSubmitEditing: () => {
console.log(secondTextInput);
secondTextInput.current.focus();
},
blurOnSubmit: false,
}}
/>
</View>
{!!validator.message("Email", state.userName, "email") && (
<Text style={[styles.error]}>
{validator.message("Email", state.userName, "email")}
</Text>
)}
<View
style={[
styles.flexCenter,
styles.flexRow,
localStyle.absoluteContainer,
]}
>
<RegularInput
reff={secondTextInput}
title="Password"
value={state.password}
attri="password"
placeHolder={"Password"}
updateStateFunc={updateState}
dataDetectorTypes="phoneNumber"
secureTextEntry={!state.secured}
error={isValid("Password")}
isFocus={model.focus === "password"}
onFocusFun={() => setModel({ focus: "password" })}
/>
<TouchableOpacity
style={localStyle.eyeIcon}
onPress={() => {
updateState("secured", !state.secured);
}}
>
{state.secured && (
<Icon style={{ fontSize: 16 }} name="eye" type="Entypo" />
)}
{!state.secured && (
<Icon
style={{ fontSize: 16 }}
name="eye-with-line"
type="Entypo"
/>
)}
</TouchableOpacity>
</View>
{!!validator.message("Password", state.password, "required") && (
<Text style={[styles.error]}>
{validator.message("Password", state.password, "required")}
</Text>
)}
<View style={[styles.flexCenter, localStyle.authButton]}>
<AuthButton title="LOGIN" onPress={() => submit()} />
</View>
</Form>
</ScrollView>
);
};
const localStyle = StyleSheet.create({
authButton: {
marginTop: 10,
borderRadius: 5,
},
inputStyle: {
height: 40,
borderColor: "gray",
borderBottomWidth: 1,
},
absoluteContainer: {
position: "relative",
overflow: "hidden",
width: "100%",
},
eyeIcon: {
position: "absolute",
// right: 0,
width: 25,
height: 25,
elevation: 999,
zIndex: 999,
top: 42,
right: 5,
},
});
LoginForm.propsType = propsType;
export default LoginForm;
I have tried
import LoginForm from "./Component/LoginForm";
as
import {LoginForm} from "./Component/LoginForm";
It produce check the render method of SignIn
and also use connect in LoginForm,
export default connect(null, null)(LoginForm);
but it gives same error. I don't know what mistake i have made.unable to find any cause. Thanks in advance
Element type Error
I wrote the below code to make multiple side drawer but unluckily I am not able.
Here open the left side drawer easily but the right-side drawer is not open. for Analyze purpose header.js file when I used here onPress={() => navigation.openDrawer()} then open left side drawer and I also used in second drawer element onPress={() => navigation.openDrawer()} also open left ride drawer but I want to open right side drawer.
What should I do?
app.js file:
import * as React from 'react';
import {View, Button,StyleSheet, Alert, Text, ActivityIndicator, Image} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import {createDrawerNavigator} from '#react-navigation/drawer';
import DrawerContent from './screens/common/DrawerContent';
import SearchDrawer from './screens/common/SearchDrawer';
import Registration from './screens/authentication/Registration';
import Login from './screens/authentication/Login';
import ForgotPassword from './screens/authentication/ForgotPassword';
import ChangePassword from './screens/authentication/ChangePassword';
import Dashboard from './screens/user/Dashboard';
import Notifications from './screens/user/Notifications';
import ProfileStep from './screens/user';
import Shipment from './screens/user/shipment';
// import SplashScreen from 'react-native-splash-screen';
// import {LogBox} from 'react-native';
import {Provider} from 'react-redux';
import AsyncStorage from '#react-native-community/async-storage';
import {store, getAsyncStorage} from './redux/store';
import messaging from '#react-native-firebase/messaging';
const Stack = createStackNavigator();
const DrawerR = createDrawerNavigator();
const DrawerL = createDrawerNavigator();
function User(props) {
const [userInfo, setUserInfo] = React.useState('');
React.useEffect(() => {
getUserInfo();
}, []);
const getUserInfo = async () => {
let userInfo = await AsyncStorage.getItem('userInfo');
if (userInfo) {
store.dispatch(getAsyncStorage());
userInfo = JSON.parse(userInfo);
setUserInfo(userInfo);
}
};
return (
<DrawerL.Navigator
drawerContent={(props) => (
<DrawerContent {...props} size="22" data={userInfo} />
)}
// drawerPosition="right"
// drawerContent={(props) => (
// <SearchDrawer {...props} size="22" />
// )}
>
{props.route.params !== undefined && props.route.params.completed ? (
<>
<DrawerL.Screen name="Dashboard" component={Dashboard} />
<DrawerL.Screen name="ProfileStep" component={ProfileStep} />
</>
) : (
<>
<DrawerL.Screen name="ProfileStep" component={ProfileStep} />
<DrawerL.Screen name="Dashboard" component={Dashboard} />
</>
)}
<DrawerL.Screen name="Shipment" component={Shipment} />
</DrawerL.Navigator>
);
}
function User1(props){
const [userInfo1, setUserInfo1] = React.useState('')
React.useEffect(() => {
getUserInfo1();
}, []);
const getUserInfo1 = async () => {
let userInfo1 = await AsyncStorage.getItem('userInfo');
if (userInfo1) {
store.dispatch(getAsyncStorage());
userInfo1 = JSON.parse(userInfo1);
setUserInfo1(userInfo1);
}
};
return (
<DrawerR.Navigator
drawerPosition="right"
drawerContent={(props) => (
<SearchDrawer {...props} size="22" data={userInfo1}/>
)}
>
</DrawerR.Navigator>
);
}
function App() {
React.useEffect(() => {
const unsubscribe = messaging().onMessage(async (remoteMessage) => {
Alert.alert('A new FCM message arrived!', JSON.stringify(remoteMessage));
});
return unsubscribe;
}, []);
return (
<Provider store={store}>
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false,
}}>
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Registration" component={Registration} />
<Stack.Screen name="ForgotPassword" component={ForgotPassword} />
<Stack.Screen name="ChangePassword" component={ChangePassword} />
<Stack.Screen name="User" component={User} />
<Stack.Screen name="User1" component={User1} />
<Stack.Screen name="Notifications" component={Notifications} />
</Stack.Navigator>
</NavigationContainer>
</Provider>
);
}
export default App;
DrawerContent.js
import React,{useEffect} from 'react';
import {View, StyleSheet, Alert, Text, ActivityIndicator, Image} from 'react-native';
import {
Avatar,
Title,
Caption,
Drawer,
TouchableRipple,
Divider,
Switch,
} from 'react-native-paper';
import {DrawerContentScrollView, DrawerItem} from '#react-navigation/drawer';
import AsyncStorage from '#react-native-community/async-storage';
import {connect} from 'react-redux';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {setTheme} from './../../redux/actions/config';
import {getThemeColors} from '../../global/themes';
import {API_URL} from './../../global/config';
import { Linking } from 'react-native';
// import {bindActionCreators} from 'redux';
var pkg = require('./../../package.json');
function DrawerContent(props) {
const [loading, setLoading] = React.useState(false);
const [profileStatus, setProfileStatus] = React.useState({});
const [whitelabel, setIfWhiteLabel] = React.useState('')
// const [isDarkMode, setIsDarkMode] = React.useState(false);
let userInfo = props.data;
const logout = () => {
Alert.alert(
'Are you sure?',
'You want to Logout',
[
{
text: 'Cancel',
style: 'cancel',
},
{
text: 'Yes',
onPress: () => {
setLoading(true);
console.log(`${API_URL}disableDevice`);
fetch(`${API_URL}disableDevice`, {
method: 'post',
body: JSON.stringify({user_id: userInfo.id}),
})
.then((res) => res.json())
.then(async (res) => {
if (!res.status) {
setLoading(false);
alert('something went wrong!!');
} else {
try {
await AsyncStorage.removeItem('userInfo');
await AsyncStorage.removeItem('profileStatus');
props.navigation.reset({
index: 0,
routes: [{name: 'Login'}],
});
} catch (exception) {
setLoading(false);
return false;
}
}
})
.catch((e) => {
setLoading(false);
console.log(e);
});
},
},
],
{cancelable: false},
);
};
const onThemeChange = async () => {
AsyncStorage.setItem(
'themeMode',
props.theme === 'default' ? 'dark' : 'default',
);
props.onSelectTheme(props.theme === 'default' ? 'dark' : 'default');
fetch(`${API_URL}toggleDarkMode`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
user_id: userInfo.id,
dark_mode: props.theme === 'default' ? 1 : 0,
}),
})
.then((res) => res.json())
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
};
const {colors} = props;
React.useEffect(() => {
var profileStatus = props.profileStatus;
if (profileStatus) {
profileStatus = JSON.parse(profileStatus);
setProfileStatus(profileStatus);
}
checkIfWhiteLabel()
}, [props.profileStatus]);
useEffect(() => {
checkIfWhiteLabel()
}, [])
const checkIfWhiteLabel = async () =>{
let iftru = await AsyncStorage.getItem('whiteLabel');
if(iftru == null){
setIfWhiteLabel('false')
}else{
setIfWhiteLabel(iftru)
}
}
return (
<>
<View style={{flex: 1, backgroundColor: colors.drawerBackground}}>
<DrawerContentScrollView {...props}>
<View style={styles.drawerContent}>
<View style={styles.tinyLogoDiv}>
<Image
style={styles.tinyLogo}
source={require('../../assets/logo.png')}
/>
</View>
<TouchableRipple
style={styles.userInfoSection}
onPress={() =>
props.navigation.navigate('ProfileStep', {status: 'TRUE'})
}
rippleColor="rgba(0, 0, 0, .32)">
<View style={{flexDirection: 'row'}}>
<Avatar.Image
source={require('../../assets/avater.png')}
size={50}
/>
<View style={{marginLeft: 15, flexDirection: 'column'}}>
<Title style={styles.title(colors.textColor)}>
{profileStatus.username ?? userInfo.name}
</Title>
<Caption style={styles.caption(colors.textColor)}>
{profileStatus.email ?? userInfo.email}
</Caption>
</View>
<View
style={{
justifyContent: 'center',
marginLeft: 'auto',
paddingRight: 7,
}}>
<Icon
name="account-edit"
size={25}
color={colors.textColor}
/>
</View>
</View>
</TouchableRipple>
<Divider />
<Drawer.Section style={styles.drawerSection}>
<DrawerItem
icon={() => (
<Icon name="home" size={30} color={colors.textColor} />
)}
labelStyle={{color: colors.textColor}}
label="Home"
onPress={() => {
if (profileStatus.type || profileStatus.type === undefined) {
alert('Complete Your profile first');
} else {
props.navigation.navigate('Dashboard');
}
}}
/>
<DrawerItem
icon={() => (
<Icon
name="text-box-plus"
size={30}
color={colors.textColor}
/>
)}
label="Parcel"
labelStyle={{color: colors.textColor}}
onPress={() => {
if (profileStatus.type || profileStatus.type === undefined) {
alert('Complete Your profile first');
} else {
props.navigation.navigate('Shipment');
}
}}
/>
</Drawer.Section>
</View>
</DrawerContentScrollView>
<Drawer.Section style={styles.bottomDrawerSection}>
<DrawerItem
style={{paddingBottom: 0}}
icon={() =>
loading ? (
<ActivityIndicator size={30} color={colors.primaryColor} />
) : (
<Icon name="exit-to-app" size={30} color={colors.textColor} />
)
}
label={'Logout'}
labelStyle={{color: colors.textColor}}
onPress={() => logout()}
/>
</Drawer.Section>
<View
style={{
marginBottom: 5,
alignItems: 'center',
}}>
<Text style={{opacity: 0.8, color: colors.textColor}}>
V - {pkg.version}
</Text>
</View>
</View>
</>
);
}
const mapStateToProps = (state) => {
let imagePlaceholder = JSON.parse(state.brand);
if (imagePlaceholder) {
imagePlaceholder = imagePlaceholder.default.avatar;
} else {
imagePlaceholder = '';
}
var theme = getThemeColors(state.theme);
return {
theme: state.theme,
colors: theme,
profileStatus: state.profileStatus,
imagePlaceholder: imagePlaceholder,
};
// count: state.count,
};
export default connect(mapStateToProps, {
onSelectTheme: setTheme,
})(DrawerContent);
//
const styles = StyleSheet.create({
drawerContent: {
flex: 1,
},
userInfoSection: {
paddingLeft: 20,
paddingVertical: 10,
},
title: (color) => ({
fontSize: 16,
marginTop: 3,
fontWeight: 'bold',
color: color,
}),
caption: (color) => ({
fontSize: 12,
lineHeight: 14,
opacity: 0.8,
color: color,
marginLeft:-15,
}),
row: {
marginTop: 20,
flexDirection: 'row',
alignItems: 'center',
},
section: {
flexDirection: 'row',
alignItems: 'center',
marginRight: 15,
},
paragraph: {
fontWeight: 'bold',
marginRight: 3,
},
drawerSection: {
marginTop: 15,
},
bottomDrawerSection: {
// marginBottom: 15,
borderTopColor: '#ccc',
borderTopWidth: 0.2,
borderBottomColor: '#ccc',
borderBottomWidth: 0.2,
},
preference: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 12,
paddingHorizontal: 16,
},
loading: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
opacity: 0.6,
justifyContent: 'center',
alignItems: 'center',
},
loadingText: {
fontSize: 20,
paddingTop: 20,
fontWeight: 'bold',
},
tinyLogoDiv:{
// width:100,
},
tinyLogo: {
width: 150,
height: 50,
// alignItems:'center',
marginLeft:70
},
});
SearchDrawer.js
import React from 'react';
import { View, StyleSheet, Text, Button,TextInput } from 'react-native';
import { DrawerContentScrollView} from '#react-navigation/drawer';
import { setTheme } from './../../redux/actions/config';
import { getThemeColors } from '../../global/themes';
import { connect } from 'react-redux';
function SearchDrawer(props) {
return (
<>
<View style={{ flex: 1, backgroundColor: '#ffffff' }}>
<DrawerContentScrollView {...props}>
<View>
<Text>This is input Field</Text>
<TextInput
label='Search here'
style={styles.input}
placeholder="Search By Order Id"
/>
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="#fff"
/>
</View>
</DrawerContentScrollView>
</View>
</>
);
}
const mapStateToProps = (state) => {
let imagePlaceholder = JSON.parse(state.brand);
if (imagePlaceholder) {
imagePlaceholder = imagePlaceholder.default.avatar;
} else {
imagePlaceholder = '';
}
var theme = getThemeColors(state.theme);
return {
theme: state.theme,
colors: theme,
profileStatus: state.profileStatus,
imagePlaceholder: imagePlaceholder,
};
};
const styles = StyleSheet.create({
drawerSection: {
marginTop: 15,
},
})
export default connect(mapStateToProps, {
onSelectTheme: setTheme,
})(SearchDrawer);
Header.js
import React from 'react';
import {
// StyleSheet,
// TouchableOpacity,
// TouchableWithoutFeedback,
Text,
View, TouchableOpacity,
AppState, TextInput, StyleSheet
} from 'react-native';
import { DrawerItem } from '#react-navigation/drawer';
import { DrawerActions } from '#react-navigation/native';
import { useNavigation } from '#react-navigation/native';
import { Appbar, Badge } from 'react-native-paper';
// import {colors} from '../../global/themes';
import { FontAwesomeIcon } from '#fortawesome/react-native-fontawesome'
import { faCoffee } from '#fortawesome/free-solid-svg-icons'
import Icon from 'react-native-vector-icons/FontAwesome';
import { connect } from 'react-redux';
import { setTheme } from './../../redux/actions/config';
// import {bindActionCreators} from 'redux';
import { getThemeColors } from '../../global/themes';
// import {useState} from 'react';
import { API_URL } from '../../global/config';
import AsyncStorage from '#react-native-community/async-storage';
import Menu, { MenuItem } from 'react-native-material-menu';
import messaging from '#react-native-firebase/messaging';
import notifee, { EventType } from '#notifee/react-native';
const ContentTitle = ({ title, color }) => (
<Appbar.Content
title={
// <View style={{zIndex: 99999999}}>
<Text style={{ fontSize: 20, color: color, zIndex: 99999999 }}>
{' '}
{title}{' '}
</Text>
// </View>
}
style={{ marginLeft: -10 }}
/>
);
function Header(props) {
const navigation = useNavigation();
console.log('Pera Navigation', navigation)
const { colors } = props;
const [notificationCount, setNotificationCount] = React.useState(0);
const [showMenu, setShowMenu] = React.useState(false);
const [appState, setAppState] = React.useState(AppState.currentState);
const [actions, setActions] = React.useState([]);
const menu = React.useRef();
const getUserId = async () => {
let userInfo = await AsyncStorage.getItem('userInfo');
if (userInfo) {
userInfo = JSON.parse(userInfo);
return userInfo.id;
}
};
function getNotificationCount() {
getUserId().then((id) => {
console.log(`${API_URL}newNotification`);
fetch(`${API_URL}newNotification`, {
method: 'post',
body: JSON.stringify({ user_id: id }),
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
})
.then((res) => res.json())
.then((res) => {
if (res.status) {
setNotificationCount(res.notification_count);
}
})
.catch((e) => {
console.log(e);
});
});
}
const _handleAppStateChange = (nextAppState) => {
getNotificationCount();
setAppState(nextAppState);
};
React.useEffect(() => {
AppState.addEventListener('change', (e) => _handleAppStateChange(e));
getNotificationCount();
notifee.createChannel({
id: 'custom-sound',
name: 'System Sound',
sound: 'notification__.mp3',
});
notifee.onForegroundEvent(({ type, detail }) => {
switch (type) {
case EventType.DISMISSED:
console.log('User dismissed notification', detail.notification);
break;
case EventType.PRESS:
let count = notificationCount;
setNotificationCount(0);
// alert('0 done');
navigation.navigate('Notifications', {
count: count,
screen: ' ',
});
break;
}
});
messaging().onMessage(async (remoteMessage) => {
// console.log('ok oko k');
await notifee.displayNotification({
title: remoteMessage.notification.title,
body: remoteMessage.notification.body,
android: {
channelId: 'custom-sound',
},
});
getNotificationCount();
});
messaging().onNotificationOpenedApp((remoteMessage) => {
let count = notificationCount;
setNotificationCount(0);
navigation.navigate('Notifications', {
count: count,
screen: 'header',
});
});
}, []);
React.useEffect(() => {
if (showMenu) {
menu.current.show();
}
}, [showMenu]);
return (
<Appbar.Header style={{ backgroundColor: colors.headerColor }}>
{props.back ? (
<Appbar.BackAction
onPress={() => (props.goBack ? props.goBack() : navigation.goBack())}
/>
) : (
<Appbar.Action
icon="menu"
onPress={() => navigation.openDrawer()}
size={28}
color={colors.textColor}
style={{ paddingLeft: 3 }}
/>
)}
<TouchableOpacity style={styles.searchSection}>
<TextInput
style={styles.input}
placeholder="Search By Order Id"
onPress={() =>navigation.openDrawer()}
/>
<Icon style={styles.searchIcon} name="search" size={20} color="#000" />
</TouchableOpacity>
{/* <TouchableOpacity onPress={() => navigation.openDrawer()}>
<Icon style={{marginLeft: 10}} name='menu'/>
</TouchableOpacity> */}
{/* <Button title='open the drawer' onPress={this.props.navigation.dispatch(DrawerActions.openDrawer('drawerOpenLeft'))}></Button>
<Button title='open the drawer right' onPress={this.props.navigation.dispatch(DrawerActions.openDrawer('drawerOpenRight'))}></Button> */}
<ContentTitle title={props.title} color={colors.textColor} />
{!props.hideNotification && (
<View>
{notificationCount > 0 && (
<Badge
visible={true}
size={16}
style={{ position: 'absolute', top: 10, right: 7, zIndex: 9999 }}>
<Text style={{ fontSize: 12 }}>{notificationCount}</Text>
</Badge>
)}
<Appbar.Action
icon="bell"
onPress={() => {
let count = notificationCount;
setNotificationCount(0);
navigation.navigate('Notifications', {
count: count,
screen: 'header',
});
}}
size={28}
color={colors.textColor}
style={{ paddingLeft: 3 }}
/>
</View>
)}
{props.selected && (
<>
<Appbar.Action
icon="delete"
onPress={() => props.onDeletePress()}
size={28}
color={colors.textColor}
style={{ left: 10 }}
/>
<Menu
ref={menu}
style={{ backgroundColor: colors.secondaryColor }}
onHidden={() => {
setShowMenu(false);
}}
button={
<Appbar.Action
icon="dots-vertical"
onPress={() => {
props.onActionPress().then((res) => {
console.log(res);
// if (res.status === 'TRUE') {
setShowMenu(res.status);
setActions(res.actions);
// } else {
// setShowMenu(false);
// }
});
}}
size={28}
color={colors.textColor}
/>
}>
{actions.length > 0 &&
actions.map((item, i) => {
return (
<>
{item.statusList !== undefined && (
<>
<MenuItem style={{ height: 40 }} disabled>
<Text style={{ color: colors.textLight }}>
{item.text}
</Text>
</MenuItem>
{item.statusList.map((list) => {
return (
<MenuItem
onPress={() => {
props.onMenuPress(item.type, list.VALUE);
menu.current.hide();
}}
key={i}>
<Text style={{ color: colors.textColor }}>
{' '}
{list.LABEL}
</Text>
</MenuItem>
);
})}
</>
)}
</>
);
})}
</Menu>
</>
)}
</Appbar.Header>
);
}
const mapStateToProps = (state) => {
var theme = getThemeColors(state.theme);
return { colors: theme };
};
export default connect(mapStateToProps, {
onSelectTheme: setTheme,
})(Header);
const styles = StyleSheet.create({
searchSection: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
searchIcon: {
padding: 10,
},
input: {
flex: 1,
height: 40,
padding: 10,
paddingLeft: 0,
backgroundColor: '#fff',
color: '#424242',
},
})
I don't know if I understood well but I need a little help.
Here Home.js is Shows the both screen names
And Here Student.js screen is show only student contact numbers and Teacher.js
This is my full code..
And I have used navigation version 4
Navigation.js
import { createAppContainer } from 'react-navigation'
import { createStackNavigator } from 'react-navigation-stack'
import Home from '../screens/Home'
import Teacher from '../screens/Teacher'
import Student from '../screens/Student'
const StackNavigator = createStackNavigator(
{
Student: {
screen: Student
},
Home: {
screen: Home
},
Teacher: {
screen: Teacher
}
},
{
initialRouteName: 'Home',
headerMode: 'none',
mode: 'modal'
}
)
export default createAppContainer(StackNavigator)
Home.js
import React from 'react';
import { Text, View, TouchableOpacity, StyleSheet } from 'react-native';
export default class Home extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ marginTop: 50, fontSize: 25 }}>Home!</Text>
<View
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Teacher')}>
<Text>Teacher Numbers</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Student')}>
<Text>Student Numbers</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
padding: 10,
width: 300,
marginTop: 16,
},
});
Student.js
import React, { useState } from 'react'
import { StyleSheet, View, Button, FlatList } from 'react-native'
import { Text, FAB, List, IconButton, Colors, TextInput } from 'react-native-paper'
import { useSelector, useDispatch } from 'react-redux'
import { addnumber, deletenumber } from './../store/actions/studentList'
import Header from '../components/Header'
function StudentNumber({ navigation }) {
const [studentNumber, setStudentNumber] = useState('')
const snumbers = useSelector(state => state)
const dispatch = useDispatch()
const addNumber = number => dispatch(adbnumber(number))
const deleteNumber = id => dispatch(deletenumber(id))
function onSaveNumber() {
addNumber({studentNumber})
}
function FlatListItemSeparator () {
return (
//Item Separator
<View style={{height: 0.5, width: '100%', backgroundColor: '#C8C8C8'}}/>
);
};
function GetItem(item) {
//Function for click on an item
Alert.alert(item);
}
return (
<>
<View style={styles.container}>
<Button title="Go back" onPress={() => navigation.goBack()} />
<TextInput
label='Add a Number Here'
value={studentNumber}
mode='outlined'
onChangeText={setStudentNumber}
style={styles.title}
/>
{bnumbers.length === 0 ? (
<View style={styles.titleContainer}>
<Text style={styles.title}>You do not have any student numbers</Text>
</View>
) : (
<FlatList
data={snumbers}
ItemSeparatorComponent={FlatListItemSeparator}
renderItem={({ item }) => (
<List.Item
title={item.number.studentNumber}
descriptionNumberOfLines={1}
titleStyle={styles.listTitle}
onPress={() => deletestudentNumber(item.bid)}
/>
)}
keyExtractor={item => item.id.toString()}
/>
)}
<FAB
style={styles.fab}
small
icon='plus'
label='Add new number'
onPress={() => onSaveNumber()}
/>
</View>
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingHorizontal: 10,
paddingVertical: 20
},
titleContainer: {
alignItems: 'center',
justifyContent: 'center',
flex: 1
},
title: {
fontSize: 20
},
fab: {
position: 'absolute',
margin: 20,
right: 0,
bottom: 10
},
listTitle: {
fontSize: 20
}
})
export default Student
Teacher.js
import React, { useState } from 'react'
import { StyleSheet, View, Button, FlatList } from 'react-native'
import { Text, FAB, List, IconButton, Colors, TextInput } from 'react-native-paper'
import { useSelector, useDispatch } from 'react-redux'
import { addnumber, deletenumber } from './../store/actions/teacherList'
import Header from '../components/Header'
function Teacher({ navigation }) {
const [teacherNumber, setTeacherNumber] = useState('')
const numbers = useSelector(state => state)
const dispatch = useDispatch()
const addNumber = number => dispatch(addnumber(number))
const deleteNumber = id => dispatch(deletenumber(id))
function onSaveNumber() {
addNumber({ teacherNumber})
}
function FlatListItemSeparator () {
return (
//Item Separator
<View style={{height: 0.5, width: '100%', backgroundColor: '#C8C8C8'}}/>
);
};
function GetItem(item) {
//Function for click on an item
Alert.alert(item);
}
return (
<>
<View style={styles.container}>
<Button title="Go back" onPress={() => navigation.goBack()} />
<TextInput
label='Add a Number Here'
value={teacherNumber}
mode='outlined'
onChangeText={setTeacherNumber}
style={styles.title}
/>
{numbers.length === 0 ? (
<View style={styles.titleContainer}>
<Text style={styles.title}>You do not have any teacher numbers</Text>
</View>
) : (
<FlatList
data={numbers}
ItemSeparatorComponent={FlatListItemSeparator}
renderItem={({ item }) => (
<List.Item
title={item.number.teacherNumber}
descriptionNumberOfLines={1}
titleStyle={styles.listTitle}
onPress={() => deleteNumber(item.id)}
/>
)}
keyExtractor={item => item.id.toString()}
/>
)}
<FAB
style={styles.fab}
small
icon='plus'
label='Add new number'
onPress={() => onSaveNumber()}
/>
</View>
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingHorizontal: 10,
paddingVertical: 20
},
titleContainer: {
alignItems: 'center',
justifyContent: 'center',
flex: 1
},
title: {
fontSize: 20
},
fab: {
position: 'absolute',
margin: 20,
right: 0,
bottom: 10
},
listTitle: {
fontSize: 20
}
})
export default Teacher
studentStore.js
import { createStore } from 'redux'
import studentReducer from '../actions/studentList'
const studentStore = createStore(studentReducer)
export default studentStore
teacherStore.js
import { createStore } from 'redux'
import teacherReducer from '../actions/teacherList'
const teacherStore = createStore(teacherReducer)
export default teacherStore
teacherReducer.js
import remove from 'lodash.remove'
export const ADD_NUMBER = 'ADD_NUMBER'
export const DELETE_NUMBER = 'DELETE_NUMBER'
let numberID = 0
export function addnumber(number) {
return {
type: ADD_NUMBER,
id: numberID++,
number
}
}
export function deletenumber(id) {
return {
type: DELETE_NUMBER,
payload: id
}
}
const initialState = []
function teacherReducer(state = initialState, action) {
switch (action.type) {
case ADD_NUMBER:
return [
...state,
{
id: action.id,
number: action.number
}
]
case DELETE_NUMBER:
const deletedNewArray = remove(state, obj => {
return obj.id != action.payload
})
return deletedNewArray
default:
return state
}
}
export default teacherReducer
studetnReducer.js
import remove from 'lodash.remove'
export const ADD_NUMBER = 'ADD_NUMBER'
export const DELETE_NUMBER = 'DELETE_NUMBER'
let numberID = 0
export function addnumber(number) {
return {
type: ADD_NUMBER,
id: numberID++,
number
}
}
export function deletenumber(id) {
return {
type: DELETE_NUMBER,
payload: id
}
}
const initialState = []
function studentReducer(state = initialState, action) {
switch (action.type) {
case ADD_NUMBER:
return [
...state,
{
id: action.id,
number: action.number
}
]
case DELETE_NUMBER:
const deletedNewArray = remove(state, obj => {
return obj.id != action.payload
})
return deletedNewArray
default:
return state
}
}
export default studentReducer
I Have tried this but is working only for Teachers not for both..
I want the state of my variable (with which it is given a value from a textInput) is sent to a reducer and change the state of that reducer by the state of the variable that I sent, so that way I can show it in different screens using mapStateToProps and I get it globally.
Is there any way to do that? I researched and found examples but not the way I want to do it.
I clarify my code is just an example so that you understand what I want to do, do not take it as a guide as I do not know if it works that way
I show you some of my code to give you an idea of what I
import React, { Component } from "react";
import {
View,
Text,
StyleSheet,
TextInput,
TouchableOpacity
} from "react-native";
import { connect } from 'react-redux';
class ScreenHome extends Component {
static navigationOptions = {
header: null
}
constructor(props) {
super(props);
this.state = {
Texto: '',
}
}
render() {
this.props.ChangeState({type: 'ACTION_TYPE', Texto: this.state.Texto});
const { navigation } = this.props;
return (
<View style={styles.container}>
<TextInput
placeholder="Enter Text"
value={this.state.Texto}
onChangeText={Texto => this.setState({ Texto })}
/>
<View style={{ marginBottom: 10, marginTop: 10, backgroundColor: 'black', padding: 10 }}>
<TouchableOpacity onPress={this.props.ChangeState}>
<Text style={{ color: 'white' }}>Send Text Input status to the reducer</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity style={{ backgroundColor: 'blue', padding: 10 }} onPress={() => { navigation.navigate('Other') }}>
<Text style={{ color: '#fff' }}>Go</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const mapStateToProps = (state) => {
return {
// prop: state.prop
}
}
const mapDispatchToProps = (dispatch) => {
return {
ChangeState: () => {
// dispatch({ type: 'ACTION_TYPE', Texto: this.state.Texto });
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ScreenHome)
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
});
OTHER SCREEN:
import React, { Component } from "react";
import {
View,
Text,
StyleSheet,
TouchableOpacity
} from "react-native";
import { connect } from 'react-redux';
class ScreenOther extends Component {
static navigationOptions = {
header: null
}
render() {
const { navigation } = this.props;
return (
<View style={styles.container}>
<Text>{this.props.StateInitial}</Text>
<TouchableOpacity onPress={() => { navigation.navigate('Home') }}>
<Text>Go back</Text>
</TouchableOpacity>
</View>
);
}
}
const mapStateToProps = (state) => {
return {
StateInitial: state.reducerText
}
}
const mapDispatchToProps = (dispatch) => {
return {
// ChangeState: () => {
// dispatch({type: 'CHANGE_TEXT'})
// }
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ScreenOther)
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
});
Store
import { createStore, combineReducers } from 'redux';
const reducerText = (state = [0], action) => {
switch (action.type) {
case 'ACTION_TYPE':
return {...state, Texto:action.Texto};
default:
return state;
}
};
const Reducers = combineReducers({
reducerText
})
const Store = createStore(Reducers)
export default Store;
dispatch1 should be visible in your props in the homescreen. So if you do
this.props.dispatch1({type: 'YOUR_ACTION_TYPE', Text: this.state.Text});
Your reducer function will be called where you can do:
reducer: (state, action) => {
switch (action.type) {
case 'YOUR_ACTION_TYPE':
return {...state, Text:action.Text};
}
}
Then in the other screen you should get the changed Text prop.
For those who look at this post and want to do something similar, I mean send the status of the textInput variable to a reducer and ask for the status from another screen with redux feel free to see the code that I will leave below since I was investigating and I got it after a while.
This is the code of redux-form
import React, { Component } from "react";
import {
View,
TextInput,
StyleSheet,
Button,
Text
} from "react-native";
import { Field, reduxForm } from 'redux-form';
import { connect } from 'react-redux';
const ScreenFormHome = (props) => (
<View>
<Field name="Text" component={fieldNombre} ph="Enter Text" />
<Button title="Send Dispatch" onPress={props.handleSubmit((values) => props.SendDispatch(values))} />
</View>
);
const fieldNombre = (props) => (
<View style={styles.textInput}>
<TextInput
placeholder={props.ph}
onChangeText={props.input.onChange}
value={props.input.value}
autoCapitalize="none"
onBlur={props.input.onBlur}
/>
<View style={styles.linea} />
</View>
);
const styles = StyleSheet.create({
textInput: {
marginBottom: 16,
},
linea: {
backgroundColor: '#DCDCDC',
height: 2,
},
});
const mapDispatchToProps = (dispatch) => {
return {
SendDispatch: (values) => {
dispatch({ type: 'ACTION_TYPE', Text: values.Text })
}
}
}
const mapStateToProps = (state) => {
return {
// StateInitial: state.reducerText
}
}
export default reduxForm({
form: 'ScreenFormHome',
})(connect(mapStateToProps, mapDispatchToProps)(ScreenFormHome));
and this is the component code
import React, { Component } from "react";
import {
View,
Text,
StyleSheet,
TouchableOpacity
} from "react-native";
import ScreenFormHome from "./ScreenFormHome";
class ScreenHome extends Component {
static navigationOptions = {
header: null
}
render() {
const { navigation } = this.props;
return (
<View style={styles.container}>
<TouchableOpacity style={{ backgroundColor: 'blue', padding: 10, marginBottom: 10 }} onPress={() => { navigation.navigate('Other') }}>
<Text style={{ color: '#fff' }}>Go</Text>
</TouchableOpacity>
<ScreenFormHome />
</View>
);
}
}
export default ScreenHome;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
});
This is the Store code
import { createStore, combineReducers } from 'redux';
import { reducer as form } from 'redux-form'
const reducerText = (state = [], action) => {
switch (action.type) {
case 'ACTION_TYPE':
return (action.Text)
default:
return state;
}
};
const Reducers = combineReducers({
reducerText,
form
})
const Store = createStore(Reducers)
export default Store;
how to navigate from LoginForm.js to product.js ?
route.js
import React from 'react';
import { StyleSheet,View,Text } from 'react-native';
import { StackNavigator } from 'react-navigation';
import Home from './pages/home';
import Products from './pages/product';
// import Products from './pages/components/LoginForm';
const navigation = StackNavigator({
Home : { screen: Home },
// Login : { screen: LoginForm },
Products : { screen: Products },
});
export default navigation;
home.js
import React from 'react';
import { StyleSheet, Text, View, Button, StatusBar, Image } from 'react-native';
import LoginForm from './components/LoginForm';
export default class Home extends React.Component {
static navigationOptions = {
header: null
};
render() {
return (
<View style = { styles.container }>
<StatusBar
backgroundColor="#007ac1" barStyle="light-content"/>
<View style= { styles.logoContainer }>
<Image style = {styles.logo} source={require('../images/logo.png')} />
</View>
<View style= { styles.formContainer }>
<LoginForm />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#03a9f4'
},
logoContainer: {
flexGrow: 1, justifyContent:'center', alignItems:'center'
},
logo: {
width: 80, height: 80
},
formContainer: {
}
});
LoginForm.js
import React from 'react';
import { StyleSheet, Text, View ,TextInput, TouchableOpacity } from 'react-native';
export default class LoginForm extends React.Component {
constructor(props){
super(props)
this.state={
userName:'',
password:'',
type:'A'
}
}
userLogin = () =>{
const { userName } = this.state;
const { password } = this.state;
const { type } = this.state;
fetch('http://192.168.0.4:3000/notes',{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body:JSON.stringify({
userName : userName,
password : password,
type : type
})
})
.then((response)=> response.json())
.then((responseJson) => {
if(responseJson.response.success == true) {
// alert(responseJson.response.result);
navigate('Products');
}else{
alert(responseJson.response.result);
}
})
.catch((error)=>{
console.error(error);
})
}
render() {
return (
<View style = {styles.container}>
<TextInput
underlineColorAndroid="transparent"
placeholder="Username or Email"
placeholderTextColor = "rgba(255,255,255,0.7)"
returnKeyType="next"
onSubmitEditing={() => this.passwordInput.focus()}
onChangeText = {userName => this.setState({userName})}
style={styles.input} />
<TextInput
placeholder="Password"
underlineColorAndroid="transparent"
secureTextEntry
returnKeyType="go"
placeholderTextColor = "rgba(255,255,255,0.7)"
ref = {(input) => this.passwordInput = input}
onChangeText = {password => this.setState({password})}
style={styles.input} />
<TouchableOpacity style={styles.buttonContainer} onPress={this.userLogin} >
<Text style={styles.buttonText}>LOGIN</Text>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
container : {
padding:20
},
input: {
height:40, backgroundColor: 'rgba(255,255,255,0.2)', marginBottom:20,
color:'#FFF', paddingHorizontal:10, borderRadius:5
},
buttonContainer: {
backgroundColor: "#2980b9", paddingVertical:10, borderRadius:5
},
buttonText: {
textAlign :'center', color:'#FFFFFF', fontWeight:'700'
}
});
product.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class Product extends React.Component {
static navigationOptions = {
// title: 'Home',
header: null
};
render() {
return (
<View style = { styles.container }>
<Text> Product Page open </Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Make LoginForm as part of navigator (it is currently commented). Then inside the userLogin function use this.props.navigation.navigate('Products') to navigate, take a look at the navigation doc
userLogin = () =>{
...
fetch('http://192.168.0.4:3000/notes',{
...
})
.then((response)=> response.json())
.then((responseJson) => {
if(responseJson.response.success == true) {
// alert(responseJson.response.result);
this.props.navigation.navigate('Products');
}else{
alert(responseJson.response.result);
}
})
.catch((error)=>{
console.error(error);
})
}
Hope this will help!