How To Know Last Item of FlatList - javascript

I have a FlatList.
I want to add comma between items.
Currently working like this;
If there is only one item;
Mon,
If there are multiple items;
Mon, Tue, Wed,
My code;
<FlatList
data={job.schedule}
renderItem={({ item, index }) => (
<View style={[[Layout.center], {}]}>
<Text style={[[Fonts.textInterRegular12]]}>
{item.dayHuman.slice(0, 3)}{', '}
</Text>
</View>
)}
horizontal
keyExtractor={item => item.id}
extraData={this.state}
showsVerticalScrollIndicator={false}
/>
Above code has two issues.
If there is only one item, I don't want to add a comma.
E.g. Mon
If there are multiple items, I don't want to add a comma next to the last item.
E.g. Mon, Tue, Wed
How can I achieve this?

When working with ReactNative FlatList, you can use FlatList's ItemSeparatorComponent prop to render a component between each item, but not at the start or end of the list.
You can use FlatList's ListFooterComponent & ListHeaderComponent props to render some JSX or a component at the end or start of the list.
See diagram below.
If the above doesn't help and you just need to know that you are at the end of the list within a renderItem, you can check the index in the metadata provided to renderItem against the length of data.
const data = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];
export default function App() {
return (
<SafeAreaView>
<FlatList
data={data}
renderItem={({ item, index }) => {
const isEnd = index === data.length - 1;
return (
<View>
<Text>
{item}{isEnd && <Text>. </Text>}
</Text>
</View>
);
}}
horizontal
keyExtractor={(item) => item.id}
extraData={this.state}
showsVerticalScrollIndicator={false}
ItemSeparatorComponent={() => <Text>, </Text>}
ListFooterComponent={() => <Text>The End!</Text>}
/>
</SafeAreaView>
);
}
Snack

<FlatList
data={job.schedule}
renderItem={({ item, index }) => (
<View style={[[Layout.center], {}]}>
<Text style={[[Fonts.textInterRegular12]]}>
{item.dayHuman.slice(0, 3)}
{index !== job.schedule.length -1 && ', '}
</Text>
</View>
)}
horizontal
keyExtractor={item => item.id}
extraData={this.state}
showsVerticalScrollIndicator={false}
/>

I think you are looking for this
<FlatList
data={job.schedule}
renderItem={({ item, index }) => (
<View style={[[Layout.center], {}]}>
<Text style={[[Fonts.textInterRegular12]]}>
{item.dayHuman.slice(0, 3)}{index < job.schedule.length -1 ?', ':""}
</Text>
</View>
)}
horizontal
keyExtractor={item => item.id}
extraData={this.state}
showsVerticalScrollIndicator={false}
/>

Related

Beginners Problem with ReactNative FlatList

I'm pretty new to react native and have an issue that my data is not showing up in my view.
I can retrieve it from my server and save it in the data array.
When I want to go through it and create a flatlist it doesn't show up and I don't know why.
The console.log output shows that I have data in my array and also displayList is true at that point in time. Any help why this happens ?
return (
<View style={styles.container}>
<Button title="Retrieve Data" onPress={fetchData} />
<Text>before</Text>
{console.log(
`Size of Data: ${data.length} and displayList: ${displayList}`
) &&
displayList &&
data &&
data.map((item, i) => (
<FlatList
data={data}
renderItem={({ item }) => <Text>{item["name"].Value[0]}</Text>}
keyExtractor={(item) => item}
/>
))}
<Text>after</Text>
<StatusBar style="auto" />
</View>
);
}
By mapping over the flat list you are creating a new list for each item of data which I doubt it what you want to do.
The internals of render item have the map function in for you.
I think what you're looking for is...
return (
<View style={styles.container}>
<Button title="Retrieve Data" onPress={fetchData} />
<Text>before</Text>
<FlatList
data={data}
renderItem={({ item }) => <Text>{item["name"].Value[0]}</Text>}
keyExtractor={(item) => item.id.toString()}
/>
))}
<Text>after</Text>
<StatusBar style="auto" />
</View>
);
If you want to render something else if theres no data then you can use the ListEmptyComponent prop on the flat list.
Im also not sure what your data array looks like. But this may also be an issue. If this doesn't work please update your question with the full component and data structure.
try this, Don't have to iterate through map, the item is already containing the object for respective index.
return (
<View style={styles.container}>
<Button title="Retrieve Data" onPress={fetchData} />
<Text>before</Text>
{data.lenght()>0? <FlatList
data={data}
renderItem={({ item }) => <Text>{item["name"].Value[0]}</Text>}
keyExtractor={(item) => item}
/>:<Text>No DATA FOUND<Text>}
<Text>after</Text>
<StatusBar style="auto" />
</View>
);

React Native, error looping through an array (Failed child context type:)

I have the below code to loop through an array.
export default function App() {
const [x, setX] = useState([
{name:'a'},{name:'b'}
]);
return (
<View >
<FlatList
data={x}
renderItem={(item) => {
return <Text>{item.name}</Text>;
}}
/>
</View>
);
The above code gives below error
Warning: Failed child context type: Invalid child context `virtualizedCell.cellKey` of type `number` supplied to `CellRenderer`, expected `string`.
When I change
<FlatList
data={x}
renderItem={(item) => {
return <Text>{item.name}</Text>;
}}
/>
To
<FlatList
data={x}
renderItem={({item}) => {
return <Text>{item.name}</Text>;
}}
/>
The code is correct now and it works, see I changed (item) to ({item}) added curly braces .
Why is so ?
As you can see link document https://reactnative.dev/docs/flatlist.html
renderItem
renderItem({ item, index, separators });
item: (Object): The item from data being rendered.
index (number): The index corresponding to this item in the data array.
separators (Object)
highlight (Function)
unhighlight (Function)
updateProps (Function)
select (enum('leading', 'trailing'))
newProps (Object)
Example usage:
<FlatList
ItemSeparatorComponent={
Platform.OS !== 'android' &&
(({ highlighted }) => (
<View
style={[
style.separator,
highlighted && { marginLeft: 0 }
]}
/>
))
}
data={[{ title: 'Title Text', key: 'item1' }]}
renderItem={({ item, index, separators }) => (
<TouchableHighlight
key={item.key}
onPress={() => this._onPress(item)}
onShowUnderlay={separators.highlight}
onHideUnderlay={separators.unhighlight}>
<View style={{ backgroundColor: 'white' }}>
<Text>{item.title}</Text>
</View>
</TouchableHighlight>
)}
/>
you should use the key prop flour. try again with the code below
<FlatList
data={x}
renderItem={({ item, index }) => (
<Text key={index}>{item.name}</Text>
)}
keyExtractor={(item, index) => index.toString()}
/>
Because the FlatList returns item object in which their is your items or array to be render!
its like
{
items: {
{name:'a'},
{name:'b'}
}
}
so we have to go to item first by destructuring by {item} and then access the inner objects.
Hope it will make understanding !

How to create a FlatList

I want to create a FlatList, Grid List or a View off numColum={3} for my
{folderToDisplay.map((item) => {
return <Text key={item.id}>{item.value}</Text>;
})}
right now my text is a list row. How to make it a colum off 3?
Use FlatList with numColumns props.
<FlatList
data={folderToDisplay}
renderItem={({ item }) => <Text key={item.id}>{item.value}</Text>}
keyExtractor={item => item.id}
numColumns={3}
/>
https://reactnative.dev/docs/flatlist
numColumns
Multiple columns can only be rendered with horizontal={false}.
FlatList in React-Native
<FlatList
contentContainerStyle={{margin:4}}
horizontal={false}
numColumns={4}
data={this.state.categoryDataSource}
renderItem={(item) =>
return <Text key={item.id}>{item.value}</Text>;
}
keyExtractor={category => category.id}
/>

How do I alternate colors in Flat List (React Native)

Trying to alternate colors in React Natives Flatlist. I believe I need rowID or something similar to do it. This is what I've got so far:
let colors = ['#123456', '#654321', '#fdecba', '#abcdef'];
<View >
<FlatList style={{backgroundColor: colors[this.index % colors.length]}}
data={this.state.dataSource}
renderItem={({item}) => <Text style={styles.listStyle}>{item.title}, {item.releaseYear}</Text>}
keyExtractor={(item, index) => index}
/>
</View>
Any ideas?
The renderItem callback argument has a property index that allows you to access the row index for the current row:
<View >
<FlatList
data={this.state.dataSource}
keyExtractor={(item, index) => index}
renderItem={({item, index}) => (
<View style={{ backgroundColor: colors[index % colors.length] }}>
<Text style={styles.listStyle}>{item.title}, {item.releaseYear}</Text>
</View>
)}
/>
</View>

border bottom changing on press flatlist item in react native

i'm new in react native and i need your help
i want to give border-bottom to pressed item of horizontal flatlist and border-bottom of Previous item disappear,
now i can give border to new pressed item but i cant remove previous item border
how can i achive this?
enter image description here
these are my Category_style code
state = {
isModalVisible: false,
Index : 0
}
_toggleModal = (index) => {
this.setState({isModalVisible: !this.state.isModalVisible});
this.setState({Index : index});
}
renderProduct(item) {
return <Sub_Categories_FlatList_style name={item.title} icon={item.icon}/>
}
renderSeparator = () => (
<View
style={{
backgroundColor: '#d2d2d2',
height: 0.5,
}}
/>
)
render() {
const {title, index} = this.props;
return (
<View style={pStyles.container}>
<TouchableHighlight onPress={() => this._toggleModal(index)}
style={(index === this.state.Index) ? pStyles.border_bottom : pStyles.no_border_bottom}>
<Text style={pStyles.title}>{title}</Text>
</TouchableHighlight>
<Modal isVisible={this.state.isModalVisible} animationType={'slide'}>
<TouchableOpacity onPress={() => this._toggleModal(index)} style={pStyles.T_opacity}
activeOpacity={.7}>
<Image source={require('./../pictures/x_icon.png')}
style={pStyles.close_image}/>
</TouchableOpacity>
<View style={pStyles.in_modal_view}>
<Text style={pStyles.modal_header_text}>{title}</Text>
<FlatList
data={this.props.subCategory}
renderItem={({item}) => this.renderProduct(item)}
ItemSeparatorComponent={this.renderSeparator}
keyExtractor={(item, index) => index}/>
</View>
</Modal>
</View>
and these are my Category code
static navigationOptions = {
headerStyle: {
backgroundColor: '#4caf50'
},
headerTitle: <Text style={Category_in_style.headerTitleStyle}>Category</Text>
}
renderCategory(item, index) {
return <Category_style title={item.title} index={index} subCategory={item.sub_category}/>
}
renderProduct(item) {
return <Product_style image={item.imageUrl} title={item.title} price={item.price}/>
}
render() {
return (
<View style={{backgroundColor: 'white'}}>
<FlatList style={styles.first_flat}
horizontal
data={this.state.main_categories}
renderItem={({item, index})=> this.renderCategory(item, index)}
keyExtractor={(item, index) => index}/>
<PTRView style={{backgroundColor: '#f1f1f1'}}>
<FlatList style={[{marginTop: 10}, {marginBottom: 50}]}
data={this.state.articles}
renderItem={({item}) => this.renderProduct(item)}
keyExtractor={(item, index) => index}
numColumns={2}/>
</PTRView>
</View>
There may be multiple ways of doing this but I prefer having the parent decide which component is clicked.
So what I suggest is in your renderProduct the item object also has an index which you can pass to your Sub_Categories_FlatList_style and also pass a function to it which basically updates a variable whenever the item is clicked.
Then when you render the list item simply check if it's index matches the currently selected index and then style it accordingly.
Sorry if this seems a bit vague but I'm eyeballing this since I'm at work but I'll be more than happy to answer any follow ups.

Categories

Resources