How to add an Update + Delete feature in my Details page in React Native? (DjangoRestFramework + React Native)? - react-native

My app is a CRUD React Native that interacts with Django Rest Framework based off of a book called "Building Versatile Mobile Apps with Python and REST: RESTful Web Services with Django and React".
The project lets users enter in different data fields about pizza restaurants and display them.
I've been able to build the Crud web application in React and Django and a mobile app with Django and React native that only lets me add and read data.
I'm on the very last chapter and I'm about to deploy, but I don't know how to send update and delete requests in React Native to an API the book never covers this section. I added an update button but I don't know how to logically navigate to an edit section from the detail_view.js section.
Here is the open source code from the book on github
This is my app.js file
import React from 'react';
import { StyleSheet, Text, SafeAreaView, Image } from 'react-native';
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import { createDrawerNavigator } from '#react-navigation/drawer';
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import ListView from "./src/screens/components/function_list_view";
import DetailView from "./src/screens/components/detail_view";
import AddPizzeria from "./src/screens/drawer/addPizzeria.js";
import RegForm from "./src/screens/drawer/regForm.js";
import LoginForm from "./src/screens/drawer/loginForm.js";
import TabOne from "./src/screens/tabs/tab1.js";
import TabTwo from "./src/screens/tabs/tab2.js";
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const Tab = createBottomTabNavigator();
renderTabComponents = () => (
<Tab.Navigator>
<Tab.Screen name="Tab 1" component={TabOne} />
<Tab.Screen name="Tab 2" component={TabTwo} />
</Tab.Navigator>
);
renderScreenComponents = () => (
<Stack.Navigator>
<Stack.Screen name="Home" component={ListView} />
<Stack.Screen name="Detail" component={DetailView} />
<Stack.Screen name="Tabs" children={this.renderTabComponents} />
</Stack.Navigator>
);
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="Home" children={this.renderScreenComponents} />
<Drawer.Screen name="Add Pizza" component={AddPizzeria} />
<Drawer.Screen name="Registration" component={RegForm} />
<Drawer.Screen name="Login" component={LoginForm} />
</Drawer.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
baseText: {
color: "navy",
fontSize: 30,
fontStyle: "italic",
},
newText:{
color: "red",
},
pizzaImage: {
width: 200,
height: 200,
},
})
Here is my detailview file:
import React, { useState, useEffect } from "react";
import {View, Text, Image, FlatList } from "react-native";
import client from "./../../api/client";
import styles from "./detail_styles";
const DetailView = ({ route }) => {
const [detail, setDetail] = useState("");
const { objurl } = route.params;
const getDetail = async (url) => {
try {
const response = await client.get(url);
if (!response.ok) {
setDetail(response.data);
}
} catch (error) {
console.log(error);
}
};
useEffect(()=>{
getDetail(objurl);
}, [])
return (
<View style={styles.center}>
<FlatList
horizontal={true}
data={detail.pizzeria_images}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => {
return (
<Image
style={styles.pizzaImage}
source={{
uri: item.image,
}}
/>
);
}}
/>
<Text style={styles.title}>Pizzeria: {detail.pizzeria_name}</Text>
<Text style={styles.details}>Address: {detail.street}</Text>
<Text style={styles.details}>
City: {detail.city}, {detail.state},{detail.zip_code}
</Text>
<Text style={styles.details}>Web: {detail.website}</Text>
<Text style={styles.details}>Ph: {detail.phone_number}</Text>
<Text style={styles.details}>Description: {detail.description}</Text>
<Text style={styles.details}>Email: {detail.email}</Text>
// this is where I want to edit the data fields
<Button
style={styles.addButton}
onPress={() => *I don't know what to navigate*}
title="Edit"
/>
</View>
);
}
export default DetailView;
This is the addPizzeria.js file that submits the data
import React, {useState} from "react";
import { SafeAreaView, ScrollView, TextInput, Button, NativeModules,Text, Alert } from "react-native";
import { Formik } from "formik";
import client from "./../../api/client";
import styles from "./addPizzeria_styles";
import validationSchema from "./addPizzeria_valid";
import PhotoPicker from "../components/shared/photo.js";
const AddPizzeria = () => {
const [photo, setPhoto] = useState("");
const postedAlert = () => {
Alert.alert("Success!", "Thank you! ", [
{
text: "Go to main screen",
onPress: () => NativeModules.DevSettings.reload()
},
]);
};
const handleSubmit = async (values) =>{
const data = new FormData();
data.append("pizzeria_name", values.pizzeria);
data.append("street", values.street);
data.append("city", values.city);
data.append("state", values.state);
data.append("zip_code", values.zip_code);
data.append("website", values.website);
data.append("phone_number", values.phone_number);
data.append("pizzeria_name", values.pizzeria);
data.append("description", values.description);
data.append("email", values.email);
data.append("logo_image", {
uri: photo,
name: "filename.jpg",
type: "image/jpg",
});
try {
const response = await client.post("api/create/", data); postedAlert();
} catch(error) {
console.log(error);
};
};
return (
<Formik
initialValues={{
pizzeria: "",
street: "",
city: "",
state: "",
zip_code: "",
website: "",
phone_number: "",
description: "",
email: "",
}}
onSubmit={handleSubmit}
validationSchema={validationSchema}
>
{({ handleChange, handleSubmit, values, errors }) => (
<SafeAreaView style={styles.content}>
<ScrollView>
<PhotoPicker photo={photo} onPressPhoto={(uri) => setPhoto(uri)} />
<TextInput
style={styles.textBox}
value={values.pizzeria}
placeholder="Enter a new pizz place here"
onChangeText={handleChange("pizzeria")}
/>
<Text style={styles.error}>{errors.pizzeria}</Text>
<TextInput
style={styles.textBox}
value={values.street}
placeholder="Street address"
onChangeText={handleChange("street")}
/>
<Text style={styles.error}>{errors.street}</Text>
<TextInput
style={styles.textBox}
value={values.city}
placeholder="City"
onChangeText={handleChange("city")}
/>
<Text style={styles.error}>{errors.city}</Text>
<TextInput
style={styles.textBox}
value={values.state}
placeholder="State"
onChangeText={handleChange("state")}
/>
<Text style={styles.error}>{errors.state}</Text>
<TextInput
style={styles.textBox}
value={values.zip_code}
placeholder="Zip"
onChangeText={handleChange("zip_code")}
/>
<Text style={styles.error}>{errors.zip_code}</Text>
<TextInput
style={styles.textBox}
value={values.website}
placeholder="Website"
onChangeText={handleChange("website")}
/>
<Text style={styles.error}>{errors.website}</Text>
<TextInput
style={styles.textBox}
value={values.phone_number}
placeholder="Phone number"
onChangeText={handleChange("phone_number")}
/>
<Text style={styles.error}>{errors.phone_number}</Text>
<TextInput
style={styles.textBox}
value={values.description}
placeholder="Description"
onChangeText={handleChange("description")}
/>
<Text style={styles.error}>{errors.description}</Text>
<TextInput
style={styles.textBox}
value={values.email}
placeholder="Email"
onChangeText={handleChange("email")}
/>
<Text style={styles.error}>{errors.email}</Text>
<Button
style={styles.addButton}
onPress={handleSubmit}
title="Submit"
/>
</ScrollView>
</SafeAreaView>
)}
</Formik>
)}
export default AddPizzeria;
I tried creating an update file that is same as my addpizzeria file, but I get lost trying to plan out where and how to structure it so I can reference it when I make a request to update that data.
The only viable option is to make a feature on the detailview.js to update the data. This is what I'm trying and unsure of. I don't know where to go from here aside from adding an update and delete button on this page that navigates to another file and does the delete and update functions. your text

Ok I solved the issue. It seems the creator of the book added tabs in app.js in the Bottonnavigator class just in case you'd want to add and Update and Delete feature in detailview.js page.
All that is needed is to just add the navigation.navigate("Tabs") in a button in my detailview.js file.
<Button
style={styles.addButton}
title="Click for tabs"
onPress={() => navigation.navigate("Tabs")}
/>

Related

React native (React navigation)- instance of same screen in differents tabs. Navigate from drawer

I have an issue with react navigation.
I would like to have the same behavior as the linkedIn app has.
I mean, in that app, you can open the settings page from the drawer in differents tabs. You can open it from the first tab, second one... and so on. and at the end you get multiple instances.
I am not able to reproduce this behavior
My navigation is:
One drawer with one drawer screen (one Tab navigator inside). 3 tabs screens inside that Tab navigator. Each one contains a stack. I have set the same screens in that screen. For example I want to share the Profile, so I have one profile screen in each tab.
In the customDrawer I navigate to screens name, but here is the problem. React navigation does not know what stack should call before calling the right screen.
And I cannot find a way to know the current mounted stack so I cannot set it dinamically in order to do inside the custom drawer:
onPress={() =>
props.navigation.navigate(Routes.student.home.STACK, { screen: Routes.student.SETTINGS })
}
Thanks!
App.tsx
/* eslint-disable react-native/no-inline-styles */
import 'react-native-gesture-handler';
import React from 'react';
import { Text } from 'react-native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItem,
} from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import { QueryClient, QueryClientProvider } from '#tanstack/react-query';
import { StatusBar } from 'expo-status-bar';
import HomeStackScreen from '#pages/Home';
import { Routes } from '#src/constants/routes';
import { PracticalStackScreen } from '#src/pages/Practical/Practical';
import { TheoryStackScreen } from '#src/pages/Theory/Theory';
// Create a client
const queryClient = new QueryClient();
const Tab = createBottomTabNavigator();
const Drawer = createDrawerNavigator();
const TabNavigator = () => {
return (
<Tab.Navigator
screenOptions={{ headerShown: false }}
initialRouteName={Routes.student.home.STACK}
>
<Tab.Screen
name={Routes.student.theory.STACK}
component={TheoryStackScreen}
options={{ title: 'TEÓRICO' }}
/>
<Tab.Screen
name={Routes.student.home.STACK}
component={HomeStackScreen}
options={{ title: '' }}
/>
<Tab.Screen
name={Routes.student.practical.STACK}
component={PracticalStackScreen}
options={{ title: 'PRÁCTICO' }}
/>
</Tab.Navigator>
);
};
function CustomDrawerContent(props: any) {
console.log('props ', props);
return (
<DrawerContentScrollView {...props}>
<Text>Mi cuenta</Text>
<DrawerItem
label='Configuración'
onPress={() => props.navigation.navigate(Routes.student.SETTINGS)}
/>
<DrawerItem
label='Métodos de pago'
onPress={() => props.navigation.navigate(Routes.student.PAYMENT)}
/>
<Text>Social</Text>
<DrawerItem
label='Tiktok'
onPress={() => props.navigation.navigate(Routes.student.PROFILE)}
/>
<Text>Ayuda</Text>
<DrawerItem
label='Preguntas frecuentes'
onPress={() => props.navigation.navigate(Routes.student.FAQ)}
/>
<DrawerItem
label='Atención al alumno'
onPress={() => props.navigation.navigate(Routes.student.STUDENT_SUPPORT)}
/>
</DrawerContentScrollView>
);
}
const DrawerNavigation = () => {
return (
<Drawer.Navigator
useLegacyImplementation={true}
drawerContent={(props) => <CustomDrawerContent {...props} />}
initialRouteName={Routes.student.home.STACK}
>
<Drawer.Screen name={Routes.MAIN_TAB} component={TabNavigator} />
</Drawer.Navigator>
);
};
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<StatusBar />
<NavigationContainer>
<DrawerNavigation />
</NavigationContainer>
</QueryClientProvider>
);
}
Home.tsx
/* eslint-disable react-native/no-color-literals */
import React from 'react';
import { StyleSheet, Text, View, Pressable } from 'react-native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { Routes } from '#src/constants/routes';
import Faq from '../Faq';
import Payment from '../Payment';
import Profile from '../Profile';
import Settings from '../Settings';
import StudentSupport from '../StudentSupport';
const HomeStack = createNativeStackNavigator();
export const HomeStackScreen = (): JSX.Element => {
return (
<HomeStack.Navigator
screenOptions={{ headerStyle: { backgroundColor: 'red' }, headerShown: false }}
>
<HomeStack.Screen name={Routes.student.home.MAIN} component={Home} />
<HomeStack.Screen name={Routes.student.PROFILE} component={Profile} />
<HomeStack.Screen name={Routes.student.SETTINGS} component={Settings} />
<HomeStack.Screen name={Routes.student.PAYMENT} component={Payment} />
<HomeStack.Screen name={Routes.student.FAQ} component={Faq} />
<HomeStack.Screen name={Routes.student.STUDENT_SUPPORT} component={StudentSupport} />
</HomeStack.Navigator>
);
};
export const Home = ({ navigation }: any): JSX.Element => (
<View style={styles.container}>
<Text>Home Screen</Text>
<Pressable style={styles.button} onPress={() => navigation.navigate(Routes.student.PROFILE)}>
<Text style={styles.text}>Perfil</Text>
</Pressable>
</View>
);
const backgroundColor = '#fff';
const styles = StyleSheet.create({
button: {
alignItems: 'center',
backgroundColor: 'grey',
borderRadius: 4,
elevation: 3,
justifyContent: 'center',
paddingHorizontal: 32,
paddingVertical: 12,
},
container: {
alignItems: 'center',
backgroundColor,
flex: 1,
justifyContent: 'center',
},
text: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
letterSpacing: 0.25,
lineHeight: 21,
},
});
Theroy.tsx
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { Routes } from '#src/constants/routes';
import Faq from '../Faq';
import Payment from '../Payment';
import Profile from '../Profile';
import Settings from '../Settings';
import StudentSupport from '../StudentSupport';
const TheoryStack = createNativeStackNavigator();
export const TheoryStackScreen = (): JSX.Element => {
return (
<TheoryStack.Navigator
screenOptions={{ headerStyle: { backgroundColor: 'red' }, headerShown: false }}
>
<TheoryStack.Screen name={Routes.student.theory.MAIN} component={Theory} />
<TheoryStack.Screen name={Routes.student.PROFILE} component={Profile} />
<TheoryStack.Screen name={Routes.student.SETTINGS} component={Settings} />
<TheoryStack.Screen name={Routes.student.PAYMENT} component={Payment} />
<TheoryStack.Screen name={Routes.student.FAQ} component={Faq} />
<TheoryStack.Screen name={Routes.student.STUDENT_SUPPORT} component={StudentSupport} />
</TheoryStack.Navigator>
);
};
export function Theory({ navigation }: any): JSX.Element {
return (
<View style={styles.container}>
<Text>Theory Screen</Text>
<Button title='Go to Home' onPress={() => navigation.navigate(Routes.student.home.STACK)} />
<Button
title='Go to Practical'
onPress={() => navigation.navigate(Routes.student.practical.STACK)}
/>
<Button
title='Go to Profile'
onPress={() =>
navigation.navigate(Routes.student.home.STACK, { screen: Routes.student.PROFILE })
}
/>
</View>
);
}
const backgroundColor = '#fff';
const styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor,
flex: 1,
justifyContent: 'center',
},
});
Practical.tsx
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { Routes } from '#src/constants/routes';
import Faq from '../Faq';
import Payment from '../Payment';
import Profile from '../Profile';
import Settings from '../Settings';
import StudentSupport from '../StudentSupport';
const PracticalStack = createNativeStackNavigator();
export const PracticalStackScreen = (): JSX.Element => {
return (
<PracticalStack.Navigator
screenOptions={{ headerStyle: { backgroundColor: 'red' }, headerShown: false }}
>
<PracticalStack.Screen name={Routes.student.practical.MAIN} component={Practical} />
<PracticalStack.Screen name={Routes.student.PROFILE} component={Profile} />
<PracticalStack.Screen name={Routes.student.SETTINGS} component={Settings} />
<PracticalStack.Screen name={Routes.student.PAYMENT} component={Payment} />
<PracticalStack.Screen name={Routes.student.FAQ} component={Faq} />
<PracticalStack.Screen name={Routes.student.STUDENT_SUPPORT} component={StudentSupport} />
</PracticalStack.Navigator>
);
};
export function Practical({ navigation }: any): JSX.Element {
return (
<View style={styles.container}>
<Text>Practical Screen</Text>
<Button title='Go to Home' onPress={() => navigation.navigate(Routes.student.home.STACK)} />
<Button
title='Go to Theory'
onPress={() => navigation.navigate(Routes.student.theory.STACK)}
/>
<Button
title='Go to Profile'
onPress={() =>
navigation.navigate(Routes.student.home.STACK, { screen: Routes.student.PROFILE })
}
/>
</View>
);
}
const backgroundColor = '#fff';
const styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor,
flex: 1,
justifyContent: 'center',
},
});
Try renaming your Settings screen component differently for each stack navigator. So something like
<PracticalStack.Screen name="Practical/Settings" component={Settings} />
<HomeStack.Screen name="Home/Settings" component={Settings} />
Then you could navigate to the appropriate screen from your drawer based on the tab in focus.
I think I found a possible solution to my question. I have changed the CustomDrawerContent.
function CustomDrawerContent(props: any) {
const drawerState = props.state.routes[0]?.state;
const routeIndex = drawerState?.index;
const focusedTab = drawerState?.routes?.[routeIndex]?.name || Routes.student.home.STACK;
return (
<DrawerContentScrollView {...props}>
<Text>Mi cuenta</Text>
<DrawerItem
label='Configuración'
onPress={() => props.navigation.navigate(focusedTab, { screen: Routes.student.SETTINGS })}
/>
<DrawerItem
label='Métodos de pago'
onPress={() => props.navigation.navigate(focusedTab, { screen: Routes.student.PAYMENT })}
/>
<Text>Social</Text>
<DrawerItem
label='Tiktok'
onPress={() => props.navigation.navigate(focusedTab, { screen: Routes.student.PROFILE })}
/>
<Text>Ayuda</Text>
<DrawerItem
label='Preguntas frecuentes'
onPress={() => props.navigation.navigate(focusedTab, { screen: Routes.student.FAQ })}
/>
<DrawerItem
label='Atención al alumno'
onPress={() =>
props.navigation.navigate(focusedTab, { screen: Routes.student.STUDENT_SUPPORT })
}
/>
</DrawerContentScrollView>
);
}

React Native — React-Navigation back button on wrong side of appbar?

Okay so I'm just jumping into React Native and I'm going through the docs with the react-navigation package. Whenever a screen is pushed onto the stack, the animation goes from right-left by default—Also I'm noticing the back button is on the right side of the appbar instead of the left be default. Is this by design or have I set something up incorrectly?
Also ignore the FC I'm using, I know it's not recommended but I'm just getting a feel for RN 😅
See image and code below:
import { StatusBar } from "expo-status-bar";
import { Button, StyleSheet, Text, View } from "react-native";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import { BaseNavigationContainer } from "#react-navigation/native";
import { FC } from "react";
import { StackScreenProps } from "./Types";
const Home: FC<StackScreenProps> = ({ navigation }) => {
return (
<View style={styles.container}>
<Text>Hello World </Text>
<Button
title="Switch Page"
onPress={() => {
navigation.navigate("About");
}}
/>
</View>
);
};
const About: FC<StackScreenProps> = ({ navigation }) => {
return (
<View style={styles.container}>
<Text>Learn the Process First</Text>
<Button title="Go Back" onPress={() => navigation.goBack()} />
</View>
);
};
const Stack = createNativeStackNavigator();
export default function App() {
return (
<BaseNavigationContainer>
{/* #ts-ignore */}
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="About" component={About} />
</Stack.Navigator>
</BaseNavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});

React Navigation Nested No Route Params v5

I can't seem to get any route params in my nested navigator. The params are present in the parent navigator, but they are not reachable in the child navigator.
So the child navigator does render the correct screen, but it does not have any params in the route (namely a category or product id).
It feels like I am misusing some syntax, but I can't quite figure out which one. Here is the stack of code, edited down a bit to make it easier to read.
Snack on Expo
Thank you.
Note: These are separate files so the includes are off.
import * as React from 'react';
import { Text, View, StyleSheet, SafeAreaView } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { NavigationContainer } from '#react-navigation/native'
import { createDrawerNavigator, DrawerContentScrollView, DrawerItem } from '#react-navigation/drawer'
import { createStackNavigator } from '#react-navigation/stack'
import { AppearanceProvider } from 'react-native-appearance'
const Drawer = createDrawerNavigator()
const Stack = createStackNavigator()
const HomeScreen = ({ navigation, route }) => {
return(
<View style={styles.container}>
<Text>Home Screen </Text>
</View>
)
}
const CategoryScreen = ({ navigation, route }) => {
return(
<View>
<Text>Category Screen </Text>
<Text>{JSON.stringify(route)}</Text>
</View>
)
}
const ProductScreen = ({ navigation, route }) => {
return(
<View>
<Text>Product Screen </Text>
<Text>{JSON.stringify(route)}</Text>
</View>
)
}
const CustomDrawerContent = ({ props }) => {
return (
<DrawerContentScrollView {...props}>
<DrawerItem
label="Home"
onPress={() => props.navigation.navigate('Home')}
/>
<DrawerItem
label="Category 1"
onPress={() =>
props.navigation.navigate('Main', {
Screen: 'Category',
params: { id: 1 },
})
}
/>
<DrawerItem
label="Category 2"
onPress={() =>
props.navigation.navigate('Main', {
Screen: 'Category',
params: { id: 101 },
})
}
/>
</DrawerContentScrollView>
)
}
const MainNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Category" component={CategoryScreen} />
<Stack.Screen name="Product" component={ProductScreen} />
</Stack.Navigator>
)
}
const ApplicationNavigator = () => {
return (
<NavigationContainer initialRouteName="Home">
<Drawer.Navigator
drawerContent={(props) => {
return <CustomDrawerContent props={props} />
}}
>
<Drawer.Screen
name="Home"
component={HomeScreen}
/>
<Drawer.Screen
name="Main"
component={MainNavigator}
/>
</Drawer.Navigator>
</NavigationContainer>
)
}
export default function App() {
return <ApplicationNavigator />
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
padding: 8,
backgroundColor: '#FFFFFF',
},
});
UPDATE
I have noted that if I initialize the params (blank, with values, whichever) outside of the custom drawer content first, the above code begins to work as expected.
Very simple and silly fix that a rubber duck could solve.
Screen !== screen. I was passing in an unknown param to navigate.

React Native Buttons onPress nothing happens, also onChangeText not working

I am new to React Native. I have a single login form with two fields. I want to authenticate the user before sending him to Dashboard.js. No matter what I try the button is not doing anything(absolutely nothing happens,no error). I have kept the code in Login.js to show all the things I have tried to do namely
routing to dashboard.js
trying to do something with invoking the handleSubmitPress function on button press.
pop an alert.
I have used two buttons. One from react-native-paper and one from react-native.
I am giving the code of my app.js and login.js below. Please can someone help?
CODE
App.js
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import DashBoard from "./mainmenu/DashBoard";
import Login from "./mainmenu/Login";
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="DashBoard" component={DashBoard} />
</Stack.Navigator>
</NavigationContainer>
);
}
Login.js
import React, { useState } from "react";
import { Title, TextInput} from "react-native-paper";
import { View, Alert,Button } from "react-native";
export default function Login() {
const [mobile, setMobile] = useState("123456789");
const [password, setPassword] = useState("123");
function handleSubmitPress() {
console.log({ mobile, password });
}
return (
<View
style={{
backgroundColor: "skyblue",
alignItems: "center",
justifyContent: "center",
}}
>
<TextInput
label="Your mobile number "
value={mobile}
onChangeText={(text) => setMobile(text)}
/>
<TextInput
label="Type Password "
value={password}
onChangeText={(text) => setPassword(text)}
/>
<Button
icon="camera"
type="submit"
mode="contained"
//onPress={() => props.navigation.navigate("DashBoard")}
onPress={()=>Alert.alert('Navigate pressed')}
>
Navigate
</Button>
<Button
title="Print"
onPress={() => Alert.alert('Simple Button pressed')}
// onPress={handleSubmitPress()}
/>
</View>
);
}
Change your Login component to this.
...
const Login = ({navigation}) => {
const [mobile, setMobile] = useState('123456789');
const [password, setPassword] = useState('123');
function handleSubmitPress() {
console.log({mobile, password});
}
return (
<View
style={{
backgroundColor: 'skyblue',
alignItems: 'center',
justifyContent: 'center',
}}>
<TextInput
label="Your mobile number "
value={mobile}
onChangeText={text => setMobile(text)}
/>
<TextInput
label="Type Password "
value={password}
onChangeText={text => setPassword(text)}
/>
<Button
title="title"
icon="camera"
type="submit"
mode="contained"
onPress={() => navigation.navigate('DashBoard')}>
Navigate
</Button>
<Button title="Print" onPress={() => handleSubmitPress()} />
</View>
);
};
export default App;
There were a couple problems.
I've used the default React Native buttons. So I added a title prop to one of the buttons, because that's required. I gave it the value "title", but change this to what you want or use the React Native Paper buttons.
The main problem was how you called handleSubmitPress in your button onPress.
Your onChangeText was fine, you just couldn't see the result, because the handleSubmitPress wasn't being called.
I've also used destructuring so you're able to access the navigation prop directly. You can also do const Long = (props) => {...} and use props.navigation, but either way you need to pass in something otherwise navigation will not work.

Navigation back click event in React Native

I am working on a React Native application. I am using navigation in my application. I want to do something when user presses back navigation i.e. moved to a back screen.
How can i get the click event of "blacked circle Frage" in the above image. I am working on IOS
Use a custom header with
import { Header } from "native-base";
And add below code in your route file to disable default header.
navigationOptions: {
header: null
}
my custome header code for your reference
<Header style={styles.header}>
<View style={{ flex: 2 }}>
<TouchableOpacity
style={styles.iconButton}
onPress={() => { this.createNote(); this.props.navigation.navigate('Home') }}>
<Icon name="arrow-back" size={28} color="#606060" />
</TouchableOpacity>
</View>
<View style={{ flex: 8 }}></View>
<View style={{ flex: 2 }}>
<TouchableOpacity
style={styles.iconButton}
onPress={() => { this.createNote(); this.props.navigation.navigate('Home') }}>
<Icon name="check" size={28} color="#606060" />
</TouchableOpacity>
</View>
</Header>
reference link:- https://www.npmjs.com/package/native-base
It probably varies depending on the libraries you are using. I am using react-native-paper in Expo, which uses the headerLeft option in the Stack.Screen component. Here's a complete example - save it and then 'expo start'
import { Provider as PaperProvider, Text } from 'react-native-paper'
import { NavigationContainer } from '#react-navigation/native'
import { createNativeStackNavigator } from '#react-navigation/native-stack';
const Stack = createNativeStackNavigator();
export default function App() {
return (
<PaperProvider>
<NavigationContainer >
<Stack.Navigator>
<Stack.Screen
name="Example"
options={{
title: 'Example',
headerLeft: () => <Text>Custom left button</Text>,
}}
component={() => <Text>Example body text</Text>}
/>
</Stack.Navigator>
</NavigationContainer>
</PaperProvider>
)
}
You can use onPress={() => this.props.navigation.goBack()} on TouchableOpacity if you are redirecting to the previous page
Also you can use this.props.navigation.navigate('Any_Screen') to move to other screens.
Also, I would like to suggest you to get familiar with BackHandler to move back to previous page when hardware back button is pressed.
add the code
onClick={this.props.navigation.goBack()}
or use specif navigation replace go back to
onClick={this.props.navigation.navigate('namepagespacific')}
check this screen there are mutiple example of handling click event
import React from 'react';
import { View, Text, StyleSheet, Button} from 'react-native';
class DetailsScreen extends React.Component {
static navigationOptions = ({ navigation, navigationOptions, screenProps }) => {
return {
title: navigation.getParam('title', 'A Nested Details Screen'),
};
};
render() {
const { navigation } = this.props;
const itemId = navigation.getParam('itemId', 'NO-ID');
const otherParam = navigation.getParam('otherParam', 'some default value');
return (
<View style={styles.detailsScreen}>
<Text>Details Screen</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
<Button
title="Go to Details... again"
onPress={() => this.props.navigation.push('Details')}
/>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.popToTop()}
/>
<Button
title="Update the title"
onPress={() => this.props.navigation.setParams({ title: 'Updated!' })}
/>
<Button
title="Modal"
onPress={() => this.props.navigation.navigate('MyModal')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
detailsScreen: {
flex: 1,
alignItems: "center",
justifyContent: "center"
}
})
export default DetailsScreen;
things you have asked in the comment section I could not find any exact answer for your question but you can take a look into this url how header buttons work
https://snack.expo.io/#react-navigation/simple-header-button-v3
hope this will work for you
header: ({ goBack }) => ({
left: ( <Icon name={'chevron-left'} onPress={ () => { goBack() } } /> ),
}),
you can also follow this page https://github.com/react-navigation/react-navigation/issues/779