React Native Buttons onPress nothing happens, also onChangeText not working - react-native

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.

Related

How to add an Update + Delete feature in my Details page in React Native? (DjangoRestFramework + 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")}
/>

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",
},
});

'OnPress' non functional used in ternary operator

I am new to React Native. I am trying to render a button conditional on the value of a 'global' value. This is incredibly frustrating.
Normally it would be a simple case of using an 'if/else' statement to accomplish this in Javascript or nearly any other language. Apparently this is not possible in React Native. Here is my code:
import React, { useState } from 'react';
import { Button, Text, TextInput, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function HomeScreen({ navigation }) {
const [isLogged, setLog] = useState(0);
return (
<>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
{isLogged === 0 ? (<Button title="Go to Login"> onPress={() => navigation.navigate('Login')} </Button>) : (<Button title="Do Stuff"> onPress={() => navigation.navigate('Stuff')} </Button>)}
</>
);
}
function LoginScreen({ navigation }) {
//do things to login here
}
function StuffScreen({ navigation }) {
//do other things here
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Stuff" component={StuffScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
This code above correctly renders a 'Home' screen with a button that reads 'Go to Login' as it should. However the 'OnPress' statement attached to the button is not functional...nothing happens when pressing the button on the phone. If I were to simply insert a button with the 'OnPress' assigned singly, without the ternary operator statement, I can get the button to be functional.
Can somebody please explain why the 'OnPress' is not functioning when the button is used within a ternary operator? In addition would I be able to change the value of 'isLogged' in another function (for example the 'Login') and have this correctly pass to the 'Home' screen?
Why are simple tasks that could be handled with 'if/else' statements so challenging in React Native? This is driving me crazy...I thank you in advance.
The way you are providing the onpress is wrong. You are providing it as a child but it should be a prop like below.
{isLogged === 0 ? (
<Button
title="Go to Login"
onPress={() => navigation.navigate('Login')}
/>
) : (
<Button
title="Do Stuff"
onPress={() => navigation.navigate('Stuff')} />
)
}

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

undefined is not a function (evaluating navigate(screen))

1.Can't navigate to the screen from inside the content component to the mention screen
import React, { Component } from "react";
import {View,Text,Button,Image,StyleSheet,TouchableOpacity} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons'
import SettingsScreen from '../screens/SettingsScreen'
export default class DrawerScreen extends Component{
static navigationOptions= ({navigation}) =>({
});
render(){
return(
<View style={styles.container}>
<Image style={styles.Image}
source={require('../images/defalut.png')} />
<Text> #username </Text>
<View>
<Icon
name='ios-settings'
color='#000'
size={14}
/>
<Button
onPress={() =>{
const { navigate } = this.props.navigation.navigate;
navigate('SettingsScreen')}}
color="orange"
title="Settings"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
Image:{
width:70,
height:80,
borderRadius:40
}
});
Navigating to screen from contentComponent in drawer isnot working using the props function it still shows the error
and the still it can't navigate to the screen
Unfortunately I cannot yet add comments, so I have to use an answer.
Have you defined a route for your DrawerScreen Component?
Otherwise it will not get the navigation as a prop, afaik.
The problem is here:
const { navigate } = this.props.navigation.navigate;
navigate('SettingsScreen')}}
You are trying to take the navigate function from the navigate function.
What is the problem with using just:
this.props.navigation.navigate('SettingsScreen');