Redux - Undefined is not an object (evaluating 'store.getState') - react-native

I'm learning reactNative and I cannot resolve an error. In the tutorial I'm following, we want to allow user to be able to add (or remove) movie to favourites and for that we are using Redux. After implementing the code when launch (through Expo Go on android), I've got the following error: undefined is not an object (evaluating 'store.getState'). Thanks
Reducers:
// Store/Reducers/favoriteReducer.js
const initialState = { favoritesFilm: [] }
function toggleFavorite(state = initialState, action) {
let nextState
switch (action.type) {
case 'TOGGLE_FAVORITE':
const favoriteFilmIndex = state.favoritesFilm.findIndex(item => item.id === action.value.id)
if (favoriteFilmIndex !== -1){
nextState = {
...state,
favoritesFilm: state.favoritesFilm.filter( (item, index) => index !== favoriteFilmIndex )
}
}
else{
nextState = {
...state,
favoritesFilm: [...state.favoritesFilm, action.value]
}
}
return nextState || state
default:
return state
}
}
export default toggleFavorite
Store configure:
// Store/configureStore.js
import { createStore } from 'redux';
import toggleFavorite from './Reducers/favoriteReducer'
export default createStore(toggleFavorite)
App.js
import React from 'react';
import Navigation from './Navigation/Navigation';
import { Provider } from 'react-redux';
import { Store } from './Store/configureStore';
export default class App extends React.Component {
render(){
return (
<Provider store={Store}>
<Navigation/>
</Provider>
)
}
}
Film detail
import React from 'react'
import { StyleSheet, View, Text, ActivityIndicator, ScrollView, Image } from 'react-native'
import { getFilmDetailFromApi, getImageFromApi } from '../API/TMDBApi'
import moment from 'moment'
import numeral from 'numeral'
import { connect } from 'react-redux';
class FilmDetail extends React.Component {
constructor(props) {
super(props)
this.state = {
film: undefined,
isLoading: true
}
}
componentDidMount() {
getFilmDetailFromApi(this.props.navigation.state.params.idFilm).then(data => {
this.setState({
film: data,
isLoading: false
})
})
}
_displayLoading() {
if (this.state.isLoading) {
return (
<View style={styles.loading_container}>
<ActivityIndicator size='large' />
</View>
)
}
}
_displayFilm() {
const { film } = this.state
if (film != undefined) {
return (
<ScrollView style={styles.scrollview_container}>
<Image
style={styles.image}
source={{uri: getImageFromApi(film.backdrop_path)}}
/>
<Text style={styles.title_text}>{film.title}</Text>
<Text style={styles.description_text}>{film.overview}</Text>
<Text style={styles.default_text}>Sorti le {moment(new Date(film.release_date)).format('DD/MM/YYYY')}</Text>
<Text style={styles.default_text}>Note : {film.vote_average} / 10</Text>
<Text style={styles.default_text}>Nombre de votes : {film.vote_count}</Text>
<Text style={styles.default_text}>Budget : {numeral(film.budget).format('0,0[.]00 $')}</Text>
<Text style={styles.default_text}>Genre(s) : {film.genres.map(function(genre){
return genre.name;
}).join(" / ")}
</Text>
<Text style={styles.default_text}>Companie(s) : {film.production_companies.map(function(company){
return company.name;
}).join(" / ")}
</Text>
</ScrollView>
)
}
}
render() {
console.log(this.props)
return (
<View style={styles.main_container}>
{this._displayLoading()}
{this._displayFilm()}
</View>
)
}
}
const styles = StyleSheet.create({
main_container: {
flex: 1
},
loading_container: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
},
scrollview_container: {
flex: 1
},
image: {
height: 169,
margin: 5
},
title_text: {
fontWeight: 'bold',
fontSize: 35,
flex: 1,
flexWrap: 'wrap',
marginLeft: 5,
marginRight: 5,
marginTop: 10,
marginBottom: 10,
color: '#000000',
textAlign: 'center'
},
description_text: {
fontStyle: 'italic',
color: '#666666',
margin: 5,
marginBottom: 15
},
default_text: {
marginLeft: 5,
marginRight: 5,
marginTop: 5,
}
})
const mapStateToProps = (state) => {
return {
favoritesFilm: state.favoritesFilm
}
}
export default connect(mapStateToProps)(FilmDetail)
Package.json
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"#react-native-community/masked-view": "^0.1.10",
"#react-navigation/native": "^5.9.3",
"#react-navigation/stack": "^5.14.3",
"expo": "~40.0.0",
"expo-status-bar": "~1.0.3",
"moment": "^2.29.1",
"numeral": "^2.0.6",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
"react-native-gesture-handler": "~1.8.0",
"react-native-reanimated": "~1.13.0",
"react-native-safe-area-context": "^3.1.9",
"react-native-screens": "~2.15.2",
"react-native-web": "~0.13.12",
"react-navigation": "^4.4.4",
"react-navigation-stack": "^2.10.4",
"react-redux": "^7.2.2",
"redux": "^4.0.5"
},
"devDependencies": {
"#babel/core": "~7.9.0",
"typescript": "~4.0.0",
"#types/react": "~16.9.35",
"#types/react-native": "~0.63.2"
},
"private": true
}
UPDATE: changing import { Store } from './Store/configureStore'; to import Store from './Store/configureStore'; in App.js makes it work
Already answer here: TypeError: undefined is not an object (evaluating 'store.getState')

you have to change
Store config:
export const store = createStore(toggleFavorite)
now you can import like this
import { store } from './Store/configureStore';
In mapStateToProps add (toggleFavorite) reducer where, that (favoritesFilm) state is present
const mapStateToProps = (state) => {
return {
favoritesFilm: state.toggleFavorite.favoritesFilm
}
}

Related

React Native Gesture Handler / React Native animated 2: Tried to synchronously call function {_readOnlyError} from a different thread

Error
Im learning react native gesture handler and react native reanimated from the docs. I got this error when i got the gesture coordinates ,passed them to the useShared value translateX. Im running my app on a Samsung Galaxy A5 2017 running android 8.0.0. Please explain your answer.
App.js
// import { StatusBar } from 'expo-status-bar';
import { useEffect } from 'react';
import { StyleSheet, Text, View,StatusBar,TouchableOpacity } from 'react-native';
import Animated, {useSharedValue, useAnimatedStyle, withTiming,withSpring,withRepeat} from 'react-native-reanimated'
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { NavigationContainer } from '#react-navigation/native';
import Header from './components/Header';
import Gesture from './screens/Gesture';
const SimpleAnimation=({navigation})=>{
const SIZE=100.0
const handleRotation=(progress)=>{
"worklet";
return `${progress.value*2*Math.PI}rad`;
}
const progress=useSharedValue(0.5)
const scale=useSharedValue(0.5)
const reanimatedStyle=useAnimatedStyle(()=>{
return {
opacity: progress.value,
transform:[{scale:scale.value},{rotate:handleRotation(progress) }],
borderRadius:(progress.value*SIZE)/2,
};
},[])
useEffect(()=>{
progress.value=withRepeat(withSpring(1),-1,true);
scale.value=withRepeat(withSpring(2),-1,true)
},[]);
return (
<View style={{flex:1,marginTop:StatusBar.currentHeight}}>
<Header LeftComponent={()=>(<Text style={{color:"tomato",fontWeight:"bold",fontSize:20}}>Animation</Text>)} RightComponent={()=>(<TouchableOpacity onPress={()=>navigation.navigate("GestureScreen")} style={{backgroundColor:"tomato",padding:10,borderRadius:10,}}><Text style={{color:"white",fontWeight:"bold"}}>Go To Gestures</Text></TouchableOpacity>)} />
<View style={styles.container}>
<Animated.View style={[{width:SIZE,height:SIZE,backgroundColor:"blue"},reanimatedStyle]}>
</Animated.View>
</View>
</View>
);
}
const Stack = createNativeStackNavigator();
export default function App() {
const navigateTo=(screenname)=>{
}
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Animation' screenOptions={{headerShown:false}}>
<Stack.Screen name="Animation" component={SimpleAnimation}/>
<Stack.Screen name="GestureScreen" component={Gesture}/>
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Gesture.js
import { StyleSheet, Text, View,StatusBar,TouchableOpacity } from 'react-native'
import React from 'react'
import Animated,{useSharedValue,useAnimatedStyle, runOnJS} from 'react-native-reanimated'
import Header from '../components/Header'
import { Gesture,GestureDetector,GestureHandlerRootView } from 'react-native-gesture-handler'
function ActualGesture() {
const translateX=useSharedValue(0);
// const translateY=useSharedValue(0);
const gesture=Gesture.Pan().onUpdate((event)=>{
translateX=event.translationX;
});
const rStyle=useAnimatedStyle(()=>{
return {
transform:[{translateX:translateX.value}],
};
});
return (
<GestureHandlerRootView style={styles.container}>
<GestureDetector gesture={gesture}>
<Animated.View style={[styles.circle,rStyle]}></Animated.View>
</GestureDetector>
</GestureHandlerRootView>
)
}
const GestureScreen = ({navigation}) => {
return (
<View style={{flex:1,marginTop:StatusBar.currentHeight}}>
<Header LeftComponent={()=>(<TouchableOpacity onPress={()=>navigation.navigate("Animation")} style={{backgroundColor:"tomato",padding:10,borderRadius:10,}}><Text style={{color:"white",fontWeight:"bold"}}>Return</Text></TouchableOpacity>)} RightComponent={()=>(<TouchableOpacity onPress={()=>navigation.navigate("GestureScreen")} style={{backgroundColor:"tomato",padding:10,borderRadius:10,}}><Text style={{color:"white",fontWeight:"bold"}}>Go To Gestures</Text></TouchableOpacity>)} />
<ActualGesture/>
</View>
)
}
export default GestureScreen
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
circle:{
height:60,aspectRatio:1,backgroundColor:"blue",borderRadius:50
}
});
package.json
{
"name": "animate",
"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",
"eject": "expo eject"
},
"dependencies": {
"#react-navigation/native": "^6.0.8",
"#react-navigation/native-stack": "^6.5.0",
"expo": "~44.0.0",
"expo-status-bar": "~1.2.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-gesture-handler": "~2.1.0",
"react-native-reanimated": "~2.3.1",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "~3.10.1",
"react-native-web": "0.17.1"
},
"devDependencies": {
"#babel/core": "^7.12.9"
},
"private": true
}
From what i understand from the error is that the gesture function shouldve either been a JS thread or a worklet,i tried doing that to no avail by adding "worklet"; to the beginning of the functions code. Im guessing this is an android error, because based off youtube tutorials given an iOS emulator it works just fine. The gesture function is bringing the right coordinates, its just the changing of the styling to match the translatex value. Please help me i dont know how to carry on from here.
react-native-gesture-handler Gesture can run on js thread with .runOnJS(true) in your case it would be :
function ActualGesture() {
const translateX=useSharedValue(0);
// const translateY=useSharedValue(0);
const gesture=Gesture.Pan().runOnJS(true).onUpdate((event)=>{
translateX=event.translationX;
});
const rStyle=useAnimatedStyle(()=>{
return {
transform:[{translateX:translateX.value}],
};
});
return (
<GestureHandlerRootView style={styles.container}>
<GestureDetector gesture={gesture}>
<Animated.View style={[styles.circle,rStyle]}></Animated.View>
</GestureDetector>
</GestureHandlerRootView>
)
}

Expo GestureHandler isn't firing any events

i've seen alot of people having the same problem but sadly without any solutions .
I'm using expo with react native gesture handler, i have added "react-native-reanimated/plugin" in babel.config.js but still not getting any response.
Here is my code:
babel.config.js
module.exports = function (api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: ["react-native-reanimated/plugin"],
};
};
App.js
import { PanGestureHandler } from "react-native-gesture-handler";
import "react-native-gesture-handler";
import Animated, {
useAnimatedGestureHandler,
useAnimatedStyle,
useSharedValue,
} from "react-native-reanimated";
import { StyleSheet, View } from "react-native";
const SIZE = 100.0;
export default function App() {
const translateX = useSharedValue(0);
const panGestureEvent = useAnimatedGestureHandler({
onStart: (event) => {
console.log("starting...");
},
onActive: (event) => {
// translateX.value = event.translationX;
console.log(event.translationX);
},
onEnd: (event) => {},
});
const rStyle = useAnimatedStyle(() => {
return {
transform: [{ translateX: translateX.value }],
};
});
return (
<View style={styles.container}>
<PanGestureHandler onGestureEvent={panGestureEvent}>
<Animated.View style={[styles.square, rStyle]} />
</PanGestureHandler>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
square: {
width: SIZE,
height: SIZE,
backgroundColor: "dodgerblue",
borderRadius: 15,
},
});
i didn't do anything smart, simple and easy code, yet not getting any response.
package.json
{
"name": "a",
"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",
"eject": "expo eject"
},
"dependencies": {
"expo": "~44.0.0",
"expo-status-bar": "~1.2.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-web": "0.17.1",
"react-native-gesture-handler": "~2.1.0",
"react-native-reanimated": "^2.3.1"
},
"devDependencies": {
"#babel/core": "^7.12.9"
},
"private": true
}
On Android you need to wrap everything with GestureHandlerRootView.
So do this below
import {
GestureHandlerRootView,
} from 'react-native-gesture-handler';
then
<GestureHandlerRootView style={{ flex: 1 }}>
<View style={styles.container}>
<PanGestureHandler onGestureEvent={panGestureEvent}>
<Animated.View style={[styles.square, rStyle]} />
</PanGestureHandler>
</View>
</GestureHandlerRootView>
Related documentation: https://docs.swmansion.com/react-native-gesture-handler/docs/installation#js

React.createElement: type is invalid expected a string

I am newbie with react native, I trying to make restaurant app, but getting the following error in the browser console:
React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s%s, undefined, You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
so what I am missing? it telling me that the error is in the render method but i can't figure it out
app.js :
import React from 'react';
import { StyleSheet, Text, FlatList, ActivityIndicator, View, Image } from 'react-native';
import { List, ListItem, SearchBar, Avatar } from "react-native-elements";
import { StackNavigator,createAppContainer } from 'react-navigation';
import { createStackNavigator} from 'react-navigation-stack';
import { constants } from 'expo';
import HomeScreen from './src/home';
import DetailScreen from './src/detail';
const AppNavigator = createStackNavigator({
Home: { screen: HomeScreen,
navigationOptions: {
title: 'Home',
headerBackTitle: 'Back',
},
},
Detail: { screen: DetailScreen,
navigationOptions: {
title: 'Detail',
},
}
});
export default createAppContainer(AppNavigator);
home.js :
import React from 'react';
import { StyleSheet, Text, FlatList, ActivityIndicator, View, Image } from 'react-native';
import { List, ListItem, SearchBar, Avatar } from "react-native-elements";
import { StackNavigator } from 'react-navigation';
export default class HomeScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
data: [],
error: null,
refreshing: false,
base_url: "http://localhost:8000/api"
}
}
componentDidMount() {
this.fetchDataFromApi();
}
fetchDataFromApi = () => {
const url = "http://localhost:8000/api.json";
this.setState({ loading: true });
fetch(url)
.then(res => res.json())
.then(res => {
this.setState({
data: res,
error: null,
loading: false,
refreshing: false
});
})
.catch(error => {
this.setState({ error, loading : false });
})
};
handleRefresh = () => {
this.setState(
{
refreshing: true
},
() => {
this.fetchDataFromApi();
}
);
};
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: "86%",
backgroundColor: "#CED0CE",
marginLeft: "14%",
marginTop: "3%"
}}
/>
);
};
renderHeader = () => {
return <SearchBar placeholder="Type Here..." lightTheme round />;
};
render() {
return (
<List containerStyle={{ borderTopWidth: 0, borderBottomWidth: 0 }}>
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
onPress={() => this.props.navigation.navigate('Detail',
{name: `${item.name}`, menu: `${item.menu}`,
img: `${this.state.base_url}${item.photo}`,
address: `${item.address}`})}
avatar={<Avatar
source={{uri: `${this.state.base_url}${item.photo}`}}
onPress={() => console.log("Works!")}
containerStyle={{marginBottom: 2}}
avatarStyle={{resizeMode: "cover"}}
width={140}
height={130}
/>}
title={`${item.name}`}
titleStyle={{ fontSize: 16}}
titleContainerStyle = {{ marginLeft: 120 }}
subtitle={<View style={styles.subtitleView}>
<Text style={styles.menuText}>{item.menu}</Text>
<Text style={styles.locText}>{item.address}</Text>
</View>}
containerStyle={{ borderBottomWidth: 0, marginBottom: 20 }}
/>
)}
keyExtractor={item => item.id}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
onRefresh={this.handleRefresh}
refreshing={this.state.refreshing}
/>
</List>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
subtitleView: {
flexDirection: 'column',
paddingLeft: 10,
paddingTop: 5,
marginLeft: 110
},
menuText: {
paddingLeft: 10,
color: 'grey'
},
locText: {
paddingLeft: 10,
color: 'grey',
marginTop: 6,
fontSize: 12
},
titleText: {
fontWeight: 'bold'
},
restaurantImage: {
width: 600,
height: 800
}
});
package.json :
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"expo": "~37.0.3",
"react": "~16.9.0",
"react-dom": "~16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
"react-native-elements": "^2.0.1",
"react-native-gesture-handler": "~1.6.0",
"react-native-web": "~0.11.7",
"react-navigation": "^4.3.9",
"react-navigation-stack": "^2.5.1",
"react-native-reanimated": "~1.7.0",
"react-native-screens": "~2.2.0",
"react-native-safe-area-context": "0.7.3",
"#react-native-community/masked-view": "0.1.6"
},
"devDependencies": {
"babel-preset-expo": "~8.1.0",
"#babel/core": "^7.8.6"
},
"private": true
}
Check your imports you probably have imported the wrong component which doesn't exist.
I suspect it's List which you imported from react-native-elements, I think there is no component named List.
What you are doing wrong is you are importing stackNavigator wrongly
change
import { StackNavigator } from 'react-navigation';
to
import { createStackNavigator} from 'react-navigation';
Hope this helps!

How to decrease launch time of react native app

I am developing news app using react native, and my problem is the launch or startup time of app is long(before the home screen shows), I would appreciate any advice to improve the speed.It takes around 4 seconds to load initially and 2 seconds for the js. I have 36 articles to show on home screen and the json response is big and maybe it is the reason of the problem.
My package.json looks like this :
{
"name": "tageblattapp",
"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",
"moment": "^2.24.0",
"native-base": "^2.13.12",
"react": "16.11.0",
"react-native": "0.62.0",
"react-native-gesture-handler": "^1.6.1",
"react-native-optimized-flatlist": "^1.0.4",
"react-native-reanimated": "^1.7.1",
"react-native-render-html": "^4.2.0",
"react-native-safe-area-context": "^0.7.3",
"react-native-safe-area-view": "^1.0.0",
"react-native-screens": "^2.7.0",
"react-native-vector-icons": "^6.6.0",
"react-native-webview": "^9.3.0",
"react-navigation": "^4.3.5",
"react-navigation-drawer": "^2.4.12",
"react-navigation-stack": "^2.3.9"
},
"devDependencies": {
"#babel/core": "7.9.0",
"#babel/runtime": "7.9.2",
"#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.58.0",
"react-test-renderer": "16.11.0"
},
"jest": {
"preset": "react-native"
},
"rnpm": {
"assets": [
"../assets/fonts/"
]
}
}
My imports are:
import React,{PureComponent} from 'react';
import {AsyncStorage, Linking ,Share, View ,Image,ActivityIndicator ,StyleSheet, TouchableOpacity,Dimensions,ScrollView,SafeAreaView, TextInput ,FlatList} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { createAppContainer } from 'react-navigation';
import {Container, Header, Left, Body, Right, Button, Title,Text,Content, List, ListItem,Thumbnail} from 'native-base';
import { createStackNavigator } from 'react-navigation-stack';
import { createDrawerNavigator } from 'react-navigation-drawer';
import { IMAGE } from '../constants/image';
import { getMenusideGategory} from '../services/news';
import HTML from 'react-native-render-html';
import Time from '../components/time';
import moment from 'moment';
import FeedDetail from './FeedDetail';
import ArticleLink from './ArticleLink';
import Comments from './Comments';
import AddComments from './AddComments';
The funcyion that gets articles:
export async function getArticles(){
try {
let articles = await fetch(`${articles_url}`,{
headers:{
'X-API-KEY':_api_key
}
});
let result = await articles.json();
return result.articles;
} catch (error) {
throw error
}
}
The home.js that display the articles is :
export class HomeScreen extends PureComponent {
constructor(props) {
super(props);
this._handleItemDataOnPress = this._handleItemDataOnPress.bind(this)
this.state = {
isLoading: true,
data: null,
isError: false,
setModalVisible: false,
modalArticleData: {}
}
}
_handleItemDataOnPress(articleData) {
this.setState({
setModalVisible: true,
modalArticleData: articleData
})
}
componentDidMount() {
getArticles().then(data => {
this.setState({
isLoading: false,
data: data
})
}, error => {
Alert.alert("Error", "Something happend, please try again")
})
}
render() {
let view = this.state.isLoading ? (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<ActivityIndicator animating={this.state.isLoading} color="#00f0ff" />
<Text style={{ marginTop: 8 }} children="Please wait..." />
</View>
) : (
<FlatList
dataArray={this.state.data}
renderRow={(item) => {
return (
<ListItem>
<ListDataItem onPress={this._handleItemDataOnPress} data={item} />
</ListItem>
)
}} />
)
return (
<Container>
<Header>
<Body>
<Title children="RN NewsApp" />
</Body>
</Header>
<Content
contentContainerStyle={{ flex: 1, backgroundColor: '#fff' }}
padder={false}>
{view}
</Content>
</Container>
)
}
}
The class ListDataItem that shows single data item inside the list renderRow:
export default class ListDataItem extends PureComponent{
constructor(props){
super(props);
this.data = props.data;
this._handlePress = this._handlePress.bind(this)
}
_handlePress(){
const {url, title} = this.data
this.props.onPress({url,title})
}
render(){
return(
<TouchableOpacity onPress={this._handlePress} style={{flexDirection:'row'}} activeOpacity={0.5}>
<Thumbnail style={{ backgroundColor: '#eee', alignSelf: 'center' }} square large source={{ cache:'force-cache', uri: this.data.urlToImage != null ? this.data.urlToImage : null }} />
<Body>
<Text style={{fontSize: 16 }} numberOfLines={2}>{this.data.title}</Text>
<Text note numberOfLines={3}>{this.data.description}</Text>
<View style={{ flex: 1, flexDirection: 'row', marginTop: 8, marginLeft: 8 }}>
<Text note>{this.data.source.name}</Text>
<TimeAgo date={this.data.publishedAt} />
</View>
</Body>
</TouchableOpacity>
)
}
}
I tried also to put the header inside the flatlist using LisHeaderComponent, but there was no difference.
Decrease your start up time and RAM memory consumption by an application via splitting JS bundle by components and navigation routes.
https://www.npmjs.com/package/react-native-bundle-splitter
Just by creating a release Apk/Build
In a release Apk, App loads in just half a second which means the Splash screen or Launch screen shows up for half a second only.

Uncaught Error: undefined is not an object (evaluating 't.props.navigation.navigate') touchableHandlePress#[native code]

I am creating a component called HomeIcon and inserting it in my header via defaultNavigationOptions > headerRight, I added an onPress in this component by assigning this.props.navigation.navigate('Main'); with the purpose that clicking on this component loads the MainScreen but when I click the error described in the above heading occurs.
Here's the code:
import React from 'react';
import { StyleSheet, TouchableOpacity, Image, Dimensions } from 'react-native';
export default class HomeIcon extends React.Component {
render() {
return (
<TouchableOpacity onPress={() => {
this.props.navigation.navigate('Main');
}}>
<Image style={styles.buttonHome} source={require('../icons/home2.png')} />
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
buttonHome: {
aspectRatio: 1,
resizeMode: 'contain',
height: Dimensions.get('window').width * 0.08,
width: Dimensions.get('window').height * 0.08,
margin: Dimensions.get('window').height * 0.018
}
});
import React from 'react';
import { createAppContainer, createStackNavigator } from 'react-navigation';
import Main from './source/screens/MainScreen';
import CustomCards from './source/screens/CustomCardsScreen';
import HomeIcon from './source/components/HomeIcon';
const AppNavigator = createStackNavigator ({
'Main': {
screen: Main,
navigationOptions: {
title: 'Tela Principal'
}
},
'CustomCards': {
screen: CustomCards,
navigationOptions: {
title: 'Cartões Personalizados'
}
}
}, {
defaultNavigationOptions: {
headerTitleStyle: {
flexGrow: 1,
fontWeight: 'bold',
textAlign: 'center'
},
headerLeft: (null),
headerRight: (
<HomeIcon />
),
headerStyle:{
backgroundColor: '#7d253b'
},
headerTintColor: '#FFF'
}
});
const AppContainer = createAppContainer(AppNavigator);
export default AppContainer;
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject"
},
"dependencies": {
"#types/react": "^16.8.13",
"#types/react-native": "^0.57.43",
"expo": "^32.0.0",
"react": "16.5.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
"react-navigation": "^3.6.1"
},
"devDependencies": {
"babel-preset-expo": "^5.0.0"
},
"private": true
}
Visit the project repository in GitHub for more details: https://github.com/Alex-Xavier/ACTIFICA
defaultNavigationOptions = ({ navigation }) => ({
headerTitleStyle: {
flexGrow: 1,
fontWeight: 'bold',
textAlign: 'center',
},
headerLeft: (null),
headerRight: (
<HomeIcon navigation={navigation} />
),
headerStyle: {
backgroundColor: '#7d253b',
},
headerTintColor: '#FFF',
});
You need to pass a navigation object to that component.
'this.props.navigation' only available in a screens that is directly assign to stack/tab/drawer navigation.
In your case it's screens 'Main' and 'CustomCards'
HomeIcon component have no idea what is a this.props.navigation.
You have to pass 'navigation' as a props. Like so:
headerRight: ({ navigation }) => <HomeIcon navigation={navigation}/>
Then in you HomeIcon it's will be available as this.props.navigation.