TouchableRipple onPress is not working with react navigation - react-native

I am using stack navigator in my app to navigate through different components. but here I am facing 2 different issues. issue (1) I used a switch to toggle between dark and light theme, in the module, it works fine when using onPress but when called through stack screen it is not working. issue (2) I wanted to give some space between header text and the switch button but every time I add some padding to switch component, it is also applied to the header text. How can I solve these issues?
Here is App.js Component code:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* #format
* #flow strict-local
*/
import React from 'react';
import {StatusBar, View} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import Home from './src/screens/Home';
import Details from './src/screens/Details';
import {createStackNavigator} from '#react-navigation/stack';
import {DarkTheme, Text, Title} from 'react-native-paper';
const Stack = createStackNavigator();
const App = () => {
const Darkthemebtntoggle = () => {
return (
<Details />
);
};
return (
<>
<NavigationContainer>
<StatusBar barStyle="dark-content" />
<Stack.Navigator screenOptions={{headerTitleAlign: ''}}>
<Stack.Screen
name="Home"
component={Home}
options={{
headerTitle: (props) => (
<Darkthemebtntoggle {...props} />
),
}}
/>
</Stack.Navigator>
</NavigationContainer>
</>
);
};
export default App;
Here is also Details.js component code:
import React, {useState} from 'react';
import {View, Text} from 'react-native';
import {TouchableRipple, Switch, Title} from 'react-native-paper';
function Details() {
const [isDartheme, setDarkTheme] = useState(false);
const togglemethod = () => {
setDarkTheme(!isDartheme);
};
return (
<View style={{flexDirection:"row"}}>
<View >
<Title>
<Text >Home</Text>
</Title>
</View>
<View style={{ paddingLeft:10, flexDirection:"row"}}>
<TouchableRipple
onPress={() => {
togglemethod();
}}>
<View pointerEvents="none">
<Switch value={isDartheme} />
</View>
</TouchableRipple>
</View>
</View>
);
}
export default Details;
Here is a screenshot of the behavior of the header:

Related

ReactNative Navigation to a screen in the same direcotry

I am very new to react native and I had one question to ask. I have two screens in the same directory
screens:
Pro.js
Register.js
in Pro.js , there is one button to navigate to Register.js
<Button
textStyle={{ fontFamily: 'montserrat-regular', fontSize: 12 }}
style={styles.button}
onPress={() => navigation.navigate("Register")}>
GET STARTED
</Button>
When I run above, I get below error:
The action 'NAVIGATE' with payload {"name":"Register"} was not handled by any navigator.
Do you have a screen named 'Register'?
If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.
This is a development-only warning and won't be shown in production.
Can anyone help me to navigate to that page?
Check below code:
App.js
import React from 'react';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import RegisterScreen from './RegisterScreen';
import HomeScreen from './HomeScreen';
const Stack = createStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Register" component={RegisterScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
HomeScreen.js
import React from 'react';
import { View, Text, Button } from 'react-native';
const HomeScreen = ({ navigation }) => {
return (
<View>
<Text>This is the Home screen</Text>
<Button
title="Go to Register"
onPress={() => navigation.navigate('Register')}
/>
</View>
);
};
export default HomeScreen
RegisterScreen.js
import React from 'react';
import { View, Text, Button } from 'react-native';
const RegisterScreen = () => {
return (
<View>
<Text>This is the Register screen</Text>
</View>
);
};
export default RegisterScreen

Why can I not navigate to another page from FlatList component in react native?

I'm not sure what's wrong here, as far as I can tell I am doing this correctly as it has worked everywhere else in my app. The only difference is that I'm trying to do this from a FlatList component. What is wrong with this? I've also tried putting {navigation} in renderMyItem instead of FLToyCard brackets, didn't work either. Error I'm getting is:
TypeError: undefined is not an object (evaluating 'navigation.navigate').
import { StyleSheet, Text, View, FlatList } from 'react-native'
import React from 'react'
import Toy from './Database'
import ToyCard from './ToyCard'
const FLToyCard = ({navigation}) => {
const headerComp = () => {
return(
<View style={{alignSelf: 'center'}}>
<Text style={{fontSize: 25, padding: 10}}>All Toys For Sale</Text>
</View>
)
}
const renderMyItem = ({item}) => {
return(
<View style={{flex: 1}}>
<ToyCard
name={item.name}
image={item.image}
price={item.price}
desc={item.desc}
seller={item.seller}
onPress={()=>navigation.navigate('SlugProduct')}
/>
</View>
)
}
return(
<View>
<FlatList
data={Toy}
renderItem={renderMyItem}
keyExtractor={(item)=>item.id}
numColumns={2}
ListHeaderComponent={headerComp}
/>
</View>
)
}
export default FLToyCard
This is my App.js:
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native'
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import SlugProduct from './Screens/SlugProduct';
export default function App() {
const Stack = createNativeStackNavigator()
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Login' >
// list of other pages
<Stack.Screen name="SlugProduct" component={SlugProduct} />
<Stack.Screen name='ViewToys' component={ViewToys}
</Stack.Navigator>
</NavigationContainer>
);
}
EDIT: heres the ViewToys page that FLToyCard is being input into. I've tried adding the onPress into both Views and FLToyCard but got the same error each time.
import { StyleSheet, Text, View, ScrollView} from 'react-native'
import React from 'react'
import FLToyCard from '../Components/FlatListCards'
const ViewToys = ({navigation}) => {
return (
<View style={{backgroundColor: '#ffce20', height: '100%'}}>
<View>
<FLToyCard />
</View>
</View>
)
}
export default ViewToys
The issue is that your not passing navigation props from screen ViewToys into component FLToyCard.
Try this
In ViewToys Screen:
import { StyleSheet, Text, View, ScrollView} from 'react-native'
import React from 'react'
import FLToyCard from '../Components/FlatListCards'
const ViewToys = ({navigation}) => {
return (
<View style={{backgroundColor: '#ffce20', height: '100%'}}>
<View>
<FLToyCard navigation={navigation}/>
</View>
</View>
)
}
export default ViewToys
change this <FLToyCard /> to this <FLToyCard navigation={navigation} />
and you are all done.
you are getting undefined in navigation in FLToyCard component that's why you are getting this error.
This error come when we do not put these mention in a page
import { NavigationContainer,useFocusEffect } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
So I think put above in every page once your problem will solve,

ReactNative; How to call new component to open new screen?

I want to open new screen from Nextpage.js ,after "onPress" worked, everything still same, NextPage not show on screen but not error. How should I do?
import NextPage from './NextPage';
function onClick() {
<NextPage/>
}
<TouchableHighlight onPress = {onClick}>
<View style={[styles.itemContainer, { backgroundColor: item.code }]}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemCode}>{item.code}</Text>
</View>
</TouchableHighlight>
you can't call a screen like that. If you want to navigate to any other screen in your case NextPage, you should define it in your navigation stack first. After that, you can call function navigation.navigate("NextPage") to navigate to next page.
Navigator file:
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import * as React from 'react';
import Home from '../screens/Home';
import Next from '../screens/Next';
const Stack = createStackNavigator();
function App({initialRouteName = 'Home'}) {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Home"
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Next" component={Next} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
Suppose you are navigating from Home to NextPage
import React from 'react';
import {StyleSheet, Text, View} from 'react-native';
export default function Home(props) {
function onClick() {
props.navigation.navigate('NextPage');
}
return (
<TouchableHighlight onPress={onClick}>
<View style={[styles.itemContainer, {backgroundColor: item.code}]}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemCode}>{item.code}</Text>
</View>
</TouchableHighlight>
);
}
const styles = StyleSheet.create({});

How to open drawer in react native using navigation.openDrawer()

I wanted to create a burger icon to open drawer but has been unable to do so. I have included the icon button on the right of my header. Whenever I click it to open the drawer, it shows the error of undefined function. I have mentioned the error below.
TypeError: navigation.openDrawer is not a function. (In 'navigation.openDrawer()', 'navigation.openDrawer' is undefined)
This is App.js, in this I have mentioned the code for drawer using createDrawerNavigator()
App.js
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import PassengerScreen from './Passenger';
import Lovedones from './Lovedones';
import NewTab from './FirstScreen';
import { createDrawerNavigator } from '#react-navigation/drawer';
const Drawer = createDrawerNavigator();
export default App=() => (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Passenger" drawerPosition="right" >
<Drawer.Screen name="Passenger" component={PassengerScreen} options= {{ title:'Passenger'}} />
<Drawer.Screen name="Lovedones" component={Lovedones} options= {{ title:'loved ones!!'}} />
<Drawer.Screen name="New Screen" component={NewTab} />
</Drawer.Navigator>
</NavigationContainer>
);
This is AccountScreen.js, in this code, I have created the icon button to open the drawer using navigation.openDrawer()
AccountScreen.js
import * as React from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import { createStackNavigator } from '#react-navigation/stack';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { createDrawerNavigator } from '#react-navigation/drawer';
const Stack= createStackNavigator();
Account = () => {
return <View style={styles.container}>
<Text>Hello!!</Text>
</View>
};
export default AccountStack =(navigation)=>(
<Stack.Navigator >
<Stack.Screen name="Account" component= {Account} options={{headerRight: () => (<Ionicons.Button name="reorder-three" color={"#FF0000"} size={40} backgroundColor= {"none"} onPress={() => navigation.openDrawer()}/> ) }} />
</Stack.Navigator>
);
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
Kindly help me in identifying the error.
The problem is in this line
export default AccountStack =(navigation)=>.
Here your navigation variable points to the props instead of props.navigation.
To fix this you should destructure your navigation object from the props and change this line to
export default AccountStack =({navigation})=>

Not Able to Navigate from DrawerLayoutAndroid to any other screen in react native (android)

I have the following code
Sidebar.js
import React from 'react'
import {View,Text,StyleSheet,Image,TouchableHighlight} from 'react-native';
import {Dimensions} from 'react-native';
import Feather from 'react-native-vector-icons/Feather';
// const WIDTH = Dimensions.get('window').width;
const HEIGHT = Dimensions.get('window').height;
const logo = require('../assets/logo1.png');
export default class Sidebar extends React.Component {
constructor(props){
super(props);
this.handleNavigation = this.handleNavigation.bind(this);// you should bind this to the method that call the props
}
handleNavigation(){
this.props.navigation.navigate('QuoteDay');
}
render() {
return (
<View style={styles.navigationContainer}>
<View style={styles.logoContainer}>
<Image style={styles.logo}
source={logo} />
</View>
</TouchableHighlight>
<TouchableHighlight
activeOpacity={0.6}
underlayColor="#ffffff"
onPress={() => alert('Pressed!')}>
<Text style={styles.listitem}> <Feather name="edit" size={30} color="#273746"/> Quotes </Text>
</TouchableHighlight>
<TouchableHighlight
activeOpacity={0.6}
underlayColor="#ffffff"
onPress={this.handleNavigation}>
<Text style={styles.listitem}> <Feather name="sunrise" size={30} color="#273746"/> Quote of the Day </Text>
</TouchableHighlight>
</View>
</View>
)
}
}
App.js
import React from 'react';
import {DrawerLayoutAndroid} from 'react-native';
import {AppNavigator} from './screens/Navigation';
import Sidebar from './screens/Sidebar';
export default class App extends React.Component {
render(){
const navigationView = (
<Sidebar/>
);
return (
<DrawerLayoutAndroid
drawerWidth={300}
drawerPosition="left"
statusBarBackgroundColor="#F0B27A"
renderNavigationView={() => navigationView}
>
<AppNavigator />
</DrawerLayoutAndroid>
)
}
}
Navigation.js
import React from 'react';
import 'react-native-gesture-handler';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { HomeScreen } from './Home';
import { ModalScreen } from './Modal';
import { QuoteScreen } from './QuoteDay';
const { Navigator, Screen } = createStackNavigator();
const HomeNavigator = () => (
<Navigator mode="modal" headerMode='none'>
<Screen name='Home' component={HomeScreen} />
<Screen name='MyModal' component={ModalScreen}/>
<Screen name='QuoteDay' component={QuoteScreen}/>
</Navigator>
);
export const AppNavigator = () => (
<NavigationContainer>
<HomeNavigator/>
</NavigationContainer>
);
But it is giving me the following error
TypeError: undefined is not an object (evaluating 'this.props.navigation.navigate')
whenever I try to navigate from Sidebar.js to any other screen.
How should could I go about solving this sort of this problem.
The problem is that Sidebar is not rendered inside a screen in a navigator and does therefore not receive the navigation prop which explains the error you're getting.
I recommend you to use react navigation's Drawer (https://reactnavigation.org/docs/drawer-navigator/) instead of DrawerLayoutAndroid. You can still use your custom Sidebar component layout this way by passing Sidebar to the drawerContent prop of react navigation's Drawer navigator.
Navigation.js
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import {createDrawerNavigator} from '#react-navigation/drawer';
import Sidebar from './path';
// Other imports...
const Home = createStackNavigator();
const Main = createDrawerNavigator();
const MainNavigator = () => {
return (
<Main.Navigator
drawerStyle={{width: 240}}
drawerContent={(props) => <Sidebar {...props} />}>
<Main.Screen name="HomeNavigator" component={HomeNavigator} />
</Main.Navigator>
);
};
const HomeNavigator = () => (
<Home.Navigator mode="modal" headerMode="none">
<Home.Screen name="Home" component={HomeScreen} />
<Home.Screen name="MyModal" component={ModalScreen} />
<Home.Screen name="QuoteDay" component={QuoteScreen} />
</Home.Navigator>
);
export const AppNavigator = () => (
<NavigationContainer>
<MainNavigator />
</NavigationContainer>
);
App.js
// Be sure to import StatusBar from 'react-native' for setting the status bar color
export default class App extends React.Component {
componentDidMount() {
StatusBar.setBackgroundColor('#F0B27A');
}
render() {
return <AppNavigator />;
}
}
So the approach I've taken here is to create a Drawer Navigator and to make this the main navigator. The HomeNavigator is a screen of this MainNavigator. This way every screen inside MainNavigator has access to the drawer and the navigation prop; In this case that means HomeNavigator and every screen it has.