So, i've one Flatlist that renders a list of movies, and I'm trying to when I click on it, moves me to a detail page, but it's not working.
Literally, nothing happens and doesn't get any errors on console
My FlatList:
<FlatList
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
horizontal
data={movies}
onPress={() => navigation.navigate('Details')}
renderItem={renderItem}
keyExtractor={(item) => item.id.toString()}
/>
My "renderitem" from flatlist:
const renderItem = ({ item }) => (
<RenderList url={item.poster_path} title={item.original_title} />
);
and that is the RenderList component who fits into the const "renderItem":
<View style={styles.view}>
<Image
style={{ width: 150, height: 220 }}
source={{ uri: 'https://image.tmdb.org/t/p/w500/' + props.url }}
/>
</View>
You should call onPress from a TouchableOpacity that loops for each item.
<FlatList
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
horizontal
data={movies}
onPress={() => navigation.navigate('Details')}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => {
return (
<TouchableOpacity onPress={() => navigation.navigate('Details')}>
<RenderList url={item.poster_path} title={item.original_title} />
</TouchableOpacity>
);
}}
/>
You should have the onPress on each of the list item, not on the Flatlist
<FlatList
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
horizontal
data={movies}
renderItem={renderItem}
keyExtractor={(item) => item.id.toString()}
/>
const renderItem = ({ item }) => {
return (
<TouchableOpacity onPress={() => navigation.navigate('Details')}>
<RenderList url={item.poster_path} title={item.original_title} />
</TouchableOpacity>
);
}
Related
I am using flatlist for show user input notes in my app. But Flat List is not render any item that i entered. I used static list for testing and it works correctly. but when i enter a text through textinput it is not showing.
const addToDoHandler = () => {
if(userInput == ''){
return;
}
const newTodo = {
id: Math.floor(Math.random() * 1000),
text: userInput,
completed: false,
};
const newTodos = [...todos, newTodo];
setTodos(newTodos);
//clear user input
setUserInput('');
};
const renderItem = ( {item} ) => {
<View style={{backgroundColor:'#6b4d87', marginVertical: 10, flexDirection:'row', alignItems:'center', justifyContent:'space-between', height:60, width:'95%', borderRadius:10 }}>
<View>
<Text style={{color:'black', fontSize:20, fontWeight:'bold'}}>{item.text}</Text>
</View>
<TouchableOpacity onPress={() => deleteHandler(item.id)}>
<TrashIcon size={35} name="trash" style={{color:'#eff9f0'}} />
</TouchableOpacity>
</View>
};
return (
<SafeAreaView style={styles.root}>
<View style={styles.txtInputView}>
<TextInput
value={userInput}
onChangeText={text => setUserInput(text)}
style={styles.textInput}
placeholder={"Enter Your Note..."}
/>
<TouchableOpacity style={styles.addButton} onPress={addToDoHandler}>
<PlusSign size={35} name="add-sharp" style={styles.plusIcon}/>
</TouchableOpacity>
</View>
<View style={{alignItems:'center'}}>
<FlatList
data={todos}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</View>
</SafeAreaView>
);
You need to return the components from renderItem.
Change it to:
const renderItem = ( {item} ) => (
<View style={{backgroundColor:'#6b4d87', marginVertical: 10, flexDirection:'row', alignItems:'center', justifyContent:'space-between', height:60, width:'95%', borderRadius:10 }}>
<View>
<Text style={{color:'black', fontSize:20, fontWeight:'bold'}}>{item.text}</Text>
</View>
<TouchableOpacity onPress={() => deleteHandler(item.id)}>
<TrashIcon size={35} name="trash" style={{color:'#eff9f0'}} />
</TouchableOpacity>
</View>
);
I want to show this data in FlatList but it shows only whitescreen:
const [datas,setDatas] = useState([
{
name:'dhinesh',
phone:'9888888888',
email:'asdasd#gmail.com',
salary:'50000',
position:'ww'
},
{
name:'ramesh',
phone:'93388888',
email:'jhjj#gmail.com',
salary:'90000',
position:'sw'
}
]);
This is the code i used :
<FlatList
data={datas}
keyExtractor={(item, index) => index.toString()}
renderItem={({item}) => {
<View>
<Text>{item.name}</Text>
<Text>{item.phone}</Text>
<Text>{item.email}</Text>
<Text>{item.salary}</Text>
<Text>{item.position}</Text>
</View>
}}
/>
Please give me a solution
Add return in your view
renderItem={({item}) => {
return (
<View>
<Text>{item.name}</Text>
<Text>{item.phone}</Text>
<Text>{item.email}</Text>
<Text>{item.salary}</Text>
<Text>{item.position}</Text>
</View>
)
}}
I'm new in react-native. On one of my screen I'm using flatlist on 4 places but the last flatlist which is displaying at the bottom of screen is not scrolling so I add the scrollView then its working fine but displaying me that error
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation because it can break windowing and other functionality - use another VirtualizedList-backed container instead.
code
const Header = () => {
return (
<View>
<SafeAreaView>
<View style={styles.sellersheaderWrapper}>
<View style={styles.sellersheaderTitle}>
<Text style={styles.sellersheaderTitleText}>
Featured Sellers
</Text>
</View>
<View>
{
isFeatureSeller == '' ?
<View style={[styles.noSpecialOfferCard, {paddingVertical:hp('2%')}]} >
<Text style={[styles.noSpecialOfferCardText, {fontSize:hp('2%')}]}>Currently, No Feature Sellers</Text>
</View>
:
<View>
<FlatList
data={isFeatureSeller}
renderItem={renderCategoryItem}
keyExtractor={item => item.id}
horizontal={true}
showsHorizontalScrollIndicator={false}
/>
</View>
}
</View>
</View>
</SafeAreaView>
<View style={styles.searchWrapper}>
<View style={styles.dobregisterFormWrapperText}>
<TextInput
style={styles.dobregisterInputStyleText}
value={search}
onChangeText={(text) => searchFilterFunction(text)}
onClear={(text) => searchFilterFunction('')}
placeholder="Search ..."
/>
<View>
<SearchIconSvg />
</View>
</View>
</View>
</View>
);
};
const Footer = () => {
return (
<View>
<View style={styles.specialOfferCardWrapper}>
<View style={styles.specialOfferCardTextWrapper}>
<Text style={styles.specialOfferCardText}>Special Offer Cards</Text>
</View>
{isSpecialCards == '' ? (
<View style={styles.noSpecialOfferCard}>
<Text style={styles.noSpecialOfferCardText}>
No Special Offer cards
</Text>
</View>
) : (
<FlatList
data={isSpecialCards}
renderItem={renderCards}
keyExtractor={(item, index) => index.toString()}
horizontal={true}
showsHorizontalScrollIndicator={false}
style={styles.specialCards}
/>
)}
<View
style={[
styles.specialOfferCardTextWrapper,
{paddingBottom: isFeatureSeller == '' ? hp('17%') :hp('10%') },
]}>
<Text style={styles.specialOfferCardText}>Cards</Text>
<FlatList
data={isCard}
renderItem={renderNormalCards}
keyExtractor={item => item.id}
showsVerticalScrollIndicator={false}
scrollEnable={true}
/>
</View>
</View>
</View>
);
};
const MainData = () => {
return(
<View>
{search == '' ? (
<ScrollView>
<View >
<Header />
<Footer />
</View>
</ScrollView>
) : (
<View >
<FlatList
data={filteredDataSource}
renderItem={renderCategoryItemSearch}
keyExtractor={(item, index) => index.toString()}
ListHeaderComponent={Header}
/>
</View>
)}
</View>
)
}
return (
<View style={styles.container}>
{
loading == true ?
<View style={{marginVertical:hp('45%')}} >
<ActivityIndicator size="large" color={colors.primary} />
</View>
:
<MainData/>
}
<View style={styles.bottomNavWrapper}>
<TouchableOpacity
style={styles.storeWrapper}
onPress={() => navigation.navigate('BuyerDashboard')}>
<View style={styles.storeIcon}>
<DashboardReverseSvg />
</View>
</TouchableOpacity>
<View style={styles.dashboardWrapper}>
<View style={styles.dashboardIcon}>
<BuyerStoreReverseSvg />
</View>
<View style={styles.dashboardText}>
<Text style={styles.dashboardTextfont}>Storefront</Text>
</View>
</View>
</View>
</View>
);
};
export default Store;
I want to scroll at here.
<ScrollView>
<View >
<Header />
<Footer />
</View>
</ScrollView>
You can use nestedScrollEnabled prop on your FlatList component
https://reactnative.dev/docs/scrollview#nestedscrollenabled
I am trying to generate unique keys for some <TouchableOpacity> components that I would like to pass in onPress but it's not picking up the key variable.
const options = ["pic1","pic2","pic2"];
export default function ColourScreen() {
const handlePress = (key) => {
...do something wity key...
}
return (
<View>
<TouchableOpacity onPress={key => handlePress(key)}>
<Image
style={styles.icon}
source={require('../../../assets/icons/icon_1.jpg')}
/>
</TouchableOpacity>
<TouchableOpacity onPress={key => handlePress(key)}>
<Image
style={styles.icon}
source={require('../../../assets/icons/icon_2.jpg')}
/>
</TouchableOpacity>
<TouchableOpacity onPress={key => handlePress(key)}>
<Image
style={styles.icon}
source={require('../../../assets/icons/icon_3.jpg')}
/>
</TouchableOpacity>
</View>
)
}
I've tried manually setting it like:
<TouchableOpacity
key = {1}
onPress={key => handlePress(key)}>
<Image
style={styles.icon}
source={require('../../../assets/icons/icon_1.jpg')}
/>
</TouchableOpacity>
or:
{options.map((option, key) =>
<TouchableOpacity
key = {key}
onPress={() => handlePress(key)}>
<Image
style={styles.icon}
source={require('../../../assets/icons/icon_1.jpg')}
/>
</TouchableOpacity>, ...
)}
But this just creates multiple components.
How can I successfully do this?
You could take the key and map it to your icon.
const icons = [
require(`../../../assets/icons/icon_1.jpg`),
reqiuire(`../../../assets/icons/icon_2.jpg`),
require(`../../../assets/icons/icon_3.jpg`),
require(`../../../assets/icons/icon_4.jpg`),
]
{options.map((option, key) =>
<TouchableOpacity
key = {key}
onPress={() => handlePress(key)}>
<Image
style={styles.icon}
source={icons[key]}
/>
</TouchableOpacity>
)}
Sometimes when my data do not have unique id I use this approach with lodash
import { map, uniqueId } from 'lodash'
{map(someArray, () => (
<React.Fragment key={uniqueId()}>
<TextButton />
</React.Fragment>
))}
Just simply, do this.
<TouchableOpacity
onPress={() => yourFunctionName(1)}
>
your text or image goes here
<TouchableOpacity />
const yourFunctionName = (id) => {
console.log(id);
}
I have a array of data which I render in flatlist in React-Native. On pressing one of the items I want it to fade away, but instead all items on the flatlist get animated and not just the one that I pressed on.
constructor(props){
super(props);
this.state = { fadeAnim: new Animated.Value(1) }
onPressButtonnotdelivered(item) {
//Alert.alert(item.name)
const animations = [
Animated.timing(this.state.fadeAnim, {
toValue: 0,
duration: 500
}),
];
Animated.sequence(animations).start()
}
render() {
return (
<View>
<FlatList
data={this.state.data}
extraData={this.state}
keyExtractor={item => item.id}
renderItem={({ item, index }) => {
return (
<Animated.View key={index} style={[styles.animatedview, {opacity: this.state.fadeAnim}]}>
<View>
<View style={[styles.button, {backgroundColor: '#E94F64'}]}>
<TouchableOpacity style={styles.buttonview}
onPress={() => {this.onPressButtonnotdelivered(item)}}>
<View style={styles.btnIcon}>
<Icon name="block" size={30} />
<Text>Not delivered</Text>
</View>
</TouchableOpacity>
</View>
</View>
</Animated.View>
);
}}
/>
</View>
);
}
You need to add one more state to your component say indexToAnimate and set it to null.
Then put one condition in style of <Animated.View>
<Animated.View
key={index}
style={[
styles.animatedview,
{
opacity:
index == this.state.indexToAnimate
? this.state.fadeAnim
: "whatever your static value is..(in integer)"
}
]}
/>
and set indexToAnimate state on onPress method of <TouchableOpacity>
<TouchableOpacity
style={styles.buttonview}
onPress={() => {
this.setState({ indexToAnimate: index }, () => this.onPressButtonnotdelivered(item));
}}
>
<View style={styles.btnIcon}>
<Icon name="block" size={30} />
<Text>Not delivered</Text>
</View>
</TouchableOpacity>
What if you add a conditional render to the renderItem like:
renderItem={({ item, index }) => {
if (index === 'id')
return(<Animated.View> ... </Animated.View>);
else
return(<View> ... </View>);
}