onPress event not working on TouchableOpacity on Android - react-native

Before I begin, I have checked out other common solutions to this problem, like importing TouchableOpacity from 'react-native' instead of 'react-gesture-handler' (I don't even have it installed), or changing z-index/absolute positioning. None of them work.
I'm a beginner in react native. I'm trying to follow along with a react native course, but I'm stuck on this issue. I'm using Expo on a real Android. I don't use emulators. Haven't tested on iOS as I don't have access to one. When I add onPress to TouchableOpacity, most of the time it gives feedback when clicked (opacity changes), but it won't fire the onPress event. Sometimes, however, it works. When I press on the right edge, sometimes the event fires. Here's an example:
index.js
import React from "react";
import Options from "./screens/Options";
export default function App() {
return <Options />;
}
Options.js
import React from "react";
import { View, StyleSheet } from "react-native";
import RowItem from "../components/RowItem";
import Constants from "expo-constants";
import styled from "styled-components";
import colors from "../constants/colors";
import { Entypo } from "#expo/vector-icons";
const SSeparator = styled.View`
background: ${colors.border};
height: ${StyleSheet.hairlineWidth}px;
margin-left: 20px;
`;
const SView = styled.View`
margin-top: ${Constants.statusBarHeight}px;
`;
export default () => {
return (
<SView>
<RowItem
title="Themes"
icon={
<Entypo
name="chevron-left"
size={20}
color={colors.blue}
onPress={() => alert("click")}
/>
}
/>
<SSeparator />
</SView>
);
};
RowItem.js
import React from "react";
import { TouchableOpacity, Text } from "react-native";
import styled from "styled-components";
import colors from "../constants/colors";
const SText = styled.Text`
font-size: 16px;
`;
const STouchableOpacity = styled.TouchableOpacity`
margin: 16px 20px;
flex-direction: row;
align-items: center;
justify-content: space-between;
`;
export default ({ title, icon, onPress }) => {
return (
<STouchableOpacity onPress={onPress}>
<SText>{title}</SText>
{icon}
</STouchableOpacity>
);
};
Any ideas?

can you try like this:
export default () => {
const testFunc = () =>{
alert('test')
}
return (
<SView>
<RowItem
title="Themes"
icon={
<Entypo
name="chevron-left"
size={20}
color={colors.blue}
onPress={testFunc}
/>
}
/>
<SSeparator />
</SView>
);
};
and then :
<STouchableOpacity onPress={()=>onPress()}>
<SText>{title}</SText>
{icon}
</STouchableOpacity>

Okay, so I finally noticed the mistake, and I feel ashamed for not noticing it. I kept reading the code but I couldn't see the obvious.
I mistakenly copied the onPress event into the icon instead of putting it directly inside RowItem.
Instead of this:
<RowItem
title="Themes"
icon={
<Entypo
name="chevron-left"
size={20}
color={colors.blue}
onPress={() => alert("click")}
/>
}
/>
It should be this:
<RowItem
title="Themes"
handlePress={() => alert("test")}
icon={<Entypo name="chevron-left" size={20} color={colors.blue} />}
/>
And inside RowItem.js:
export default ({ title, icon, handlePress }) => {
return (
<STouchableOpacity onPress={() => handlePress()}>
<Text>{title}</Text>
{icon}
</STouchableOpacity>
);
};
And now the app works as intended.

Related

React-Navigation: How to implement multi-independant viewstacks with react-navigation (React-Native)

Good morning, good afternoon or good evening
I want to archive this navigation interface (for desktop / tablet screen size):
https://photos.app.goo.gl/ZEna1uozQP1UnVWm6
Each viewstack should be fully dependent to only one navigation; I am using react-navigation.
However, with my following code, the the pane view (the card) is completely hidden / gone on the main page.
How should I do this in order to archive the results on the prototype / video.
Below are my codes.
Thank you!
App.js (Main navigation)
import React, { FC } from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { ThemeProvider } from '#emotion/react';
import setTheme from '#lib/theme';
import changeNavigationBarColor from 'react-native-navigation-bar-color';
import {
Home as Billing,
Customers,
} from '#components/5-pages';
const theme = setTheme('light');
const Stack = createStackNavigator();
changeNavigationBarColor("black", false, true);
type Props = {};
const App: FC<Props> = ({...props}) => {
return (
<ThemeProvider theme={theme}>
<NavigationContainer>
<Stack.Navigator initialRouteName={"billing"} screenOptions={{ headerShown: false }}>
<Stack.Screen name="billing" component={ Billing } />
<Stack.Screen name="customers" component={ Customers } />
</Stack.Navigator>
</NavigationContainer>
</ThemeProvider>
);
};
export default App;
Card.js (Pane / Inner navigation)
import React, { FC }from 'react';
import styled from '#emotion/native';
import Text from './Text';
import setTheme from '#lib/theme';
import { NavigationContainer, useNavigation } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { ThemeProvider } from '#emotion/react';
const Container = styled.View`
background: ${({ theme }: any) => theme.colors.white };
border-radius: 6px;
flex-direction: column;
padding: 6px 12px;
margin: 6px 12px;
width: 320px;
`;
const Content = styled.View`
align-items: center;
flex-direction: column;
padding-left: 6px;
`;
const Title = styled(Text)`
font-size: 15px;
font-weight: bold;
color: #404040;
line-height: 49px;
`;
const Stack = createStackNavigator();
const theme = setTheme('light');
const Card: FC<Props> = ({ children, modal, title, ...props }) => {
const List : FC<Props>= () => {
const navigation = useNavigation();
return (
<Container {...props} >
<Title>{title}</Title>
<Content onModal={()=>{navigation.push("modal", props)}}>
{children}
</Content>
</Container>
)};
const Modal : FC<Props>= () => {
return (
<Container {...props} >
<Title>{title}</Title>
<Content>
{modal}
</Content>
</Container>
)};
return (
<NavigationContainer independent={true}>
<Stack.Navigator initialRouteName={"list"} screenOptions={{ headerShown: false }}>
<Stack.Screen name="list" component={ List } />
<Stack.Screen name="modal" component={ Modal } />
</Stack.Navigator>
</NavigationContainer>
);
}
type Props = {
title?: string;
children?: React.ReactNode;
modal?: React.ReactNode;
};
export default Card;

I want to move the screen with a button in React Native

I want to go to another screen by pressing the image button on the screen, but I don't know how. I am a complete beginner.
How can I go to the next page?
import React, { Component } from 'react'
import { StyleSheet, Text, View, TouchableOpacity,Image,Alert } from 'react-native';
import {} from 'react-navigation';
const ButtonScreen = props => {
const content = (
<View style= {[styles.button]}>
<Image source={require('../assets/icon/룰렛.png')} style={{
transform: [{scale: 0.37}],
}}
/>
</View>
)
return (
<TouchableOpacity onPress={() => {
Alert.alert('빨리');
}}
>{content}</TouchableOpacity>
)
}
const styles = StyleSheet.create ({
button: {
top: 60,
flexDirection: 'row',
alignItems: 'center',
height: '30%',
width: '100%',
},
})
export default ButtonScreen;
for navigation in react-native there are various libraries. react-navigation, react-native-router-flux, react-native-navigation(wix) are the ways you can use for navigation.
react-navigation is the famous one that currently has V5.x following by thorough documentation. It uses JavaScript codes for navigation and I assume you installed this library.
the react-native-router-flux use react-navigation V4.x and it really looks like react-router-dom in React-js. However I strongly suggest to not using that due to problems regarding performance.
react-native-navigation(wix) has the highest performance because it uses native codes for navigation. however it has poor document and it is really difficult for beginners to use.
In order to use the current version of react-navigation the first step you need to do is the installation of requirement then you need to have separate file for defining your routes. Lets assume you have two screens. the file looks like the following code:
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import Screen1 from 'the path of Screen1'
import Screen2 from ' the path of Screen2'
const Stack = createStackNavigator();
function Navigation() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Screen1" component={Screen1} />
<Stack.Screen name="Screen2" component={Screen2} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default Navigation
then you need to import this file on your index file.
import Navigation from "the path of Navigation";
AppRegistry.registerComponent(appName, () => Navigation);
if you are at ButtonScreen and you want to go on Screen2 you need the following code:
import React, { Component } from 'react'
import { StyleSheet, Text, View, TouchableOpacity,Image,Alert } from 'react-native';
const ButtonScreen = props => {
const content = (
<View style= {[styles.button]}>
<Image source={require('../assets/icon/룰렛.png')} style={{
transform: [{scale: 0.37}],
}}
/>
</View>
)
return (
<TouchableOpacity onPress={() => props.navigation.navigate("Screen2")}
>{content}</TouchableOpacity>
)
}
const styles = StyleSheet.create ({
button: {
top: 60,
flexDirection: 'row',
alignItems: 'center',
height: '30%',
width: '100%',
},
})
export default ButtonScreen;
this is the easiest way to navigate and I recommend you to read the document

React Navigation Bottom Tabs occupying the whole screen in React Native Web

I'm trying to use React-Navigation bottom tabs in React-Native-Web, the result is the expected in the device:
result in device
But in the web it gets like this:
result in the browser
If I inspect the page I can find the elements of main in there.
and here is the code:
src/App.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* #format
* #flow strict-local
*/
import React from 'react';
import {StatusBar} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import Main from './pages/Main/index';
const Tab = createBottomTabNavigator();
const App = () => {
return (
<>
<StatusBar
backgroundColor="transparent"
translucent
barStyle="light-content"
/>
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Main" component={Main} />
</Tab.Navigator>
</NavigationContainer>
</>
);
};
export default App;
src/pages/Main/index.js
import React, {useState, useEffect} from 'react';
import {View, Dimensions} from 'react-native';
// import api from '../../services/api';
import Company from '../../components/Company';
import {Container, Title, List} from './styles';
export default function Main() {
//...
return (
<View
style={{
display: 'flex',
flexDirection: 'column',
height: Dimensions.get('window').height,
justifyContent: 'center',
}}>
<Container>
<Title>Empresas Cadastradas</Title>
<List
keyboardShoulPersistTaps="handled"
data={companies}
keyExtractor={(item) => String(item.id)}
renderItem={({item}) => <Company data={item} />}
/>
</Container>
</View>
);
}
src/pages/Main/styles.js
import styled from 'styled-components/native';
export const Container = styled.View`
background-color: #7159c1;
padding-top: 30px;
flex: 1;
`;
export const Title = styled.Text`
font-size: 32px;
color: #fff;
font-weight: bold;
padding: 0 20px;
margin-bottom: 10px;
`;
export const List = styled.FlatList.attrs({
contentContainerStyle: {paddingHorizontal: 10},
showsVerticalScrollIndicator: false,
})`
margin-top: 20px;
`;
I've encountered the same problem, and the solution is to add index.css somewhere in your src, load it in your index.js or index.web.js, then put this:
html,
body {
height: 100%;
}
/* These styles disable body scrolling if you are using <ScrollView> */
body {
overflow: hidden;
}
/* These styles make the root element full-height */
#root {
display: flex;
height: 100%;
}
Found the solution in the following discussion:
https://github.com/react-navigation/react-navigation/issues/9187

React Native TextInput loses focus on call hook from useState

Environment
react-native: "0.61.5",
"styled-components": "4.4.1"
Reproduction
Snack example: https://snack.expo.io/BJSfYqlCS
import * as React from 'react';
import styled from 'styled-components'
import {View} from 'react-native'
export default () => {
const [text, setText] = React.useState('');
const StyledInput = styled.TextInput`
background-color: red;
border-color: black;
`
return (
<View>
<StyledInput value={text} onChangeText={text => setText(text)} />
</View>
);
}
Steps to reproduce
type something in styled TextInput
Expected Behavior
Just plain typing
Actual Behavior
lost focus
Get styles out of function
import * as React from 'react';
import styled from 'styled-components'
import {View} from 'react-native'
const StyledInput = styled.TextInput`
background-color: red;
border-color: black;
`
export default () => {
const [text, setText] = React.useState('');
return (
<View>
<StyledInput value={text} onChangeText={text => setText(text)} />
</View>
);
}
Check expo shack
So the problem is pretty tricky , It looks like the problem is that you're defining your StyledInput inside it's parent return method and then calling the parent's setText method directly (instead of passing through props), which causes rerender that you don't want.
Better approach would be to use direct text input and apply styling to it. Please see below code and also ive shared a working example in expo snack. do check that.
import * as React from 'react';
import styled from 'styled-components'
import {TextInput,View} from 'react-native';
export default () => {
const [text, setText] = React.useState('');
const StyledView = styled.View`
flex: 1;
align-items:center;
justify-content: center;
background-color: papayawhip;
`
const StyledInput = styled.TextInput`
background-color: white;
`
const StyledText = styled.Text`
color: palevioletred;
`
return (
<View>
<StyledText>Hello World!</StyledText>
<TextInput style={{height:50,width:50,backgroundColor:'red'}} value={text} onChangeText={text => setText(text)} />
</View>
);
}
expo snack expo url
Hope it helps. feel free for doubts

Touchable Highlight not rendering image

So I've added a TouchableHighlight into my code but it doesn't render the image into the app, and the navigation prop assigned to it isn't activated.
import React, { Component } from "react";
import { Center } from "#builderx/utils";
import { View, StyleSheet, Image, Text } from "react-native";
import { createAppContainer } from 'react-navigation';
import { MainNavigation } from '../screens/MainNavigator';
import { TouchableHighlight } from 'react-native'
import { AppContainer } from "../screens/MainNavigator"
export default class DlLoading_2 extends Component {
render() {
return (
<View style={styles.root}>
<Center />
<TouchableHighlight onPress={() =>
{this.props.navigation.navigate('DlMain')}}>
<Image
source={require('../assets/ComponentTMP_0-image.jpg')}
style={styles.blueDisk}/>
</TouchableHighlight>
<Center horizontal>
<Image
source={require("../assets/ComponentTMP_0-image2.png")}
style={styles.dlLogo}
/>
</Center>
<Center horizontal>
<Text style={styles.text}>TRANSINDENTAL MEDITATION</Text>
</Center>
</View>
)
}
}
const styles = StyleSheet.create({
blueDisk: {
height: 401.5,
width: 602,
position: "absolute"
}
});
I've tried changing the image type, adding the styling to the element and that's pretty much all I can think of.