I need to use slice() method in my FlatList data but when I use it like below it doesn't work.
<FlatList data={userBookings} keyExtractor={item => item.id} renderItem={itemData => (
<Text style={styles.text}>{itemData.item.id.slice(3)}</Text>
.
.
.
)
}
/>
how can I solve this?
I think first mistake is not to use curly brackets for callback data.
Secondly you need to specify the first and last index for the .slice method
You can find the answer down below.
<FlatList
data={userBookings}
keyExtractor={item => item.id}
renderItem={({itemData,index}) => (
<Text style={styles.text}
{itemData.item.id.slice(0,3)}
</Text>
)}
/>
Related
I am trying to use the current index in ItemSeparatorComponent as shown below, however index is always empty and never returns a value, but item is successfully populated. I'd really appreciate it if anyone can point out what I'm doing wrong here?
<FlatList
numColumns={1}
data={messages}
keyExtractor={(item) => item.id.toString()}
renderItem={({item}) => <OFChatBubble message={item} />}
ItemSeparatorComponent={(item, index) => (
<DateSeparator item={item} index={index} />
)}
/>
To debug correctly you can try to add a debugger like this
ItemSeparatorComponent={(item, index) => {
debugger
return (
<DateSeparator item={item} index={index} />
)
}}
Open Chrome with the source tab opened to figure out the format of data={messages}
I'm pretty sure you just forgot the { }around the params in the arrow function you passed to ItemSeparatorComponent
The code should be:
ItemSeparatorComponent={({item, index}) => (
<DateSeparator item={item} index={index} />
)}
Edit:
I was wrong ItemSeparatorComponent does not get the same props as renderItem. It gets highlighted:boolean, leadingItem:<an object from the data you pass in> but you still need to use { } in order to get them
I you put an Algolia connected component in a header of a FlatList it's as if it enters an infinite loop of queries. The connectInfiniteHits runs constantly.
This is really annoying if you like to put some simple filters in the headers of a list of hits.
My setup is like this:
I have a FlatList that is wrapped by the connectInfiniteHits HOC.
The ListHeaderComponent contains a component this is wrapped by the connectRefinementList HOC. The same problem occurs with a connectSearchBox HOC.
Has anyone seen this and found a solution?
I manage to make it work with those lines:
const RefinementList = connectRefinementList(({ items, refine }) => (
<View>
{items.map(item => (
<TouchableOpacity key={item.label} onPress={() => refine(item.value)}>
<Text style={{ fontWeight: item.isRefined ? '600' : 'normal' }}>
{item.label}
</Text>
</TouchableOpacity>
))}
</View>
));
const InfiniteHits = connectInfiniteHits(({ hits, hasMore, refine }) => (
<FlatList
data={hits}
keyExtractor={item => item.objectID}
onEndReached={() => hasMore && refine()}
ListHeaderComponent={<RefinementList attribute="brand" />}
renderItem={({ item }) => (
<View>
<Text>{JSON.stringify(item).slice(0, 100)}</Text>
</View>
)}
/>
));
Note that I'm not using the function version which indeed breaks.
I was using...
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <Text>{item.username} {item.name}</Text>}
keyExtractor={({id}, index) => id}
/>
...to render two texts in React Native but now I've got an uri in my json...
How do I render the image in an IM style (thumbnail, username and name)?
Add a renderItem method and then put everything you need in there. Once you make the renderItem method you can throw it into your FlatList.
renderItem({ item }) {
return (
<View>
<Image
source={{uri: item.uri}}
/>
<Text>
{item.username}
</Text>
<Text>
{item.name}
</Text>
</View>
);
}
Then use the method inside the FlatList (the .bind makes sure it stays in the right context)
<FlatList
data={this.state.dataSource}
renderItem={this.renderItem.bind(this)}
keyExtractor={({id}, index) => id}
/>
You can build a component that takes your fields as its props, containing multiple Texts and an Image using your uri as the source. Style this like you would any other component, and then pass that component into renderItem.
You can embed the component immediately to the renderItem like this if the flatlist item is not complicated ( has a lot of component )
<FlatList
data={this.state.dataSource}
renderItem={({item}) => {
<View>
<Image source={{uri: item.uri.image}}/>
<Text>{item.userName}</Text>
<Text>{item.name}</Text>
</View>
}}
keyExtractor={(i) => i.toString()}
/>
I'm trying to make something like this:
The problem: The project was built with immutablejs and according to React Native Docs, I can't use FlatList thus I can't use numColumns props feature of that component.
AFAIK, my only choice is to use VirtualizedList as the docs points out, but I can't figure out how to display the cells as a grid as shown above.
I've already tried to add style props in both cell and view wrapper, but none of the code used to align the cells, like the picture I posted, is ignored. In fact it was showing perfect when I was using ScrollView, but due the HUGE lag I'm moving the code to VirtualizedList.
Any help? Anything would be welcome, I already digged a lot on Google but I can't find anything about this.
Some sample code:
<View>
<VirtualizedList
data={props.schedules}
getItem={(data, index) => data.get(index)}
getItemCount={(data) => data.size}
keyExtractor={(item, index) => index.toString()}
CellRendererComponent={({children, item}) => {
return (
<View style={{any flexbox code gets ignored here}}>
{children}
</View>
)}}
renderItem={({ item, index }) => (
<Text style={{also here}} key={index}>{item.get('schedule')}</Text>
)}
/>
</View>
Answering my own question:
I got it working by copying the FlatList.js source code from react-native repo.
Here's an example code:
<VirtualizedList
data={props.schedules}
getItem={(data, index) => {
let items = []
for (let i = 0; i < 4; i++) {
const item = data.get(index * 4 + i)
item && items.push(item)
}
return items
}}
getItemCount={(data) => data.size}
keyExtractor={(item, index) => index.toString()}
renderItem={({item, index}) => {
return (
<View key={index} style={{flexDirection: 'row'}}>
{item.map((elem, i) => (
<View key={i}>
<Text key={i}>{elem.get('horario')}</Text>
</View>
))}
</View>
)
}}
/>
The number 4 is for the number of columns. The key parts are in the getItem and adding flexDirection: 'row' at renderItem in the View component.
If I enclose the flatlist in a View then my onEndReached triggers infinitely if I remove the enclosing View onEndReached is not triggered at all.
render() {
return (
<Root>
<Container>
<Content>
<View>
{this.state.listView && (
<FlatList
data={this.state.variants}
keyExtractor={this._keyExtractor}
onEndReachedThreshold={0.5}
onEndReached={({ distanceFromEnd }) => {
console.log(
"on end reached ",
distanceFromEnd
);
this.loadMore();
}}
numColumns={1}
renderItem={({ item, index }) => (
<CatalogRow
item={item}
in_wishlist={this.state.in_wishlist}
toggleWishlist={() =>
this.toggleWishlist(item.title)
}
listView={this.state.listView}
/>
)}
/>
)}
</View>
</Content>
</Container>
</Root>
);
}
And my distanceFromEnd takes values like 0 , 960,1200 when it is trigerred. What does it indicate?
I'm using react-native 0.47.2
I have same problem with react-native 0.50.3
<Flatlist> must not be used in a <ScrollView> if you want to use onEndReached because Flatlist can not found the height.
Use a <View> instead
It was because of the enclosing <Content> tag. Sometimes embedding react-native tags with native-base tags causes such issues. I replaced the content and container tag with View tags and now it works fine.
I have same problem with RN 0.52
That look like because Flatlist can not found the heigh. So he can not find the end of list.
Fix by wrap your flatlist by a View with flex=1
<View style={{flex: 1}} > <Flatlist /> <View>
I would use it like this:
handleMore = () => {
// fetch more here
};
<FlatList
onEndReached={this.handleMore}
/>