React Native undefined is not an object (evaluating 'HomeScreen.props.navigation') - reactjs

I'm trying to navigate to another screen on the react navigation header when pressing the left element icon.
Error: React native Undefined is not an object(evaluating'HomeScreen.props.navigation')
Here's a picture of the error
Using:
expo, react navigation v3 and User Avatar to display user's profile picture (this will redirect to the user's profile)
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, TouchableOpacity, Image, SafeAreaView, FlatList} from 'react-native';
import CardStack, { Card } from 'react-native-card-stack-swiper';
import UserAvatar from 'react-native-user-avatar';
import GradientButton from 'react-native-gradient-buttons';
import { createStackNavigator, createAppContainer, createDrawerNavigator } from 'react-navigation';
import Drawer from 'react-native-drawer';
class HomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerLeft: (
<TouchableOpacity onPress={() => this.props.navigation.navigate('Profile')}>
<UserAvatar style={{marginLeft: 15}} size="28" name="User Test" color="#000"/>
</TouchableOpacity>
),
headerTitle: (
<View style={{flex:1, flexDirection:'row', justifyContent:'center', marginRight: 5}}>
<Image resizeMode="cover" style={{width:98, height:25}} source={require('./src/images/logo.png')}/>
</View>
),
headerRight:(
<TouchableOpacity>
<Image style={{width:28, height:28, marginRight: 15}} source={require('./src/images/share.png')}/>
</TouchableOpacity>
),
};
};
render() {
return (
<View style={styles.container}>
<View style={styles.content}>
<View style={styles.cardContainer}>
<Card style={styles.card}><Text style={styles.label} onPress={() => this.props.navigation.navigate('Feed')}>A</Text></Card>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Feed')}>
<Image style={{width:220, height:55}} source={require('./src/images/button.png')} onPress={() => this.props.navigation.navigate('Feed')}/>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
export default HomeScreen;
const drawerStyles = {
drawer: {
flex: 1.0,
backgroundColor: '#2E2E2E'
},
main: {
flex: 1.0,
backgroundColor: 'white'
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: '#EFF2F5'
},
buttonContainer:{
flex: 1,
flexDirection:'row',
justifyContent:'center',
position: 'absolute',
alignSelf: 'center',
marginTop: 30,
},
cardContainer:{
flexDirection:'row',
justifyContent:'center',
marginTop: 55,
},
card:{
width: 312,
height: 476,
backgroundColor: '#fff',
borderRadius: 25,
shadowColor: 'rgba(0,0,0,0.9)',
shadowOffset: {
width: 50,
height: 5
},
shadowOpacity:0.5,
},
label: {
lineHeight: 400,
textAlign: 'center',
fontSize: 55,
fontFamily: 'System',
color: '#000',
backgroundColor: 'transparent',
},
});
Here's the app.js file
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, TouchableOpacity, Image, SaveAreaView, ScrollView} from 'react-native';
import { createStackNavigator, createAppContainer, createDrawerNavigator } from "react-navigation";
import HomeScreen from './layout_home.js';
import FeedScreen from './layout_feed.js';
import ProfileScreen from './layout_profile.js';
const AppStackNavigator = createStackNavigator({
Home: {
screen: HomeScreen
},
Feed: {
screen: FeedScreen
},
Profile: {
screen: ProfileScreen
},
})
export default createAppContainer(AppStackNavigator);
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: '#808080'
},
});

You have already passed the navigation parameters.
You have to change it as the code below.
return {
headerLeft: (
<TouchableOpacity onPress={() => navigation.navigate('Profile')}>
<UserAvatar style={{marginLeft: 15}} size="28" name="User Test" color="#000"/>
</TouchableOpacity>
),

Related

I have a issue when i try to write react navigation

I have begun the React Navigation. I have some issue about my project and i wish everybody can support me.
In the app.js, i code:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
StatusBar,
} from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
class HomeScreen extends Component {
static navigationOptions = {
header: null
}
render() {
return (
<View style={styles.container}>
<StatusBar backgroundColor="#1e90ff"
barStyle="light-content" />
<Text style={styles.welcome}>Login To My App</Text>
<TextInput
style={styles.input}
placeholder="Username" />
<TextInput
style={styles.input}
placeholder="Password"
secureTextEntry
/>
<View style={styles.btnContainer}>
<TouchableOpacity style={styles.userBtn}
onPress{() => this.props.navigation.navigate('Details')}
>
<Text style={styles.btnTxt}>Login</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.userBtn}
onPress{() => this.props.navigation.navigate('Details')}>
<Text style={styles.btnTxt}>Signup</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
class DetailsScreen extends Component {
static navigationOptions = {
title: 'My App',
headerRight: <View/>
}
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
</View>
);
}
}
const RootStack = createStackNavigator({
Home: HomeScreen,
Detail: DetailsScreen
},
{
intialRouteName: 'Home',
defaultNavigationOptions: {
headerStyle: {
backgroundColor: "#1e90ff"
}
},
headerTintColor: "#fff",
headerTitleStyle: {
textAlign: "center",
flex: 1,
}
}
);
const AppContainer = createAppContainer(RootStack);
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<AppContainer />
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
backgroundColor: "lightskyblue",
},
welcome: {
fontSize: 30,
textAlign: "center",
margin: 10,
color: "lightgray",
},
input: {
width: "90%",
backgroundColor: "#fff",
padding: 15,
marginBottom: 10,
marginLeft: 20,
},
btnContainer: {
flexDirection: "row",
justifyContent: "space-between",
width: "90%",
marginLeft: 20,
},
userBtn: {
backgroundColor: "#FFD700",
padding: 15,
width: "45%"
},
btnTxt: {
fontSize: 18,
textAlign: "center",
}
})
Detail: I try to write the code based on the youtube https://www.youtube.com/watch?v=bUesHGYxSLg&list=PLQWFhX-gwJblNXe9Fj0WomT0aWKqoDQ-h&index=4&ab_channel=PradipDebnath and i cannot understand the mistake i met.
When i tried to run by npx react-native run-android in terminal, the warning appeared.
Result: Error failed to instal the app. Make sure you have the Android development environmet set up.
Error: Command fail: gradlew.bat app:installDebug -PreactNativeDevServerPort=8081.
Question: How can i fix the mistake? Because when i star a new file, it did not haave the mistake. Thank for your attention.

how to make initialParams updated

I want to update initialParams of react native navigation on clicking of the menu item
import React, { useState } from 'react';
import {createStackNavigator} from '#react-navigation/stack'
import { NavigationContainer } from '#react-navigation/native';
import userMain from './../../components/users/userMain';
import { View, Icon } from 'native-base';
export const UserStack = () => {
const Stack = new createStackNavigator()
const [toggleSearch, setToggleSearch] = useState(true)
const changeStyleToggle = () => {
setToggleSearch( !toggleSearch )
// console.log('toggle search here ==== ', toggleSearch)
}
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="User Homepage"
component={userMain}
initialParams={{ toggleSearch: toggleSearch}}
options = {{
title: 'My home',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
headerRight: () => (
<View style={{flexDirection:'row', justifyContent:'space-evenly', width:120}}>
<Icon name='home' onPress={() => changeStyleToggle()} />
<Icon name='home' />
<Icon name='home' />
</View>
),
}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
the component i am calling is userMain where i am calling initialParams value and on behalf of that i want to change style
import React from 'react'
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'
import { Input } from 'native-base';
const userMain = (props) => {
const {toggleSearch} = props.route.params;
console.log(toggleSearch)
const check = toggleSearch == true ? 'true!!' : 'false!!'
return (
<View style={styles.container}>
<Input
placeholder="search"
style={styles.searchInput}
/>
<Text>user homepage here</Text>
<Text>{check}</Text>
<TouchableOpacity style={styles.btn}>
<Text style={styles.btnText}> + </Text>
</TouchableOpacity>
</View>
)
}
const styles = StyleSheet.create({
container: {
alignItems: 'center', flex: 1, justifyContent: 'center',
},
btn: {
position: 'absolute', justifyContent: 'center', alignItems: 'center',
bottom:10, right:10, width:60, height: 60,
backgroundColor: '#fff', borderRadius: 50, borderColor: '#000',borderWidth:1,
},
btnText: {
fontSize: 50, color: 'black',
},
searchInput: {
position:'absolute', top: 0, borderWidth: 1, width: 300, opacity:0
}
})
export default userMain
i have checked on clicking the icon state which is toggleSearch is updating but it is not updating the initialParams hence it is not working on userMain component as well .

Passing username and family name from google login

I've managed to set up Google login using 'expo-google-app-auth'.
This is my Login.js, which handles the login page and the google login details and logic:
import React, { Component } from 'react'
import {Text,
View,
StyleSheet,
Image,
Alert} from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler';
import { Provider as PaperProvider,
Button,
Caption} from 'react-native-paper'
import { createStackNavigator } from '#react-navigation/stack'
import { NavigationContainer } from '#react-navigation/native';
import MyDrawer from '../navigation/Drawer'
import QR from './QR'
const Stack = createStackNavigator();
import * as Google from 'expo-google-app-auth';
const IOS_CLIENT_ID =
"your-ios-client-id";
const ANDROID_CLIENT_ID =
"my-android-id";
class Login extends Component {
signInWithGoogle = async () => {
try {
const result = await Google.logInAsync({
iosClientId: IOS_CLIENT_ID,
androidClientId: ANDROID_CLIENT_ID,
scopes: ["profile", "email"]
});
if (result.type === "success") {
console.log("LoginScreen.js.js 21 | ", result.user.givenName, result.user.familyName, result.user.email, result.user.photoUrl);
this.props.navigation.navigate("MyDrawer", {
username: result.user.givenName,
lastname: result.user.familyName,
email: result.user.email,
photoUrl: result.user.photoUrl
}); //after Google login redirect to MyDrawer
return result.accessToken;
} else {
return { cancelled: true };
}
} catch (e) {
console.log('LoginScreen.js.js 30 | Error with login', e);
return { error: true };
}
};
render(){
return (
<PaperProvider>
<View style={styles.container}>
<View style={styles.imageCon}>
<Image
source={require('../img/logo-krug.png')}></Image>
</View>
<View style={styles.textCon}>
<Text style={styles.text}> Dobrodošli u eSTUDENT mobilnu aplikaciju!</Text>
</View>
<View style={styles.buttonCon}>
<Button
icon='camera'
mode='outlined'
onPress={this.signInWithGoogle}
>
google
</Button>
</View>
</View>
</PaperProvider>
)
}
}
export default function LoginStack() {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName='Login'
screenOptions={{
headerShown: false
}}>
<Stack.Screen name='MyDrawer' component={MyDrawer} />
<Stack.Screen name='Login' component={Login} />
</Stack.Navigator>
</NavigationContainer>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ecf0f1'
},
imageCon: {
height: '35%',
width: '100%',
justifyContent: "center",
alignItems: "center"
},
textCon:{
height:'20%',
alignItems: 'center',
justifyContent: 'center'
},
text: {
textAlign: "center",
fontSize: 20,
fontWeight: 'bold'
},
buttonCon:{
height: '30%',
justifyContent:'center',
alignItems: 'center'
},
});
And I want to pass the username, family name, email and profile picture to these 2 files.
Drawer.js, which handles the side Drawer and navigation:
import React from 'react'
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import { Ionicons, MaterialIcons, Feather } from '#expo/vector-icons';
import { ScrollView,
TouchableOpacity,
Text,
View,
Image,
StatusBar,
StyleSheet,
} from 'react-native'
import QR from '../screens/QR';
import Odabir from '../screens/Odabir'
import { SafeAreaView } from 'react-navigation';
import { Divider } from 'react-native-paper'
const Drawer = createDrawerNavigator();
function CustomDrawerContent(props) {
return(
<SafeAreaView style={{flex:1}}>
<View style={{height: 150, alignItems: 'center', justifyContent: 'center', marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight}}>
<Image source={require('../img/account.png')}
style={{height: 120, width: 120, borderRadius: 60}}
/>
</View>
<View style={{height: 50, alignItems:'center'}}>
<Text style={styles.naslov}> This is where I want to pass the username and last name </Text>
</View>
<Divider />
<ScrollView style={{marginLeft: 5,}}>
<TouchableOpacity
style={{marginTop: 20, marginLeft: 20}}
onPress={() => props.navigation.navigate('QR')}
>
<View style={{padding:10}}>
<Ionicons name='ios-qr-scanner' size={20} styles={{}}>
<Text style={styles.naslov}> QR</Text>
</Ionicons>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{marginTop: 20, marginLeft: 20}}
onPress={() => props.navigation.navigate('Odabir')}
>
<View style={{padding:10}}>
<Ionicons name='ios-qr-scanner' size={20} styles={{}}>
<Text style={styles.naslov}> Odabir</Text>
</Ionicons>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{marginTop: 20, marginLeft: 20}}
onPress={() => props.navigation.navigate('Odabir')}
>
<View style={{padding:10}}>
<Ionicons name='ios-qr-scanner' size={20} styles={{}}>
<Text style={styles.naslov}> Odabir</Text>
</Ionicons>
</View>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
)
}
export default function MyDrawer() {
return (
<NavigationContainer independent={true}>
<Drawer.Navigator initialRouteName='QR' drawerContent={props => CustomDrawerContent(props)}>
<Drawer.Screen
name="QR"
component={QR}
/>
<Drawer.Screen
name="Odabir"
component={Odabir}
/>
</Drawer.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
naslov: {
fontSize: 20,
},
})
and finally QR.js, which holds some basic information and I'd like to personalize it a bit since it's the 'Home' page users land on
import React, { Component } from 'react'
import {Text,
SafeAreaView,
View,
StyleSheet,
Image
} from 'react-native'
import Header from '../navigation/Header'
export default function QR({navigation}) {
return (
<SafeAreaView style={styles.container}>
<Header title='Moj QR' isHome={true} navigation={navigation}/>
<View style={styles.qrCon}>
<Image
style={styles.qr}
source={require('../img/QR_code_for_mobile_English_Wikipedia.svg.png')}
/>
</View>
<View style={styles.textCon}>
<Text style={styles.text}>This is where I want to pass the username and last name</Text>
<Text style={styles.text}>Ovo je tvoj QR kod</Text>
</View>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ecf0f1',
alignItems: 'center',
},
qrCon:{
width: '60%',
height: '60%',
alignItems: 'center',
justifyContent: 'center',
},
qr: {
width: '120%',
height: '120%',
resizeMode: 'contain'
},
textCon: {
height: '7%'
},
text:{
fontSize: 35,
fontWeight: '600'
},
buttonCon:{
height: '15%',
justifyContent:'center',
alignItems: 'center'
}
})
The example I'm following used {this.props.navigation.getParam("username")} but that isn't working for me. How would I exactly pass the data?
I had this issue recently. React navigation 5 doesn't support props.navigation.getParam instead you can use this.props.route.params to access the data you passed in your navigation prop. So to access the username you can use this.props.route.params.username;
The way to solve this, at least passing data to the Drawer.js component is to rewrite the code like this:
if (result.type === "success") {
console.log("LoginScreen.js.js 21 | ", result.user.givenName, result.user.familyName, result.user.email, result.user.photoUrl);
this.props.navigation.navigate("MyDrawer",
username = result.user.givenName,
lastname = result.user.familyName,
email = result.user.email,
photoUrl = result.user.photoUrl);
return result.accessToken;
;
Then just putting that as a variable in Drawer.js
<View style={{height: 30, alignItems:'center'}}>
<Text style={styles.naslov}>{username} {lastname}</Text>
</View>

How to remove header and footer from certain screens

I need to remove the footer and header from login screen. I used header : null to remove the header but when the header gets removed a footer appears from nowhere. When the header is visible the footer is invisible.
I need to remove both not just one.
I am new to react-native. I would appreciate any help.
I tried tabBarVisible : false and it did not work
import React, {Fragment} from 'react';
import { createStackNavigator } from "react-navigation";
import HomeScreen from '../Screens/HomeScreen';
import PS4Screen from '../Screens/PS4Screen';
import XboxScreen from '../Screens/XboxScreen';
import LoginScreen from '../Screens/LoginScreen';
export default createStackNavigator(
{
HomeScreen : {screen : HomeScreen},
PS4Screen : {screen : PS4Screen},
XboxScreen : {screen : XboxScreen},
LoginScreen: {
screen : LoginScreen,
navigationOptions: {
header: null,
tabBarVisible: false,
}
}
},
{
initialRouteName: "LoginScreen",
}
);
This is the Login Screen Code. There is not functionality just the UI.
import React, { Component } from 'react'
import { Text, StyleSheet, View, ImageBackground, Image, TextInput, TouchableOpacity } from 'react-native'
const styles = StyleSheet.create({
textcolour: {
color: 'white',
},
textinputbox: {
borderWidth:2,
width: 200,
borderColor: 'white',
borderRadius: 10,
backgroundColor: 'transparent'
},
loginandsignup:{
margin:10,
borderColor: 'white',
fontSize: 15,
backgroundColor: 'transparent',
fontWeight: 'bold',
}
})
export default class LoginScreen extends Component {
render() {
const { navigation } = this.props;
return (
<ImageBackground resizeMode='repeat' source={require('../Pictures/loginscreenbackground.jpeg')} style={{width:'100%', height:'100%', justifyContent:'center', }}>
<View style={{alignItems:'center'}}>
<Text style={ [ styles.textcolour, { fontSize: 22, fontWeight:'bold', margin:20} ] }> Welcome to Healthy Foods </Text>
<TextInput style={ [styles.textcolour, styles.textinputbox, { margin:10 } ] }> Username </TextInput>
<TextInput style={ [styles.textcolour, styles.textinputbox, { margin: 10 } ] }> Password </TextInput>
<TouchableOpacity onPress = { () => this.props.navigation.navigate('HomeScreen')} style={[{borderRadius: 10, borderColor: 'white', borderWidth: 2, margin: 10, marginTop: 30, width: 100, alignItems: 'center'}]} >
<Text style={ [ styles.textcolour, styles.loginandsignup ] }> Login </Text>
</TouchableOpacity>
<TouchableOpacity style={[{borderRadius: 10, borderColor: 'white', borderWidth: 2, margin: 5, width: 100, alignItems: 'center'}]}>
<Text style={ [ styles.textcolour, styles.loginandsignup ] }> Sign Up </Text>
</TouchableOpacity>
</View>
</ImageBackground>
)
}
}

Enzyme Shallow Rendering not working correctly

In one of my components, I check the value of my props before deciding what component to return.
But the issue I am facing in testing is that the snapshot is not getting created properly for these components.
When I am testing a component on its own, the snapshot is created properly but not when my component checks prop value before returning a JSX.
This is my component:
import React, {Component} from 'react'
import {Button, Text, View, FlatList, StyleSheet, ActivityIndicator} from 'react-native'
import CategoryCell from '../Components/CategoryCell'
import { connect } from 'react-redux'
import { fetchQuotes } from '../actions/Quotes'
class QuotesCategories extends Component {
static navigationOptions = {
title: 'Categories',
}
render() {
return this.props.error ? (
<View style={styles.Container}>
<Text style={{color: 'red'}}>FAILED TO LOAD DATA</Text>
<Button
title='Reload'
onPress={this.props.fetchQuotes}
/>
</View>
) : this.props.loading ? (
<View style={styles.Container}>
<ActivityIndicator size="large"/>
</View>
) : (
<View style={styles.Container}>
<FlatList
style= {{flex:1, width: '100%'}}
data= {this.props.data}
renderItem = {({item,index}) => {
return (
<CategoryCell Category={item} navigation={this.props.navigation} id={index}/>
)
}}
keyExtractor = {(item, index) => item.category}
/>
<Text>Additions</Text>
</View>
)
}
}
const styles = StyleSheet.create({
Container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
})
export const mapStateToProps = (state) => {
return {
loading: state.loading,
error: state.error,
data: state.data
}
}
export const mapDispatchToProps = (dispatch) => {
return {
fetchQuotes: () => {
dispatch(fetchQuotes())
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(QuotesCategories)
I am trying to test the three cases
When there is some error
When the data is loading
When the data has loaded
I am trying to test the three cases
error and loading is a boolean
data is an array of JSON objects
This is the test for the error case:
import React from 'react'
import {shallow} from 'enzyme'
import QuoteCategories from '../../Components/QuoteCategories'
import quotes from '../fixtures/quotes-fixture'
describe('Testing QuoteCategories component', () => {
it('should load error button when error loading', ( ) => {
const wrapper = shallow(
<QuoteCategories
loading = {false}
error = {true}
data = {undefined}
/>
)
expect(wrapper).toMatchSnapshot()
}
)
}
)
But in the QuoteCategories.test.js.snap file this is the snapshot I see:
exports[`Testing QuoteCategories component should load error button when error loading 1`] = `
<ContextConsumer>
<Component />
</ContextConsumer>
`;
Why am I seeing these tags <ContextConsumer>,<Component /> ?
In my other component test which directly returns a component, the snapshot is displaying properly:
My Component:
import React from 'react'
import { View, Text, TouchableHighlight, StyleSheet } from 'react-native'
const FavouriteQuoteCell = (props) => {
return (
<TouchableHighlight
onPress={() => props.navigation.navigate('Quotes',{id: props.item.parentId, category: props.item.category})}
style={styles.TableCell}
>
<View>
<Text style={styles.Quote}>{props.item.text}</Text>
<Text style={styles.Author}>-- {props.item.person}</Text>
<View style={styles.CategoryPill}>
<Text style={styles.Category}>
{props.item.category}
</Text>
</View>
</View>
</TouchableHighlight>
)
}
export default FavouriteQuoteCell
const styles = StyleSheet.create({
TableCell: {
backgroundColor: '#ff6347',
margin:5,
padding: 5,
justifyContent: 'space-around',
flexDirection: 'column',
flex: 1 ,
padding: 10,
margin: 5,
borderRadius: 15,
},
"Quote": {
fontWeight: 'bold',
color: 'white'
},
"Author": {
fontWeight:'200',
color:'white',
justifyContent: 'flex-end',
alignItems: 'flex-end',
height: 20
},
Category: {
color: '#ff6347',
fontWeight: 'bold',
fontSize: 12,
textTransform: 'capitalize',
margin: 'auto'
},
CategoryPill: {
marginTop: 10,
padding: 2,
height: 20,
borderRadius: 10,
backgroundColor: 'white',
width: 100,
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
})
The test:
import React from 'react'
import {shallow} from 'enzyme'
import FavouriteQuoteCell from '../../Components/FavouriteQuoteCell'
import {favouriteItem} from '../fixtures/favourites-fixture'
describe('testing FavouriteQuoteCell', () => {
let wrapper,navigation
beforeEach(() => {
navigation = {
navigate: jest.fn()
}
wrapper = shallow(<FavouriteQuoteCell navigation={navigation} item={favouriteItem}/>)
})
it('should render FavouriteQuoteCell correctly', () => {
expect(wrapper).toMatchSnapshot()
})
})
The snapshot:
exports[`testing FavouriteQuoteCell should render FavouriteQuoteCell correctly 1`] = `
<TouchableHighlight
activeOpacity={0.85}
delayPressOut={100}
onPress={[Function]}
style={
Object {
"backgroundColor": "#ff6347",
"borderRadius": 15,
"flex": 1,
"flexDirection": "column",
"justifyContent": "space-around",
"margin": 5,
"padding": 10,
}
}
underlayColor="black"
>
<View>
<Text
style={
Object {
"color": "white",
"fontWeight": "bold",
}
}
>
Believe you can and you"re halfway there
</Text>
<Text
style={
Object {
"alignItems": "flex-end",
"color": "white",
"fontWeight": "200",
"height": 20,
"justifyContent": "flex-end",
}
}
>
--
Theodore Roosevelt
</Text>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "white",
"borderRadius": 10,
"flex": 1,
"height": 20,
"justifyContent": "center",
"marginTop": 10,
"padding": 2,
"width": 100,
}
}
>
<Text
style={
Object {
"color": "#ff6347",
"fontSize": 12,
"fontWeight": "bold",
"margin": "auto",
"textTransform": "capitalize",
}
}
>
inspirational
</Text>
</View>
</View>
</TouchableHighlight>
`;
Your QuotesCategories component is connected to redux with:
export default connect(mapStateToProps,mapDispatchToProps)(QuotesCategories)
that is why when you are shallow rendering you see the redux wrapper component in the snapshot and not your QuotesCategories.
The usual why to fix this to also export your QuotesCategories and import it with its name in your tests:
So your component file should have two exports:
export class QuotesCategories extends Component {
...
}
export default connect(mapStateToProps,mapDispatchToProps)(QuotesCategories)
And in your test you should import QuotesCategories with:
import { QuoteCategories } from '../../Components/QuoteCategories'

Resources