When declaring the useRoute() hook of React Navigation (#react-navigation/native), I get the following error message:
Component Exception
Couldn't find a route object. Is your component inside a screen in a
navigator?
Source
if (route === undefined) {
throw new Error(
^
"Couldn't find a route object ..."
);
}
I noticed the error occurs when declaring the useRoute hook
const route = useRoute();
Here's the code of my NavBar component where I want to use useRoute:
import React, { useState } from 'react';
import { useRoute, useNavigation } from '#react-navigation/native';
import { Image, View, TouchableOpacity, Text } from 'react-native';
import menu from '../assets/menu.png';
import { nav } from '../styles';
const NavBar: React.FC = () => {
const [show, setShow] = useState(false);
const navigation = useNavigation();
const route = useRoute();
function navigate(path: any) {
if (path) {
setShow(false);
navigation.navigate(path);
}
setShow(false);
}
return (
<TouchableOpacity
activeOpacity={0.8}
style={nav.drawer}
onPress={() => setShow(!show)}>
<Image source={menu} />
{show ? (
<View style={nav.options}>
<TouchableOpacity style={nav.option}>
<Text
style={[
nav.textOption,
route.name == 'Home' ? nav.textActive : null,
]}
onPress={() => navigate('Home')}>
Home
</Text>
</TouchableOpacity>
<TouchableOpacity style={nav.option}>
<Text
style={[
nav.textOption,
route.name == 'Catalog' ? nav.textActive : null,
]}
onPress={() => navigate('Catalogo')}>
Catalogo
</Text>
</TouchableOpacity>
<TouchableOpacity style={nav.option}>
<Text
style={[
nav.textOption,
route.name == 'Adm' ? nav.textActive : null,
]}
onPress={() => navigate('Home')}>
Adm
</Text>
</TouchableOpacity>
</View>
) : null}
</TouchableOpacity>
);
};
export default NavBar;
Here's my package.json
"#react-navigation/native": "^6.0.2",
"#react-navigation/native-stack": "^6.1.0",
"axios": "^0.21.4",
"expo": "~42.0.1",
"expo-status-bar": "~1.0.4",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-42.0.0.tar.gz",
"react-native-gesture-handler": "^1.10.3",
"react-native-safe-area-context": "3.2.0",
"react-native-screens": "~3.4.0",
"react-native-web": "~0.13.12"
Related
I want to incorporate the MaterialUI date-time-pickers into my MERN project and to test the waters I just want to render the JS example (not typescript) from the "Getting-Started" section of the MaterialUI website: https://mui.com/x/react-date-pickers/getting-started/. I have an App.js file where my routing, screens and providers are located. I want to render the example on my CountdownScreen.js file. I assumed that I would need to wrap my screens in the LocalizationProvider component in my App.js file as opposed to wrapping the pickers like how the example shows but I tried both ways and it didn't seem to help. I'm getting the following error:
Invariant Violation: View config getter callback for component style must be a function (received undefined). Make sure to start component names with a capital letter.
MaterialUI has changed their syntax
(https://mui.com/material-ui/guides/pickers-migration/)
so its hard to find new tutorials that don't use the deprecated code. I don't get what I'm doing wrong. I may have downloaded too many conflicting dependencies but I'm not sure which one is the culprit. Thank you in advance. Also, if I didn't want to use MaterialUI are there any other decent date/time pickers out there?
Below is my CountdownScreen.js code:
import React from "react";
import { View, StyleSheet } from "react-native";
import dayjs from "dayjs";
import Stack from "#mui/material/Stack";
import TextField from "#mui/material/TextField";
import { LocalizationProvider } from "#mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "#mui/x-date-pickers/AdapterDayjs";
import { TimePicker } from "#mui/x-date-pickers/TimePicker";
import { DateTimePicker } from "#mui/x-date-pickers/DateTimePicker";
import { DesktopDatePicker } from "#mui/x-date-pickers/DesktopDatePicker";
import { MobileDatePicker } from "#mui/x-date-pickers/MobileDatePicker";
const CountdownScreen = () => {
const [value, setValue] = React.useState(dayjs("2014-08-18T21:11:54"));
const handleChange = (newValue) => {
setValue(newValue);
};
return (
<View>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<Stack spacing={3}>
<DesktopDatePicker
label="Date desktop"
inputFormat="MM/DD/YYYY"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
/>
<MobileDatePicker
label="Date mobile"
inputFormat="MM/DD/YYYY"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
/>
<TimePicker
label="Time"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
/>
<DateTimePicker
label="Date and Time picker"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
/>
</Stack>
</LocalizationProvider>
</View>
);
};
CountdownScreen.navigationOptions = { title: "Countdown" };
const styles = StyleSheet.create({
countdownScreenStyle: {
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: "rgba(232, 180, 68, 1.0)",
height: "100%",
width: "100%",
flex: 1,
},
});
export default CountdownScreen;
Below is my App.js:
import * as React from "react";
import { NavigationContainer, useIsFocused } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
//https://mui.com/material-ui/guides/pickers-migration/
import HomeScreen from "./src/screens/HomeScreen";
import CountdownScreen from "./src/screens/CountdownScreen";
import WeatherScreen from "./src/screens/WeatherScreen";
import MusicScreen from "./src/screens/MusicScreen";
import SettingsScreen from "./src/screens/SettingsScreen";
import { Ionicons } from "#expo/vector-icons";
const Tab = createBottomTabNavigator();
export default function App() {
return (
<SafeAreaProvider>
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === "Home") {
iconName = focused ? "home" : "home-outline";
} else if (route.name === "Countdown") {
iconName = focused ? "timer" : "timer-outline";
} else if (route.name === "Weather") {
iconName = focused ? "partly-sunny" : "partly-sunny-outline";
} else if (route.name === "Music") {
iconName = focused
? "musical-notes"
: "musical-notes-outline";
} else if (route.name === "Settings") {
iconName = focused ? "settings" : "settings-outline";
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: "tomato",
tabBarInactiveTintColor: "gray",
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Countdown" component={CountdownScreen} />
<Tab.Screen name="Weather" component={WeatherScreen} />
<Tab.Screen name="Music" component={MusicScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
</SafeAreaProvider>
);
}
Below is my package.json file:
{
"name": "countdown-hound",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"#date-io/date-fns": "^1.3.13",
"#emotion/react": "^11.10.4",
"#emotion/styled": "^11.10.4",
"#material-ui/core": "^5.0.0-beta.5",
"#material-ui/lab": "^5.0.0-alpha.44",
"#mui/icons-material": "^5.10.6",
"#mui/lab": "^5.0.0-alpha.100",
"#mui/material": "^5.10.6",
"#mui/x-date-pickers": "^5.0.3",
"#react-native-community/datetimepicker": "^6.3.2",
"#react-navigation/bottom-tabs": "^6.3.3",
"#react-navigation/drawer": "^6.4.4",
"#react-navigation/native": "^6.0.12",
"#react-navigation/native-stack": "^6.8.0",
"#react-navigation/stack": "^6.2.3",
"#rneui/base": "^4.0.0-rc.6",
"#rneui/themed": "^4.0.0-rc.6",
"axios": "^0.27.2",
"date-fns": "^2.29.3",
"dayjs": "^1.11.5",
"expo": "~46.0.9",
"expo-location": "~14.3.0",
"expo-secure-store": "^11.3.0",
"expo-status-bar": "~1.4.0",
"material-ui": "^0.20.2",
"moment": "^2.29.4",
"react": "18.0.0",
"react-css-transition-replace": "^4.0.5",
"react-dom": "^18.2.0",
"react-native": "0.69.5",
"react-native-gesture-handler": "~2.5.0",
"react-native-localize": "^2.2.3",
"react-native-maps": "^1.3.1",
"react-native-reanimated": "^2.9.1",
"react-native-safe-area-context": "^4.3.1",
"react-native-screens": "~3.15.0",
"react-native-segmented-control": "^1.1.0",
"react-native-windows": "^0.69.6",
"react-navigation": "^4.4.4",
"react-time-picker-input": "^2.0.10"
},
"devDependencies": {
"#babel/core": "^7.12.9"
},
"private": true
}
Because of Google Play, I had to update an old project of mine to the latest expo versions (version 43.0.0 to be exact). The idea is for the app to scan a QRCode and process the data, simply. However, expo-barcode-scanner only works once and after that I need to close and open the app again to work. Has anyone encountered this problem and (or) knows how to solve it?
Below is my code:
{escaneando ? (
<BarCodeScanner
barCodeTypes={[
BarCodeScanner.Constants.BarCodeType.ean13,
BarCodeScanner.Constants.BarCodeType.ean8,
BarCodeScanner.Constants.BarCodeType.upc_a,
BarCodeScanner.Constants.BarCodeType.upc_e,
]}
onBarCodeScanned={this.handleBarCode.bind(this)}
style={[StyleSheet.absoluteFillObject, styles.barscan]}
/>
) : null}
And library specifications:
"#react-native-community/masked-view": "^0.1.11",
"#react-native-community/netinfo": "^6.0.5",
"#react-navigation/native": "^6.0.6",
"#react-navigation/stack": "^6.0.11",
"expo": "~43.0.0",
"expo-av": "^10.1.3",
"expo-barcode-scanner": "^11.1.2",
"expo-status-bar": "~1.1.0",
"lodash": "^4.17.21",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "^0.64.2",
"react-native-dropdownalert": "^4.3.0",
"react-native-elements": "^3.4.2",
"react-native-gesture-handler": "^1.10.3",
"react-native-in-app-notification": "^3.2.0",
"react-native-offline": "^6.0.0",
"react-native-paper": "^4.10.0",
"react-native-reanimated": "^2.2.3",
"react-native-safe-area-context": "^3.3.2",
"react-native-screens": "^3.9.0",
"react-native-web": "0.17.1",
"react-navigation": "^4.4.4",
"react-redux": "^7.2.6",
"redux": "^4.1.2",
"redux-thunk": "^2.4.0",
"reselect": "^4.1.2"
with expo-camera it works perfectly.
1)- install expo-camera : expo install expo-camera
this is the code for it :
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { Camera } from 'expo-camera';
const QrcodeReader = ({navigation}) => {
const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
useEffect(() => {
(async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return(
<View style={styles.container}>
<Camera
onBarCodeScanned={(...args) => {
const data = args[0].data;
result = JSON.stringify(result);
console.log(result);
navigation.navigate('your_next_screen',{result});
);
}}
barCodeScannerSettings={{
barCodeTypes: ['qr'],
}}
style={{ flex: 1 }}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
camera: {
flex: 1,
},
buttonContainer: {
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
margin: 20,
},
button: {
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
},
text: {
fontSize: 18,
color: 'white',
},
});
export default QrcodeReader;
I faced the same problem and because it was a feature i couldnt work without, i persisted and found a solution that worked for me.
Because Only one active BarCodeScanner preview is supported, I went to react navigation and found a way to re-render the barcode scanner whenever the screen is in focus.
import { useIsFocused } from '#react-navigation/native';
useIsFocused returns true when a screen with the barcode scanner is the one in focus.
{isFocused ? (
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>) : null}
Read more on https://reactnavigation.org/docs/use-is-focused.
Full Example:
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
import { useIsFocused } from '#react-navigation/native';
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
console.log(hasPermission, scanned);
const isFocused = useIsFocused();
useEffect(() => {
(async () => {
setScanned(false);
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
alert(`Bar code with type ${type} and data ${data} has been scanned!`);
};
if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View style={styles.container}>
{isFocused ? (
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>
) : null}
{scanned && (
<Button title={'Tap to Scan Again'} onPress={() => setScanned(false)} />
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
},
});
Welcome #Backup Gov18,
This is a documented issue.
Note: Only one active BarCodeScanner preview is supported currently. When using navigation, the best practice is to unmount any previously rendered BarCodeScanner component so the following screens can use without issues.
There is a workaround.
Instead of conditionally rendering the <BarcodeScanner /> component, you could render it inside another dedicated screen component.
This way, after this new screen reads the barcode, you could navigate back to your first screen. Navigating back may unmount this new screen. You can force unmount if you need to.
As you are using react-navigation, you had better use .pop() instead of goBack().
Alternative
You can also use expo-camera instead of expo-barcode-scanner. expo-camera does not have this issue. It also offers more options like flashlight/torch and switching cameras.
found this workaround:
edit the file BarCodeScannerViewFinder.kt
located at:
[your project]\node_modules\expo-barcode-scanner\android\src\main\java\expo\modules\barcodescanner
add the following two lines at the declarations part (around line 44):
#volatile
private var barCodeScannerTaskLock = false
worked fine for me.
I want to use navigation in a class component, which is not a screen component and does not automatically access navigation via props, So I have to pass the navigation to it as props. But the parent component is a functional component And I used navigation hooks in it.
However, how can I use navigation in the child component?
ParentComponent.js
import React from 'react';
import {View , TouchableOpacity} from 'react-native';
import {useNavigation} from 'react-navigation-hooks';
import ChildComponent from './ChildComponent';
const ParentComponent =()=>{
const {navigate} = useNavigation();
return(
<View>
<TouchableOpacity onPress={() => navigate('AnotherScreen')} />
<ChildComponent />
</View>
)
}
export default ParentComponent;
ChildComponent.js
import React , {Component} from 'react';
import {View , TouchableOpacity} from 'react-native';
class ChildComponent extends Component {
render(){
return(
<View>
<TouchableOpacity onPress={() => ???}>
<Text>sample text</Text>
</TouchableOpacity>
</View>
)
}
}
export default ChildComponent;
I use the following dependencies:
"dependencies": {
"#react-native-community/masked-view": "^0.1.10",
"native-base": "2.13.8",
"react": "16.13.1",
"react-native": "0.63.0",
"react-native-gesture-handler": "^1.6.1",
"react-navigation": "^4.0.7",
"react-navigation-drawer": "^2.3.3",
"react-navigation-hooks": "^1.1.0",
"react-navigation-stack": "^1.8.1",
},
Your guidance is highly appreciated.
If you have access to navigation prop in parent component simply pass it to the child navigate using the prop.
const ParentComponent =()=>{
const {navigate} = useNavigation();
return(
<View>
<TouchableOpacity onPress={() => navigate('AnotherScreen')} />
<ChildComponent navigate={navigate}/>
</View>
)
}
class ChildComponent extends Component {
render(){
return(
<View>
<TouchableOpacity onPress={() => this.props.navigate('screenname')}>
<Text>sample text</Text>
</TouchableOpacity>
</View>
)
}
}
You must be getting navigation inside props of the parent component.
In parent component:
const ParentComponent =(props)=>{
const {navigate} = useNavigation();
return(
<View>
<TouchableOpacity onPress={() => navigate('AnotherScreen')} />
<ChildComponent navigation={props.navigation} />
</View>
)
}
In the child component, you can access navigation:
class ChildComponent extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<TouchableOpacity onPress={() => this.props.navigation.navigate('SomeOtherScreen')}>
<Text>sample text</Text>
</TouchableOpacity>
</View>
)
}
}
I am doing doing navigation with new react native navigation all I want is when button is pressed it navigate to next screen, I have followed new documentation but the problem is I am doing with classes and in the documentation all the work is done with functions in App.js, I tried to modify my code accordingly but couldn't do with classes as onPress button it does not navigate instead gives me error.
This is my app.js:
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer,useNavigation } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import Nav from './screens/Nav';
import Home from './screens/Home';
import Login from './screens/Login';
const Stack = createStackNavigator();
export default class App extends React.Component {
render(){
return (
<NavigationContainer>
<Stack.Navigator headerMode='none' initialRouteName="Nav">
<Stack.Screen name="Splash" component={Nav} />
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Login" component={Login} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
That is my Home.js from where when it clicks Login button it moves to next screen which is Login.js:
import React, { Component } from 'react';
import {StyleSheet, Text, View, TouchableHighlight,Image,BackHandler} from 'react-native';
import Login from './Login';
export default class Home extends Component {
render() {
const { navigation } = this.props;
return (
<View style={styles.container}>
<TouchableHighlight style={styles.buttonContainer} onPress={() => navigation.navigate('Login')}>
<Text style={styles.loginText}>Login</Text>
</TouchableHighlight>
</View>
);
}
}
That is my Login.js Screen:
import React, { Component } from 'react';
import {StyleSheet, Text, View,TextInput,TouchableHighlight, Image} from 'react-native';
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
email : '',
password: '',
}
}
render() {
return (
<View style={styles.container}>
<Image source={require('../assets/logo.png')}
style={{ width: 250, height: 250, marginHorizontal: 20 }}
resizeMode="contain"/>
<Text style = {styles.text}>UniQmove Training </Text>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/email.png'}}/>
<TextInput style={styles.inputs}
placeholder="Email"
keyboardType="email-address"
underlineColorAndroid='transparent'
onChangeText={(email) => this.setState({email})}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/password.png'}}/>
<TextInput style={styles.inputs}
placeholder="Password"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(password) => this.setState({password})}/>
</View>
<TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress={() => {this.loginRoles();this.handleLogin();}}>
<Text style={styles.loginText}>Login</Text>
</TouchableHighlight>
</View>
);
}
}
The problem is when I import Login.js in Home it is not using it in navigation.navigate('Login')
My package.jason:
{
"name": "UniQmoves",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"#react-native-community/masked-view": "^0.1.7",
"#react-navigation/native": "^5.0.9",
"#react-navigation/stack": "^5.1.1",
"react": "16.9.0",
"react-native": "0.61.5",
"react-native-gesture-handler": "^1.6.0",
"react-native-reanimated": "^1.7.0",
"react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.3.0"
},
"devDependencies": {
"#babel/core": "7.8.7",
"#babel/runtime": "7.8.7",
"#react-native-community/eslint-config": "0.0.5",
"babel-jest": "24.9.0",
"eslint": "6.8.0",
"jest": "24.9.0",
"metro-react-native-babel-preset": "0.56.4",
"react-test-renderer": "16.9.0"
},
"jest": {
"preset": "react-native"
}
}
there is a little change in code and your code will work fine
in App Class initialRouteName and screen name should same change Splash to Nav
<Stack.Navigator headerMode='none' initialRouteName="Nav">
<Stack.Screen name="Splash" component={Nav} />
in Home class update after use this line
import React, { Component } from 'react';
import {StyleSheet, Text, View, TouchableHighlight,Image,BackHandler} from 'react-native';
import Login from './Login';
export default class Home extends Component {
render() {
return (
<View style={styles.container}>
//<TouchableHighlight style={styles.buttonContainer} onPress={() => navigation.navigate('Login')}>
use this
<TouchableHighlight style={styles.buttonContainer} onPress={() => this.props.navigation.navigate('Login')}>
<Text style={styles.loginText}>Login</Text>
</TouchableHighlight>
</View>
);
}
}
I don't know why this is popping up, I just copy my codes from my other Project and compare it, perfectly the same but I still got this bug.
Is there anyone that encounter bug like this? I don't know maybe there is any wrong configuration about my Environment?
My Environment:
"expo": "^35.0.0",
"expo-constants": "~7.0.0",
"expo-location": "^7.0.0",
"react": "16.8.3",
"react-dom": "16.8.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz",
"react-native-gesture-handler": "1.3.0",
"react-native-linear-gradient": "^2.5.6",
"react-native-maps": "^0.26.1",
"react-native-reanimated": "^1.4.0",
"react-native-screens": "^1.0.0-alpha.23",
"react-native-web": "^0.11.7",
"react-navigation": "^4.0.10",
"react-navigation-animated-switch": "^0.3.2",
"react-navigation-stack": "^1.10.3",
"react-navigation-tabs": "^2.6.2",
"react-redux": "^7.1.3",
"redux": "^4.0.4"
My Code for Parent Component:
import React from 'react';
import {FlatList, StyleSheet, Text, View, StatusBar} from 'react-native';
import {useSelector} from 'react-redux';
import {Constants} from 'react-native-unimodules';
import EventItem from '../../components/EventItem';
const HeaderComponent = () => {
return (
<Text style={styles.header}>Events</Text>
);
}
const EventsOverviewScreen = props => {
const events = useSelector(state => state.events.events);
return (
<View style={styles.container}>
<StatusBar backgroundColor='transparent' translucent barStyle='light-content'/>
<FlatList
data={events}
keyExtractor={item => item.id}
ListHeaderComponent={HeaderComponent}
ListHeaderComponentStyle={styles.headerContainer}
showsVerticalScrollIndicator={false}
renderItem={itemData => (
<EventItem
image={itemData.item.imageUrl}
title={itemData.item.title}
description={itemData.item.description}
onViewDetail={() => {
props.navigation.navigate('EventDetail', {
eventId: itemData.item.id
});
}}
/>
)}
/>
</View>
);
};
My Child Component:
const EventItem = props => {
let TouchableCmp = TouchableOpacity;
if (Platform.OS === 'android' && Platform.Version >= 21) {
TouchableCmp = TouchableNativeFeedback;
}
return (
<View style={styles.eventContainer}>
<View style={styles.event}>
<View style={styles.touchable}>
<TouchableCmp onPress={props.onViewDetail} useForeground>
<ImageBackground source={{uri: props.image}} style={styles.image}>
<View style={styles.textContainer}>
<Text style={styles.title}>{props.title}</Text>
<Text style={styles.description}>{props.description}</Text>
</View>
</ImageBackground>
</TouchableCmp>
</View>
</View>
</View>
);
};