Hi I'm working on Flatlist.
The problem is as shown in picture&code below eventhough the DATA hasn't changed FlatList Rerenders.
const Item = ({ id, name, number }) => (//id is n'th device
<View onLayout={ console.log("FLATLIST CREATED | Render Count="+ renderCount++ +JSON.stringify(DATA,null,2))} style={[{ flex: 1, backgroundColor: "gray", width: "100%" }]}>
<Text>{id}</Text>
</View>
);
const renderItem = ({ item }) => (
<Item id={item.id} name={item.name} number={item.number} />
);
<FlatList
data={DATA}//<----- DATA DON'T CHANGE Look At the console image
renderItem={renderItem}
keyExtractor={item => item.id}
style={{}}
ItemSeparatorComponent={ItemSeparator}
/>
Related
I have FlatList with 2 colums, and i want place FooterElement in row
export const HabitScreen = ({navigation}) => {
return (
<View style={{marginTop: 40}}>
<MyPlansTitle navigation={navigation}/>
<GeneralView>
<SubTitle text="Привычки"/>
<FlatList data={[0,1,2]}
extraData={[3]}
numColumns={2}
columnWrapperStyle={style.row}
showsVerticalScrollIndicator={false}
renderItem={({item}) => (<HabitItem/>)}
ListFooterComponent={<HabitAddItem />}
/>
</GeneralView>
</View>
)}
how to do it?
Image Flatlist
add one more element to the data,
renderItem={({item, index}) => {
if (index+1 == data.length){
return <Text>Footer</Text>
}
return <Text>{item}</Text>
}}
I wanna achieve this effect: when i will press icon item will be added to favourite list and when i press again item will be deleted from favourite list but without rerender all of items from flatlist ( only rerender 1 item ). Now when i press icon all items from the list are rerender. Whats wrong? Items and list of favourite items come from api. They are two arrays of objects. I put id favourite items to array. When id of object is in array you can delete or add to favourite.
snippet of code:
const [fav, setFav] = useState([]); // array of favourites id
const SingleItem = React.memo(({ item, navigation }) => {
return(
<TouchableWithoutFeedback onPress={() => navigation.navigate("xxx", {
id: item.id,
})}>
<View style={styles.singleItemContainer}>
<View style={styles.imageContainer}>
<SliderBox images={images}
ImageComponent={ImageBackground}
ImageComponentStyle={{ width: '90%', marginTop: 10,}}
imageStyle={{borderRadius: 12}}
>
{ route.params?.isLogged &&
<View style={styles.heartIcon}>
<IconFontAwesome name={fav.includes(item.id) ? "paw" : "paw-outline"}
size={30}
color={fav.includes(item.id) ? "red" : "white"}
onPress={() => {
if(fav.includes(item.id)){ // is favourite and delete from favourite
deleteFavourite(item.id)
setFav(fav.filter(el => el != item.id))
}
else{ // add to favourite
addFavourite(item.id)
setFav([item.id, ...fav])
}
}}/>
</View>
}
</SliderBox>
</View>
</View>
</TouchableWithoutFeedback>
)});
const renderItem = ({ item }) => {
return(
<SingleItem
item={item}
navigation={navigation}
/>
);}
return (
<View style={styles.screen}>
<FlatList
data={data}
initialNumToRender={12}
renderItem={renderItem}
keyExtractor={(item) => item.id}
onEndReachedThreshold = {0.2}
onEndReached = {fetchData}
/>
</View>
);
};
I have a FlatList with TouchableOpacity items. When I try to select an item, the list scrolls to top.
This is the Collapsible content;
const setBrandSelected = index => {
var temp = JSON.parse(JSON.stringify(tempFilterOptions));
temp[0].enums[index].selected = !temp[0].enums[index].selected;
setTempFilterOptions(temp);
};
const FilterOptionBrand = () => {
const RenderBrand = ({ item, index }) => {
return (
<TouchableOpacity onPress={setBrandSelected.bind(null, index)}>
{item.selected && (
<View style={[styles.brandImage, styles.selectedBrandImage]}>
<Icon iconName={iconNames.Tick} />
</View>
)}
<FastImage source={{ uri: item.logo }} style={styles.brandImage} resizeMode={FastImage.resizeMode.contain} />
<Text style={styles.brandName}>{item.name}</Text>
</TouchableOpacity>
);
};
const BrandSeparator = () => <View style={styles.brandSeparator} />;
return (
<View style={styles.filterBrandMainContainer}>
<View style={styles.searchBrandContainer}>
<View style={styles.magnifyingGlassWrapper}>
<Icon iconName={iconNames.MagnifyingGlass} />
</View>
<TextInput style={styles.searchBrandInput} placeholder={searchBrandText} />
</View>
<FlatList
horizontal={true}
showsHorizontalScrollIndicator={false}
keyExtractor={(item, index) => String(item.id)}
style={styles.collapsibleContainer}
data={tempFilterOptions[0].enums}
renderItem={RenderBrand}
ItemSeparatorComponent={BrandSeparator}
></FlatList>
</View>
);
};
If you somehow stumble upon this question. The answer is wherever the problem occurs be it Header be it Footer. You should call the component function and not directly just type the function.
const Header = () => <View />
Correct usage;
ListHeaderComponent={Header()}
Incorrect usage;
ListHeaderComponent={Header}
I've just started learning react native and I want to make a splash screen that contains a slider with dots. But when I scroll the scrollview the active dot doesn't change properly. My slider component is like below
export default function Slider() {
const [active, setActive] = useState(0);
const onChange = ({ nativeEvent }) => {
const active = Math.floor(
nativeEvent.contentOffset.x / nativeEvent.layoutMeasurement.width
);
setActive({ active });
console.log(active);
};
return (
<View style={styles.container}>
<ScrollView
onMomentumScrollEnd={onChange}
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
>
{dummyData.map((item, index) => {
return (
<SliderItem
key={index}
title={item.title}
image={item.url}
description={item.description}
/>
);
})}
</ScrollView>
<View style={styles.dotView}>
{dummyData.map((k, i) => (
<View
key={i}
style={{
backgroundColor: i === active ? "red" : "blue", // My problem is here
height: 10,
width: 10,
margin: 8,
borderRadius: 6,
}}
/>
))}
</View>
</View>
);
}
Change setActive({ active }); to setActive(active);
renderItemTop ({item}) {
return (
<TouchableOpacity
onPress={()=>this.props.navigation.navigate('DetailUpMovie')}
>
<Card
containerStyle={stylesTop.ImageCardStyle}
image={{ uri: `${BASE_IMAGE_URL}original${item.poster_path}` }}
imageStyle={{ width: CardWidthTop, height: CardHeightTop }}
imageProps={{ borderRadius: 15, resizeMode:'stretch' }}
/>
</TouchableOpacity>
);
}
render () {
const { data } = this.state;
return (
<View style={stylesTop.ViewTopstyle}>
<View style={stylesTop.InnerViewstyle}>
<Text style={stylesTop.TitleTopStyle}>Top Rated Movie</Text>
<Button
buttonStyle={stylesTop.btnStyle}
title='More'
titleStyle={stylesTop.btnTitleStyle}
type='clear'
/>
</View>
<FlatList
data={data}
renderItem={this.renderItemTop}
keyExtractor={item => item.id}
showsHorizontalScrollIndicator={false}
horizontal={true}
marginTop={5}
marginLeft={10}
marginRight={10}
marginBottom={5}
/>
</View>
);
}
this is where i want navigate to other screen in renderitem fuction but when i press on the item to navigate o got error tis.props.navigation.navigate undefined is not an object in another class i make all stack and bottomnavigator
please help
You can pass the navigation prop to your custom component via something like this:
You just need to pass the navigation prop to function to access the navigation action
const MyComponent = props => {
const { item, navigation } = props
return (
<TouchableOpacity
onPress={() => navigation.navigate('DetailUpMovie')}
>
<Card
containerStyle={stylesTop.ImageCardStyle}
image={{ uri: `${BASE_IMAGE_URL}original${item.poster_path}` }}
imageStyle={{ width: CardWidthTop, height: CardHeightTop }}
imageProps={{ borderRadius: 15, resizeMode:'stretch' }}
/>
</TouchableOpacity>
);
}
...
<FlatList
data={data}
renderItem={({item}) => (
<MyComponent item={item} navigation={this.props.navigation} />
)}
keyExtractor={item => item.id}
showsHorizontalScrollIndicator={false}
horizontal={true}
marginTop={5}
marginLeft={10}
marginRight={10}
marginBottom={5}
/>