Lessonlist in the app component displays a list of lessons, if there are a lot of them, scrolling works but does not show all the elements. That is, some element remains at the bottom and is only half visible. When the height of the lessonlist changes, the height of the dataslider component also changes.
App
return (
<View style={styles.container}>
<StatusBar style="auto" />
<View style={styles.today}>
<Moment element={Text} style={styles.today_day} format='D'></Moment>
<View style={styles.today_column}>
<Moment element={Text} style={styles.today_day_week} format='dddd'></Moment>
<Moment element={Text} style={styles.today_month_year} format='MMMM YYYY'></Moment>
</View>
</View>
<View>
<DateSlider data={Lessons} index={index} setIndex={setIndex} />
<LessonList data={Lessons} index={index} setIndex={setIndex} />
</View>
</View>
);
LessonList
import React from 'react';
import { StyleSheet, Text, View, FlatList, Dimensions, ScrollView } from 'react-native'
import AntDesign from '#expo/vector-icons/AntDesign';
const { width, height } = Dimensions.get('screen');
const LessonList = ({ data, index, setIndex }) => {
const lessonsRef = React.useRef<FlatList>();
React.useEffect(() => {
lessonsRef.current?.scrollToOffset({
offset: index * width,
animated: true,
});
}, [index]);
return (
<FlatList
ref={lessonsRef}
initialNumToRender={1}
initialScrollIndex={index}
data={data.days}
maxToRenderPerBatch={3}
keyExtractor={(item) => item.date}
getItemLayout={(data, index) => ({
length: width,
offset: width * index,
index,
})}
onMomentumScrollEnd={(ev) => {
setIndex(Math.floor(Math.floor(ev.nativeEvent.contentOffset.x) / Math.floor(width)));
}}
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
renderItem={({ item }) => {
return (
<FlatList
data={item.lessons}
keyExtractor={(item) => item.id}
showsVerticalScrollIndicator={false}
scrollEnabled={true}
style={styles.lessons_scrollview}
renderItem={({ item }) => {
return (
<View style={styles.lessons}>
<View style={styles.lesson_time}>
<Text style={styles.lesson_time_list_text}>
{item.starttime}
</Text>
<Text style={styles.lesson_time_end_list_text}>
{item.endtime}
</Text>
</View>
<View style={styles.lesson_card}>
<Text style={styles.lesson_card_name}>{item.name}</Text>
<Text style={styles.lesson_card_description}>
{item.description}
</Text>
<Text style={styles.lesson_card_locate}>
<AntDesign name="enviromento" size={16} color="white" />
{item.location}
</Text>
<Text style={styles.lesson_card_teacher}>
<AntDesign name="user" size={16} color="white" />
{item.teacher}
</Text>
</View>
</View>
);
}}
/>
);
}}
/>
);
};
const styles = StyleSheet.create({
lessons_scrollview: {
paddingHorizontal: 15,
paddingTop: 5,
width: width,
},
lessons: {
flexDirection: "row",
},
lesson_time_text: {
fontFamily: "eUkraineBold",
fontSize: 9,
paddingRight: 30,
color: "#BCC1CD",
},
lesson_time: {
flexDirection: "column",
paddingRight: 9,
borderRightWidth: 1,
borderRightColor: "#FAF9F9",
},
lessons_text: {
fontFamily: "eUkraineBold",
fontSize: 9,
color: "#BCC1CD",
},
lesson_time_list: {
flexDirection: "column",
paddingTop: 14,
},
lesson_time_list_text: {
fontFamily: "eUkraineMedium",
fontSize: 14,
},
lesson_time_end_list_text: {
fontFamily: "eUkraineMedium",
fontSize: 14,
color: "#BCC1CD",
},
lesson_card: {
flexDirection: "column",
marginLeft: 16,
backgroundColor: "#4DC591",
borderRadius: 16,
paddingTop: 16,
paddingLeft: 16,
paddingBottom: 17,
flex: 1,
marginBottom: 16,
},
lesson_card_name: {
fontFamily: "eUkraineBold",
fontSize: 13,
color: "#ffff",
},
lesson_card_description: {
fontFamily: "eUkraineMedium",
fontSize: 10,
paddingTop: 4,
color: "#ffff",
},
lesson_card_locate_img: {
height: 16,
width: 16,
marginRight: 50,
tintColor: "#FFFFFF",
},
lesson_card_locate: {
fontFamily: "eUkraineRegular",
fontSize: 10,
paddingTop: 15,
color: "#ffff",
},
lesson_card_teacher: {
fontFamily: "eUkraineRegular",
fontSize: 10,
paddingTop: 3,
color: "#ffff",
},
});
export default LessonList
Related
const Home = ({navigation}) => {
const renderDiscoverItem = ({item}) => {
return (
<TouchableOpacity
onPress={() =>
navigation.navigate('Details', {
item: item,
})
}>
<ImageBackground
source={item.images}
style={[
styles.discoverItem,
{marginLeft: item.id === 'discover-1' ? 20 : 0},
]}
imageStyle={styles.discoverItemImage}>
<Text style={styles.discoverItemTitle}>{item.title}</Text>
<View style={styles.discoverItemLocationWrapper}>
<Entypo name="location-pin" size={18} color={colors.white} />
<Text style={styles.discoverItemLocationText}>{item.location}</Text>
</View>
</ImageBackground>
</TouchableOpacity>
);
};
There were 2 issues,
You were exporting directly Home in App.js which means Home is not wrapped inside any navigator, find below the corrected code for App.js
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import Home from './components/Home';
import Details from './components/Details';
import Liked from './components/Liked';
import Profile from './components/Profile';
import colors from './assets/colors/colors';
import Entypo from 'react-native-vector-icons/Entypo';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
Entypo.loadFont();
MaterialCommunityIcons.loadFont();
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
const TabNavigator = () => {
return (
<Tab.Navigator
tabBarOptions={{
style: styles.tabBar,
activeTintColor: colors.orange,
inactiveTintColor: colors.gray,
showLable: false,
}}>
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarIcon: ({color}) => (
<Entypo name="home" size={32} color={color} />
),
}}
/>
<Tab.Screen
name="Liked"
component={Liked}
options={{
tabBarIcon: ({color}) => (
<Entypo name="heart" size={32} color={color} />
),
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarIcon: ({color}) => (
<MaterialCommunityIcons name="account" size={32} color={color} />
),
}}
/>
</Tab.Navigator>
);
};
const App = () => {
console.log('inside app')
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="TabNavigator"
component={TabNavigator}
options={{headerShown: false}}
/>
<Stack.Screen
name="Details"
component={Details}
options={{headerShown: false}}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
const styles = StyleSheet.create({
tabBar: {
backgroundColor: colors.white,
borderTapLeftRedius: 20,
borderTopRightRadius: 20,
},
});
export default App;
Second mistake is the usage of useNavigation hook, it must be used as below in the corrected code,
import React from 'react';
import {
View,
Text,
StyleSheet,
Image,
ScrollView,
ImageBackground,
AppRegistry,
} from 'react-native';
import colors from '../assets/colors/colors';
import Feather from 'react-native-vector-icons/Feather';
import Entypo from 'react-native-vector-icons/Entypo';
import activitiesData from '../assets/data/activitiesData';
import discoverCategoriesData from '../assets/data/discoverCategoriesData';
import learnMoreData from '../assets/data/learnMoreData';
import discoverData from '../assets/data/discoverData';
import {SafeAreaView} from 'react-native-safe-area-context';
import profile from '../assets/images/profile.png';
import {FlatList, TouchableOpacity} from 'react-native-gesture-handler';
import { useNavigation } from '#react-navigation/native';
Feather.loadFont();
Entypo.loadFont();
const Home = () => {
const navigation = useNavigation();
const renderDiscoverItem = ({item}) => {
return (
<TouchableOpacity
onPress={() =>
navigation.navigate('Details', {
item: item,
})
}>
<ImageBackground
source={item.images}
style={[
styles.discoverItem,
{marginLeft: item.id === 'discover-1' ? 20 : 0},
]}
imageStyle={styles.discoverItemImage}>
<Text style={styles.discoverItemTitle}>{item.title}</Text>
<View style={styles.discoverItemLocationWrapper}>
<Entypo name="location-pin" size={18} color={colors.white} />
<Text style={styles.discoverItemLocationText}>{item.location}</Text>
</View>
</ImageBackground>
</TouchableOpacity>
);
};
const renderActivityItem = ({item}) => {
return (
<View
style={[
styles.activityItemWrapper,
{
marginLeft: item.id === 'activities-1' ? 20 : 0,
},
]}>
<Image source={item.image} style={styles.activityItemImage} />
<Text style={styles.activityItemText}>{item.title}</Text>
</View>
);
};
const renderLearnMoreItem = ({item}) => {
return (
<ImageBackground
source={item.images}
style={[
styles.learnMoreItem,
{
marginLeft: item.id === 'learnMore-1' ? 20 : 0,
},
]}
imageStyle={styles.learnMoreItemImage}>
<Text style={styles.learnMoreItemText}>{item.title}</Text>
</ImageBackground>
);
};
return (
<View style={styles.container}>
<ScrollView>
{/* Header */}
<SafeAreaView>
<View style={styles.menuWrapper}>
<Feather
name="menu"
size={32}
color={colors.black}
style={styles.menuIcon}
/>
<Image source={profile} style={styles.profileImage} />
</View>
</SafeAreaView>
{/* Discover */}
<View style={styles.discoverWrapper}>
<Text style={styles.discoverTitle}>Discover</Text>
<View style={styles.discoverCategoriesWrapper}>
<Text style={[styles.discoverCategoryText, {color: colors.orange}]}>
All
</Text>
<Text style={styles.discoverCategoryText}>Destinations</Text>
<Text style={styles.discoverCategoryText}>Cities</Text>
<Text style={styles.discoverCategoryText}>Experiences</Text>
</View>
<View style={styles.discoverItemsWrapper}>
<FlatList
data={discoverData}
renderItem={renderDiscoverItem}
keyExtractor={(item) => item.id}
horizontal
showsHorizontalScrollIndicator={false}
/>
</View>
</View>
{/* Activities */}
<View style={styles.activitiesWrapper}>
<Text style={styles.activitiesTitle}>Activities</Text>
<View style={styles.activitiesItemsWrapper}>
<FlatList
data={activitiesData}
renderItem={renderActivityItem}
keyExtractor={(item) => item.id}
horizontal
showsHorizontalScrollIndicator={false}
/>
</View>
</View>
{/* Learn More */}
<View style={styles.learnMoreWrapper}>
<Text style={styles.learnMoreTitle}>Learn More</Text>
<View style={styles.learnMoreItemsWrapper}>
<FlatList
data={learnMoreData}
renderItem={renderLearnMoreItem}
keyExtractor={(item) => item.id}
horizontal
showsHorizontalScrollIndicator={false}
/>
</View>
</View>
</ScrollView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
color: colors.white,
},
menuWrapper: {
marginHorizontal: 20,
marginTop: 20,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
profileImage: {
width: 52,
height: 52,
borderRadius: 10,
},
discoverWrapper: {
// marginHorizontal: 20,
marginTop: 20,
},
discoverTitle: {
marginHorizontal: 20,
fontFamily: 'Lato-Bold',
fontSize: 32,
},
discoverCategoriesWrapper: {
marginHorizontal: 20,
flexDirection: 'row',
marginTop: 20,
},
discoverCategoryText: {
marginRight: 30,
fontFamily: 'Lato-Regular',
fontSize: 16,
color: colors.gray,
},
discoverItemsWrapper: {
paddingVertical: 20,
},
discoverItem: {
width: 170,
height: 250,
justifyContent: 'flex-end',
paddingHorizontal: 10,
paddingVertical: 15,
marginRight: 20,
},
discoverItemImage: {
borderRadius: 20,
},
discoverItemTitle: {
fontFamily: 'Lato-Bold',
fontSize: 18,
color: colors.white,
},
discoverItemLocationWrapper: {
flexDirection: 'row',
alignItems: 'center',
marginTop: 5,
},
discoverItemLocationText: {
marginLeft: 5,
fontFamily: 'Lato-Bold',
fontSize: 14,
color: colors.white,
},
activitiesWrapper: {
marginTop: 10,
},
activitiesTitle: {
marginHorizontal: 20,
fontFamily: 'Lato-Bold',
fontSize: 24,
color: colors.black,
},
activitiesItemsWrapper: {
paddingVertical: 20,
},
activityItemWrapper: {
justifyContent: 'flex-end',
alignItems: 'center',
marginRight: 20,
},
activityItemImage: {
width: 36,
},
activityItemText: {
marginTop: 5,
fontFamily: 'Lato-Bold',
fontSize: 14,
color: colors.gray,
},
learnMoreWrapper: {
marginTop: 10,
},
learnMoreTitle: {
marginHorizontal: 20,
fontFamily: 'Lato-Bold',
fontSize: 24,
color: colors.black,
},
learnMoreItemsWrapper: {
paddingVertical: 20,
},
learnMoreItem: {
width: 170,
height: 180,
justifyContent: 'flex-end',
marginRight: 20,
},
learnMoreItemImage: {
borderRadius: 20,
},
learnMoreItemText: {
fontFamily: 'Lato-Bold',
fontSize: 18,
color: colors.white,
marginHorizontal: 10,
marginVertical: 20,
},
});
export default Home;
Fully working code can be found here
I am making an app which will show some statistics. I choose to make a Barchart with help of react-native-chart-kit. But its gives error: TypeError: undefined is not an object (evaluating 'data.map'). This error shows when i use barchart and the same code is working properly with linechart.
Here is my Code:
import React, { useState } from "react";
import { StyleSheet, Dimensions, Alert, TouchableHighlight, Text, View, Button, TouchableOpacity } from 'react-native';
import {
LineChart,
BarChart,
PieChart,
ProgressChart,
ContributionGraph
} from 'react-native-chart-kit'
export default function TrendsScreen() {
const [handleClick, sethandleClick] = useState(false);
// const [color,setColor]=useState('red');
//const [textColor,setTextColor]=useState('white');
if (handleClick) {
alert("fgfhfhg");
}
return (
<View style={styles.view}>
<View style={styles.container}>
<TouchableOpacity
style={styles.customBtnBG}
onPress={() => sethandleClick(true)}
>
<Text style={styles.customBtnText}>Current month</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.customBtnBG}
onPress={() => { }}
>
<Text style={styles.customBtnText}>6 Month</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.customBtnBG}
onPress={() => { }}
>
<Text style={styles.customBtnText}>12 Month</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.customBtnBG}
onPress={() => { }}
>
<Text style={styles.customBtnText}>All Time</Text>
</TouchableOpacity>
</View>
<View>
<Text style={styles.Text}>
Trend
</Text>
</View>
<View style={styles.chart}>
<BarChart
data={{
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [{
data: [
Math.random() * 100,
Math.random() * 100,
]
}
]
}}
width={Dimensions.get('window').width} // from react-native
height={220}
chartConfig={{
backgroundColor: 'red',
backgroundGradientFrom: 'white',
backgroundGradientTo: 'white',
color: (opacity = 1) => `rgba(20, 20, 20, ${opacity})`,
style: {
borderRadius: 16
}
}}
bezier
style={{
marginVertical: 8,
borderRadius: 16
}}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
view: {
marginTop: 20
},
Text: {
padding: 16,
fontSize: 20,
fontStyle: 'italic',
},
container: {
flexDirection: 'row',
justifyContent: 'space-around',
},
customBtnText: {
fontSize: 14,
color: "#D2D5D6",
textShadowColor: '#585858',
},
/* Here style the background of your button */
customBtnBG: {
flexDirection: 'row',
backgroundColor: "white",
borderWidth: 1,
paddingHorizontal: 10,
paddingVertical: 5,
borderRadius: 5,
borderColor: "#29416F",
}
});
I'm having the same issue after updating to the new version.
Change your react-native-chart-kit version to 6.1.1
react-native-chart-kit: "6.1.1"
Look at my code below please I am trying to find a way to make a delete button but i am very new to react native, i have been trying to do it for the past few hours.
import React, { useState } from 'react';
import { StyleSheet, FlatList, Text, View, Image, TextInput, Button, Keyboard, TouchableOpacity, CheckBox } from 'react-native';
import Interactable from 'react-native-interactable';
export default function App()
const [enteredGoal, setEnteredGoal] = useState('');
const [courseGoals, setCourseGoals] = useState([]);
const goalInputHandler = (enteredText) => {
setEnteredGoal(enteredText);
};
const addGoalHandler = () => {
if (enteredGoal.length > 0) {
setCourseGoals(currentGoals => [...currentGoals, enteredGoal])
} else {
alert("You have to write something!")
}
}
return (
<View style={styles.container}>
<View style={styles.topPart}></View>
<View style={styles.navBar}>
<Image source={require('./assets/baseline_menu_black_18dp.png/')} />
<Text style={styles.heading}> Grocery List </Text>
</View>
<View style={styles.body}>
<TextInput
style={styles.textInput}
placeholder='Groceries'
maxLength={20}
onBlur={Keyboard.dismiss}
value={enteredGoal}
onChangeText={goalInputHandler}
/>
<View style={styles.inputContainer}>
<TouchableOpacity style={styles.saveButton}>
<Button title="ADD" onPress={addGoalHandler} color="#FFFFFF" style={styles.saveButtonText} />
</TouchableOpacity>
</View>
<View style={styles.container}>
<FlatList
data={courseGoals}
renderItem={itemData => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete}>X</Text>
</View>
)}
/>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
topPart: {
height: '3%',
backgroundColor: '#5498A7',
},
navBar: {
height: '10%',
backgroundColor: '#5498A7',
elevation: 3,
paddingHorizontal: 15,
flexDirection: 'row',
alignItems: 'center',
},
body: {
backgroundColor: '#edebe9',
height: '100%',
flex: 1
},
heading: {
fontWeight: "bold",
justifyContent: 'center',
paddingLeft: '13%',
fontSize: 25,
color: '#d6d4d3'
},
textInput: {
borderColor: '#CCCCCC',
borderTopWidth: 1,
borderBottomWidth: 1,
height: 50,
fontSize: 25,
paddingLeft: 20,
paddingRight: 20
},
saveButton: {
borderWidth: 1,
borderColor: '#5498A7',
backgroundColor: '#5498A7',
padding: 15,
margin: 5,
},
saveButtonText: {
color: '#FFFFFF',
fontSize: 20,
textAlign: 'center'
},
groceryItem: {
borderWidth: 1,
borderColor: 'black',
backgroundColor: '#6A686B',
padding: 15,
margin: 5,
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between'
},
groceryItemText: {
color: '#d6d4d3',
},
groceryItemDelete: {
color: 'red',
fontWeight: 'bold',
fontSize: 20
}
});
I hope you guys can find a solution I will keep u guys updated on my progress, I am constantly looking for answers but i don't really understand how to make the delete (X) work and to make it delete a different element, if you know a way to make work better just let me know i would appreciate it a lot
You have to send index to delete function.
renderItem={(itemData,index) => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete.bind(index)}>X</Text>
</View>
and example delete function :
groceryItemDelete(index){
setCourseGoals(currentGoals.splice(index,1))
}
You need to implement the delete method and add an onPress event:
renderItem={(itemData, idx) => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete} onPress={() => deleteItem(idx)}>X</Text>
</View>
)}
const deleteItem = idx => {
const clonedGoals = [...courseGoals]
clonedGoals.splice(idx, 1)
setCourseGoals(clonedGoals)
}
I was working on my app with two screens a Main Screen and a Details Screen everything was working, but the code was long, so I tried to split everything into reusable components which caused a
navigation.navigates type error for some reason.
I checked the code multiple times everything makes perfect sense to me is there something am missing here, how do I fixed this error?
Am using react navigation version 5 for the first time.
Here is a sample of the code used:
MainScreen.js
import React from "react";
import { StyleSheet, Text, View, Image, FlatList } from "react-native";
import ArticleList from "../components/ArticleList";
function MainScreen() {
return (
<View style={{ flex: 1 }}>
{/* show the data in a flatlist */}
<ArticleList />
</View>
);
}
MainScreen.navigationOptions = () => {
return {
headerShown: false,
};
};
export default MainScreen;
DetailScreen.js
import React from "react";
import { StyleSheet, Text, View, Dimensions, Image } from "react-native";
import { Feather } from "#expo/vector-icons";
import { SharedElement } from "react-native-shared-element";
import { TouchableOpacity, ScrollView } from "react-native-gesture-handler";
const DetailScreen = (props) => {
const { width, height } = Dimensions.get("window");
const { data } = props.route.params;
return (
<View style={styles.container}>
<View>
<SharedElement id={`item.${data.id}.photo`}>
<Image
resizeMode="cover"
source={{ uri: data.image }}
style={{
width: 400,
height: 300,
borderBottomLeftRadius: 10,
borderBottomRightRadius: 10,
}}
/>
</SharedElement>
<View
style={{
flexDirection: "row",
alignItems: "center",
position: "absolute",
bottom: 14,
left: 10,
}}
>
<SharedElement id={`item.${data.id}.profilePic`}>
<Image
resizeMode="cover"
source={{ uri: data.profilePic }}
style={{
width: 60,
height: 60,
borderRadius: 10,
marginRight: 14,
}}
/>
</SharedElement>
<View
style={{
flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
}}
>
<View>
<SharedElement id={`item.${data.id}.username`}>
<Text
style={{ color: "white", fontSize: 16, fontWeight: "bold" }}
>
{data.username}
</Text>
</SharedElement>
<SharedElement id={`item.${data.id}.readtime`}>
<Text style={{ color: "white", fontSize: 14 }}>
{data.readtime}
</Text>
</SharedElement>
</View>
<TouchableOpacity>
<Feather name="bookmark" size={30} color="white" />
</TouchableOpacity>
</View>
</View>
</View>
<ScrollView style={{ paddingHorizontal: 10, paddingTop: 14 }}>
<SharedElement
id={`item.${data.id}.text`}
style={{ width: width - 30, marginBottom: 14 }}
>
<Text style={{ fontSize: 22, fontWeight: "bold", lineHeight: 32 }}>
{data.title}
</Text>
</SharedElement>
<Text
style={{
fontSize: 14,
lineHeight: 28,
textAlign: "justify",
opacity: 0.5,
}}
>
Paragraph 1
</Text>
<Text
style={{
fontSize: 14,
lineHeight: 28,
textAlign: "justify",
opacity: 0.5,
}}
>
Paragraph 2
</Text>
<View
style={{
marginVertical: 25,
paddingBottom: 20,
flex: 1,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
}}
>
<TouchableOpacity
style={{ flexDirection: "row", padding: 12, alignItems: "center" }}
>
<Feather name="heart" size={16} color="orange" />
<Text style={{ marginHorizontal: 10 }}>3.4k Likes</Text>
</TouchableOpacity>
</View>
</ScrollView>
<View style={{ position: "absolute", top: 40, left: 10 }}>
<TouchableOpacity onPress={() => props.navigation.goBack()}>
<Feather name="arrow-left" size={24} color="white" />
</TouchableOpacity>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
export default DetailScreen;
ArticleList.js
import React from "react";
import {
View,
Text,
StyleSheet,
Image,
Dimensions,
FlatList,
} from "react-native";
import { SharedElement } from "react-native-shared-element";
import TouchableScale from "react-native-touchable-scale";
import { data } from "../data";
function ArticleList({ navigation }) {
const { width, height } = Dimensions.get("window");
return (
<View>
<FlatList
horizontal
showsHorizontalScrollIndicator={false}
style={{ paddingHorizontal: 30 }}
data={data}
keyExtractor={(item) => item.id}
renderItem={({ item }) => {
return (
<View>
<View>
<TouchableScale
activeScale={0.9}
tension={50}
friction={7}
useNativeDriver
onPress={() =>
navigation.navigate("DetailScreen", { data: item })
}
>
{/* to show the horizental news list*/}
<SharedElement id={`item.${item.id}.photo`}>
<Image
source={{ uri: item.image }}
style={{
width: width - 100,
height: height - 350,
borderRadius: 14,
marginRight: 30,
}}
/>
</SharedElement>
{/* to show the news titles inside the pictures*/}
<SharedElement
id={`item.${item.id}.text`}
style={{
width: width - 100,
position: "absolute",
bottom: 90,
left: 10,
paddingHorizontal: 10,
}}
>
<Text style={styles.blogTitle}>{item.title}</Text>
</SharedElement>
{/* to show the pictre of the author of the news article*/}
<View
style={{
flexDirection: "row",
alignItems: "center",
position: "absolute",
bottom: 20,
left: 20,
}}
>
<SharedElement id={`item.${item.id}.profilePic`}>
<Image
resizeMode="cover"
source={{ uri: item.profilePic }}
style={styles.blogProfilePic}
/>
</SharedElement>
</View>
{/* to show the name of the author and read time of article*/}
<View>
<SharedElement id={`item.${item.id}.username`}>
<Text style={styles.blogUsername}>{item.username}</Text>
</SharedElement>
<SharedElement id={`item.${item.id}.readtime`}>
<Text style={styles.readtime}>{item.readtime}</Text>
</SharedElement>
</View>
</TouchableScale>
</View>
</View>
);
}}
/>
</View>
);
}
const styles = StyleSheet.create({
blogTitle: {
color: "white",
fontSize: 24,
fontWeight: "bold",
lineHeight: 28,
},
blogProfilePic: {
height: 50,
width: 50,
borderRadius: 10,
marginRight: 14,
},
blogUsername: {
color: "white",
fontSize: 16,
fontWeight: "bold",
},
readtime: {
fontSize: 14,
color: "white",
},
});
export default ArticleList;
App.js
import React from "react";
import "react-native-gesture-handler";
import { createSharedElementStackNavigator } from "react-navigation-shared-element";
import { NavigationContainer } from "#react-navigation/native";
import MainScreen from "./app/screens/MainScreen";
import DetailScreen from "./app/screens/DetailScreen";
const Stack = createSharedElementStackNavigator();
const App = ({ navigation }) => {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="MainScreen"
screenOptions={{ headerShown: false }}
>
<Stack.Screen name="MainScreen" component={MainScreen} />
<Stack.Screen
name="DetailScreen"
component={DetailScreen}
options={(navigation) => ({
headerBackTitleVisible: false,
cardStyleInterpolator: ({ current: { progress } }) => {
return {
cardStyle: {
opacity: progress,
},
};
},
})}
sharedElements={(route) => {
const { data } = route.params;
return [
{
id: `item.${data.id}.photo`,
animation: "move",
resize: "clip",
align: "center-top",
},
{
id: `item.${data.id}.text`,
animation: "fade",
resize: "clip",
align: "left-center",
},
{
id: `item.${data.id}.profilePic`,
animation: "move",
resize: "clip",
align: "left-center",
},
{
id: `item.${data.id}.username`,
animation: "fade",
resize: "clip",
align: "left-center",
},
{
id: `item.${data.id}.readtime`,
animation: "fade",
resize: "clip",
align: "left-center",
},
];
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
My apologies for the long samples of code I tried to keep everything that is connected directly to the problem.
The problem is the you are accessing navigation outside the navigation stack. When you moved the flatlist to to ArticleList its outside the navigation and it wont get the navigation prop.
You can handle this in two ways.
You can simply pass the navigation from the main screen
function MainScreen({ navigation }) {
return (
{/* show the data in a flatlist */}
< ArticleList navigation={navigation} />
);
}
You can use the useNavigation hook to access navigation outside navigation.
I have two components with realm database one is for listing and other is for adding data. But my problem is that i can't update list when data is adding into second component. I have tried App state listener also but it's not triggering when user come at first screen.
This is list component
import React, { Component } from "react";
import AppScreen from "../AppScreen.js";
import realm from "../databases/RealmController.js";
import colors from "../Ui/colors.js";
import Swipeout from "react-native-swipeout";
import { Icon } from "react-native-vector-icons";
import { NavigationActions } from "react-navigation";
import Dash from "react-native-dash";
import AppStateListener from "react-native-appstate-listener";
import {
AppState,
AppRegistry,
StyleSheet,
Text,
Image,
Button,
View,
FlatList,
TouchableHighlight,
TouchableOpacity,
Alert,
StatusBar,
TextInput
} from "react-native";
type Props = {};
export default class ReminderList extends Component<Props> {
state = {
data: [],
loading: true,
refresh: false,
appState: AppState.currentState
};
static navigationOptions = {
header: null,
title: " List"
};
handleActive() {
console.warn("The application is now active!");
}
handleBackground() {
console.warn("The application is now in the background!");
}
handleInactive() {
console.warn("The application is now inactive!");
}
componentDidMount() {
//this.fetchData();
AppState.addEventListener("change", this.handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener("change", this.handleAppStateChange);
}
gotoAddReminder = () => {
// handle navigation
this.props.screenProps.rootNavigation.navigate("addReminder");
};
handleAppStateChange = nextAppState => {
if (nextAppState === "active") {
this.setState({ data: null });
this.fetchData();
this.setState({ refresh: true });
// console.warn("hello i active");
//this.flatList.scrollToIndex({ animated: true, index: 0 });
}
else {
this.setState({ refresh: false });
// console.warn("hello i inactive");
}
this.setState({ appState: nextAppState });
};
fetchData() {
let reminderList = realm.objects("Reminder");
this.setState({ data: reminderList });
}
renderClientRow(item) {
return (
<TouchableHighlight underlayColor="rgba(192,192,192,1,0.6)">
<View style={styles.cardView}>
<View style={styles.dateView}>
<Text style={styles.dateText}>18</Text>
<Text style={styles.monthText}>Jan</Text>
</View>
<View
style={{
width: 1,
backgroundColor: colors.darkGray,
marginLeft: 15,
marginRight: 20
}}
/>
<View style={{ flexDirection: "row", marginTop: 15, width: "100%" }}>
<View style={{ flexDirection: "column" }}>
<Text style={styles.titleText}>{item.name}</Text>
<Text style={(styles.item, { marginTop: 5 })}>location</Text>
<Dash
style={{
width: 300,
marginTop: 10,
height: 1,
marginRight: 15
}}
/>
<View
style={{
flex: 1,
flexDirection: "row",
marginTop: 5,
marginBottom: 15
}}
>
<Image
style={{
width: 15,
height: 15,
marginTop: 5,
marginRight: 10
}}
source={require("../Image/ic_date.png")}
/>
<Text style={styles.item}>0.40 pm</Text>
</View>
</View>
</View>
</View>
</TouchableHighlight>
);
}
render() {
return (
<View style={styles.container}>
<AppStateListener
onActive={this.handleActive}
onBackground={this.handleBackground}
onInactive={this.handleInactive}
/>
<FlatList
ref={(c) => { this.flatList = c }}
data={this.state.data}
extraData={this.state.refresh}
renderItem={({ item }) => this.renderClientRow(item)}
keyExtractor={item => item.id}
/>
<TouchableOpacity
activeOpacity={0.5}
onPress={() => {
this.gotoAddReminder();
}}
style={styles.TouchableOpacityStyle}
>
<Image
source={{
uri:
"https://reactnativecode.com/wp-content/uploads/2017/11/Floating_Button.png"
}}
style={styles.FloatingButtonStyle}
/>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 0
},
MainContainer: {
justifyContent: "center",
flex: 1,
margin: 10
},
TouchableOpacityStyle: {
position: "absolute",
width: 50,
height: 50,
alignItems: "center",
justifyContent: "center",
right: 30,
bottom: 30
},
FloatingButtonStyle: {
resizeMode: "contain",
width: 50,
height: 50
},
cardView: {
backgroundColor: "#fff",
borderWidth: 0.5,
paddingLeft: 15,
paddingRight: 10,
marginLeft: 10,
marginTop: 10,
marginRight: 10,
borderRadius: 5,
flexDirection: "row"
},
item: {
fontSize: 16,
color: colors.darkGray
},
itemRight: {
fontSize: 18,
textAlign: "right"
},
titleText: {
fontSize: 20,
color: "black",
fontWeight: "400"
},
dateText: {
fontSize: 32,
color: colors.appColor,
fontWeight: "500"
},
monthText: {
fontSize: 22,
color: colors.appColor,
fontWeight: "500"
},
dateView: {
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
marginLeft: 15,
marginRight: 15,
marginTop: 15,
marginBottom: 15
},
rightText: {
fontSize: 22,
color: "black",
textAlign: "right",
fontWeight: "bold"
},
myStarStyle: {
color: "yellow",
backgroundColor: "transparent",
textShadowColor: "black",
textShadowOffset: { width: 1, height: 1 },
textShadowRadius: 2
},
myEmptyStarStyle: {
color: "white"
}
});
This is AddData component
import React, { Component } from "react";
import realm from "../databases/RealmController.js";
import styles from "../Ui/AddClientStyles.js";
import { TextInputLayout } from "rn-textinputlayout";
import DatePicker from "react-native-datepicker";
import {
AppRegistry,
StyleSheet,
Text,
TouchableHighlight,
Button,
View,
ScrollView,
Image,
Alert,
StatusBar,
TextInput
} from "react-native";
const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
type Props = {};
export default class AddReminder extends Component<Props> {
state = {
to: "",
from: "",
name: "",
note: "",
location: ""
};
handlePress = async () => {
var Id = realm.objects("Reminder").length + 1;
realm.write(() => {
realm.create("Reminder", {
id: Id,
name: this.state.name,
note: this.state.note,
location: this.state.location,
to: this.state.to,
from: this.state.from
});
});
this.props.navigation.goBack();
};
render() {
return (
<ScrollView style={styles.container}>
<View style={styles.container}>
<View style={styles.profileContainer} />
<View style={styles.bottomContainer}>
<Text style={[styles.titleText, styles.titleStyle]}>
Basic Information
</Text>
<TextInputLayout style={{ marginTop: 0 }}>
<TextInput
style={styles.textInput}
placeholder={"Reminder Title"}
onChangeText={text => this.setState({ name: text })}
/>
</TextInputLayout>
<TextInputLayout style={styles.inputLayout}>
<TextInput
style={styles.textInput}
placeholder={"Note"}
onChangeText={text => this.setState({ note: text })}
/>
</TextInputLayout>
<TextInputLayout style={styles.inputLayout}>
<TextInput
style={styles.textInput}
placeholder={"Location"}
onChangeText={text => this.setState({ location: text })}
/>
</TextInputLayout>
<Text style={[styles.titleText, styles.titleStyle]}>
Date & Time
</Text>
<View style={styles.dateToContainer}>
<View style={{ flexDirection: "column", width: "30%" }}>
<Text style={styles.textInput}>From</Text>
</View>
<View styles={{ flexDirection: "column", width: "70%" }}>
<DatePicker
style={{ width: 200 }}
date={this.state.from}
mode="datetime"
format="YYYY-MM-DD HH:mm"
confirmBtnText="Confirm"
cancelBtnText="Cancel"
customStyles={{
dateIcon: {
position: "absolute",
left: 0,
top: 4,
marginLeft: 0
},
dateInput: {
marginLeft: 36
}
}}
minuteInterval={10}
onDateChange={datetime => {
this.setState({ from: datetime });
}}
/>
</View>
</View>
<View style={styles.dateContainer}>
<View style={{ flexDirection: "column", width: "30%" }}>
<Text style={styles.textInput}>To</Text>
</View>
<View styles={{ flexDirection: "column", width: "70%" }}>
<DatePicker
style={{ width: 200 }}
date={this.state.to}
mode="datetime"
format="YYYY-MM-DD HH:mm"
confirmBtnText="Confirm"
cancelBtnText="Cancel"
customStyles={{
dateIcon: {
position: "absolute",
left: 0,
top: 4,
marginLeft: 0
},
dateInput: {
marginLeft: 36
}
}}
minuteInterval={10}
onDateChange={datetime => {
this.setState({ to: datetime });
}}
/>
</View>
</View>
<TouchableHighlight
style={styles.btnStyle}
onPress={() => {
this.handlePress();
}}
underlayColor="#fff"
>
<Text style={styles.btnText}>Add Reminder</Text>
</TouchableHighlight>
<TouchableHighlight
style={{marginTop:20}}>
<Text/>
</TouchableHighlight>
</View>
</View>
</ScrollView>
);
}
}
When u use this.props.navigation.goBack(); those components not render again or not call any method that component so can use this.props.navigation.navigate('your_route_path');