FlatList is re-rendering items everytime screen is scrolled - react-native

I have a list of 300 items. I'm using FlatList to render the items.
ISSUE :
List items re-rendering when I scroll the screen. Even when I have wrapped the component in React.memo.
I tried to optimise the list by tweaking the windowSize, maxToRenderPerBatch but the issue still persist.
You can check the code in below sandbox link.
Thankyou in advance !
https://codesandbox.io/s/gracious-dhawan-i4d51h?file=/src/App.js
Below is the code snippet
const data = [
{
id: 1,
first_name: "Shaina",
last_name: "Osorio",
email: "sosorio0#a8.net"
},
{
id: 2,
first_name: "Ania",
last_name: "Cotilard",
email: "acotilard1#about.me"
},
{
id: 3,
first_name: "Hagen",
last_name: "Lisciandri",
email: "hlisciandri2#nature.com"
}
]
const isEqual = (prev, next) => {
return true;
};
const RenderItem = React.memo((props) => {
const { id, first_name, email } = props;
console.log("id >>> ", id);
return (
<View
style={{
padding: 5,
backgroundColor: "lightblue",
marginVertical: 3
}}
>
<Text>First Name : {first_name}</Text>
<Text>Email : {email}</Text>
</View>
);
}, isEqual);
function App() {
return (
<View style={{ flex: 1 }}>
<FlatList
data={data}
renderItem={({ item }) => (
<RenderItem
id={item.id}
first_name={item.first_name}
email={item.email}
/>
)}
initialNumToRender={15}
maxToRenderPerBatch={15}
keyExtractor={(item) => item.id}
/>
</View>
);
}
export default App;

In your example, you are logging inside your renderItem, so when a new element comes into the rendered area, it is logged. This happens when you scroll. But this doesn't mean that the whole list will be re-rendered. Just place a conosle.log directly in the component that hosts the list, and you'll see that it's only rendered once, unlike the renderItem, which is rendered every time a new item is created by a scroll.
const App = ()=> {
console.log("Entire List Rerendered");
return (
<View style={{ flex: 1 }}>
<FlatList
data={data}
renderItem={rendering}
initialNumToRender={5}
maxToRenderPerBatch={5}
keyExtractor={(item) => item.id}
/>
</View>
);
}
Flashlist might help, because it recycles renderItems and doesn't destroy them like Flatlist does. But you should test that better.
Also check out this attempt to visually explain your console logs.

Check out FlashList by Shopify they are saying that it is much more optimized than Flatlist. maybe it can meet your needs. no harm in trying: Click Here
import React from "react";
import { View, Text, StatusBar } from "react-native";
import { FlashList } from "#shopify/flash-list";
const DATA = [
{
title: "First Item",
},
{
title: "Second Item",
},
];
const MyList = () => {
return (
<FlashList
data={DATA}
renderItem={({ item }) => <Text>{item.title}</Text>}
estimatedItemSize={200}
/>
);
};

Related

Get position of individual Items in flatlist

I have flatlist horizontal like below
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad353abb28ba',
title: 'Fourth Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd291aa97f63',
title: 'Fifth Item',
},
{
id: '58694a0f-3da1-471f-bd961-145571e29d72',
title: 'Sixth Item',
},
];
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => {
const renderItem = ({ item }) => (
<Item title={item.title} />
);
return (
<SafeAreaView style={styles.container}>
<FlatList
horizontal
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
Whenever Item entered the viewport , I want to add animation to that element.I can get X and Y position of scroll with onScroll , now how do i get the positions of items to check if its in view port or if it went away from viewport...
Thank you.
Sorry for the late response. My pc has been super weird lately so when I encounter errors I have to second guess myself, and when nothing appears wrong, I second guess my pc (this time it was entirely me).
Here's my answer. I implemented the basic fade in/out [animation example][1] into the Item component. Whether it fades out or in is decided by the prop isViewable
// Item.js
const Item = (props) => {
const {
item:{title, isViewable}
} = props
/*
I copied and pasted the basic animation example from the react-native dev page
*/
const fadeAnim = useRef(new Animated.Value(1)).current;
const fadeIn = () => {
Animated.timing(fadeAnim, {
toValue: 1,
duration: 1000,
useNativeDriver:false
}).start();
};
const fadeOut = () => {
Animated.timing(fadeAnim, {
toValue: 0,
duration: 1500,
useNativeDriver:false
}).start();
};
/* end of animation example*/
// fade in/out base on if isViewable
if(isViewable || isViewable == 0)
fadeIn()
else
fadeOut()
const animation = {opacity:fadeAnim}
return (
//add animation to Animated.View
<Animated.View style={[style.itemContainer,animation]}>
<View style={style.item}>
<Text style={style.title}>{title}</Text>
</View>
</Animated.View>
);
}
Create a FlatListWrapper (to avoid the onViewableItemChange on fly error). By doing this, as long as you don't make changes to FlatListWrapper, you wont get the on the fly error
// FlatListWrapper.js
const FlatListWrapper = (props) => {
// useRef to avoid onViewableItemsChange on fly error
const viewabilityConfig = useRef({
// useRef to try to counter the view rerender thing
itemVisiblePercentThreshold:80
}).current;
// wrapped handleViewChange in useCallback to try to handle the onViewableItemsChange on fly error
const onViewChange = useCallback(props.onViewableItemsChanged,[])
return (
<View style={style.flatlistContainer}>
<FlatList
{...props}
horizontal={true}
onViewableItemsChanged={onViewChange}
/>
</View>
);
}
const style = StyleSheet.create({
flatlistContainer:{
borderWidth:1,
borderColor:'red',
width:'50%',
height:40
},
// main FlatList component
const FlatListAnimation = () => {
// store the indices of the viewableItmes
const [ viewableItemsIndices, setViewableItemsIndices ] = useState([]);
return (
<SafeAreaView style={style.container}>
<FlatListWrapper
horizontal={true}
//{/*give each data item an isViewable prop*/}
data={DATA.map((item,i)=>{
item.isViewable=viewableItemsIndices.find(ix=>ix == i)
return item
})}
renderItem={item=><Item {...item}/>}
keyExtractor={item => item.id}
onViewableItemsChanged={({viewableItems, changed})=>{
// set viewableItemIndices to the indices when view change
setViewableItemsIndices(viewableItems.map(item=>item.index))
}}
//{/*config that decides when an item is viewable*/}
viewabilityConfig={{itemVisiblePercentThreshold:80}}
extraData={viewableItemsIndices}
/>
{/* Extra stuff that just tells you what items should be visible*/}
<Text>Items that should be visible:</Text>
{viewableItemsIndices.map(i=><Text> {DATA[i].title}</Text>)}
</SafeAreaView>
);
}
const style = StyleSheet.create({
container:{
padding:10,
alignItems:'center'
},
flatlistContainer:{
borderWidth:1,
borderColor:'red',
width:'50%',
height:40
},
item:{
borderWidth:1,
padding:5,
},
itemContainer:{
padding:5,
}
})
By wrapping your FlatList in a separate file, you wont encounter the "onViewableItemsChange on the fly" error as long as you dont modify FlatListWrapper.js
[1]: https://reactnative.dev/docs/animated
Use onViewableItemsChanged this is called when the items in the flatlist changes.
const handleViewableItemsChanged = (viewableItems, changed) => {}
<Flatlist
...
onViewableItemsChanged={handleViewableItemsChanged}

Can't scroll absolute positioned FlatList when there is nothing behind it

What I'm trying to do:
Make a search bar and show the results in a flat list under the bar.
What I have:
I have a SearchBar and a FlatList, the FlatList needs to but in absolute position so it covers the content on the bottom of the search bar
The Problem:
The FlatList is covering the search bar when it's active and I can't scroll the list or select an item. What I noticed is that if i try to select an item or scroll the list when clicking where the SearchBar should be appearing, I can select and scroll the list.
What I need:
The FlatList to show under the SearchBar and be able to scroll it.
I could use top: 50 to show the FlatList under the SearchBar but it doesn'r seems good
Observations: I'm not that good at styles
import React, { Component } from 'react'
import { Text, View, StyleSheet, TouchableHighlight, FlatList } from 'react-native'
import {
Slider,
SearchBar,
ListItem,
} from 'react-native-elements'
export default class SearchForm extends Component {
state = {
pages: 1,
displayList: false,
itemsPerPage: 5,
}
componentDidMount = async () => {
const {
data = [],
itemsPerPage = 5,
} = this.props
await fetch('https://servicodados.ibge.gov.br/api/v1/localidades/estados', {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
})
.then(res => res.json())
.then(data => this.setState({
data: data,
displayData: data.slice(0, itemsPerPage)
}))
console.log(this.state.data.length)
}
updateSearch = search => {
const { data, itemsPerPage } = this.state
let s = search ? search.toLowerCase() : ''
this.setState({
displayData: data.filter(res => res.nome.toLowerCase().includes(s)).slice(0, itemsPerPage),
displayList: true,
search: search,
pages: 1,
})
if(this.flatListRef){
this.flatListRef.scrollToOffset({ animated: true, offset: 0 })
}
}
loadMore = () => {
const { pages, displayData, data, search, itemsPerPage } = this.state
const start = pages * itemsPerPage
let end = (pages + 1) * itemsPerPage
let s = search ? search.toLowerCase() : ''
const newData = data.filter(res => res.nome.toLowerCase().includes(s)).slice(start, end)
this.setState({
displayData: [...displayData, ...newData],
pages: pages + 1,
})
console.log(this.state.displayData.length)
}
selectItem = (value) => {
this.setState({
search: value,
displayList: false,
})
}
renderItem = ({ item, index }) => {
return (
<ListItem
style={styles.flatListItem}
containerStyle={styles.flatListItemCointainer}
key={index}
title={item.nome}
onPress={() => this.selectItem(item.nome)}
/>
);
}
render() {
const {
search,
displayData = [],
displayList,
} = this.state
return (
<View style={styles.container}>
<SearchBar
ref={search => { this.search = search }}
placeholder="Type Here..."
leftIcon={false}
noIcon
onChangeText={this.updateSearch}
value={search}
/>
{displayList && <FlatList
style={styles.flatList}
ref={ref => this.flatListRef = ref}
data={displayData}
keyExtractor={(item, index) => index.toString()}
renderItem={this.renderItem}
onEndReached={this.loadMore}
onEndReachedThreshold={0.5}
/>}
<TextInput
style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
onChangeText={(text) => this.setState({ text })}
value={this.state.text}
/>
<TextInput
style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
onChangeText={(text) => this.setState({ text })}
value={this.state.text}
/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
alignSelf: 'stretch',
backgroundColor: '#fff',
},
flatList: {
height: 200,
width: '100%',
position: 'absolute',
},
flatListItemCointainer: {
backgroundColor: 'rgba(0,0,0,1)'
}
})
Edit: I just change the code a little bit to show what I'm trying to do. Under the SearchBar will have other components (e.g. TextInput) and when the list is active, the list should go on top of that components.
With Shashin Bhayani answer, it's not going on top of things under it, only pushing it down.
This issue in android, to solve it :
import { FlatList } from 'react-native-gesture-handler';
Adding bottom: 0 solved my issue I am using zero because I want the Faltlist to end at the very bottom of the screen it can be any number.
Make sure there is no flex: 1 in flatlist style, contentContainerStyle or on the parent flatlist.
Try this and let me know this solved your issue or not.

React Native FlatList won't render

I'm trying to implement a FlatList in my React Native application, but no matter what I try the darn thing just won't render!
It's intended to be a horizontal list of images that a user can swipe through, but at this point I'd be happy to just get a list of text going.
Here's the relevant code. I can confirm that every render function is called.
render() {
const cameraScreenContent = this.state.hasAllPermissions;
const view = this.state.showGallery ? this.renderGallery() : this.renderCamera();
return (<View style={styles.container}>{view}</View>);
}
renderGallery() { //onPress={() => this.setState({showGallery: !this.state.showGallery})}
return (
<GalleryView style={styles.overlaycontainer} onPress={this.toggleView.bind(this)}>
</GalleryView>
);
}
render() {
console.log("LOG: GalleryView render function called");
console.log("FlatList data: " + this.state.testData.toString());
return(
<FlatList
data={this.state.testData}
keyExtractor={this._keyExtractor}
style={styles.container}
renderItem={
({item, index}) => {
this._renderImageView(item, index);
}
}
/>
);
}
}
_keyExtractor = (item, index) => index;
_renderImageView = (item, index) => {
console.log("LOG: renderItem: " + item);
return(
<Text style={{borderColor: "red", fontSize: 30, justifyContent: 'center', borderWidth: 5, flex: 1}}>{item}</Text>
);
}
//testData: ["item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8", "item9"]
I'm fairly confident this isn't some flex issue, but in case I missed something here's the relevant stylesheets too:
const styles = StyleSheet.create({
container: {
flex: 1
},
overlaycontainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between'
},
});
So, what I'm expecting to happen is to see a list of text items.
What's happening instead is I see a white screen with nothing on it.
Why is this list not rendering?
You can try replicating this if you want, define FlatList inside your return().
<View>
<FlatList
data={Items}
renderItem={this.renderItems}
enableEmptySections
keyExtractor={item => item.id}
ItemSeparatorComponent={this.renderSeparator}
/>
</View>
Then declare your Items inside constant(array of objects) outside your class like this,
const Items = [
{
id: FIRST,
title: 'item1',
},
{
id: SECOND,
title: 'item2',
},
{
id: THIRD,
title: 'item3',
},
// and so on......
];
After this get your items outside render by calling a function
onSelection = (item) => {
console.log(item.title)
}
renderItems = ({ item }) => {
return(
<TouchableOpacity
onPress={() => this.onSelection(item)}>
<View>
<Text>
{item.title}
</Text>
</View>
</TouchableOpacity>
)
}
Are you not missing the return on your renderItem?
render() {
console.log("LOG: GalleryView render function called");
console.log("FlatList data: " + this.state.testData.toString());
return(
<FlatList
data={this.state.testData}
keyExtractor={this._keyExtractor}
style={styles.container}
renderItem={
({item, index}) => {
return this._renderImageView(item, index);
}
}
/>
);
}
}

Highlight a selected item in React-Native FlatList

I put together a simple React-native application to gets data from a remote service, loads it in a FlatList. When a user taps on an item, it should be highlighted and selection should be retained. I am sure such a trivial operation should not be difficult. I am not sure what I am missing.
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
FlatList,
ActivityIndicator,
Image,
TouchableOpacity,
} from 'react-native';
export default class BasicFlatList extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
data: [],
page: 1,
seed: 1,
error: null,
refreshing: false,
selectedItem:'null',
};
}
componentDidMount() {
this.makeRemoteRequest();
}
makeRemoteRequest = () => {
const {page, seed} = this.state;
const url = `https://randomuser.me/api/?seed=${seed}&page=${page}&results=20`;
this.setState({loading: true});
fetch(url)
.then(res => res.json())
.then(res => {
this.setState({
data: page === 1 ? res.results : [...this.state.data, ...res.results],
error: res.error || null,
loading: false,
refreshing: false
});
})
.catch(error => {
this.setState({error, loading: false});
});
};
onPressAction = (rowItem) => {
console.log('ListItem was selected');
console.dir(rowItem);
this.setState({
selectedItem: rowItem.id.value
});
}
renderRow = (item) => {
const isSelectedUser = this.state.selectedItem === item.id.value;
console.log(`Rendered item - ${item.id.value} for ${isSelectedUser}`);
const viewStyle = isSelectedUser ? styles.selectedButton : styles.normalButton;
return(
<TouchableOpacity style={viewStyle} onPress={() => this.onPressAction(item)} underlayColor='#dddddd'>
<View style={styles.listItemContainer}>
<View>
<Image source={{ uri: item.picture.large}} style={styles.photo} />
</View>
<View style={{flexDirection: 'column'}}>
<View style={{flexDirection: 'row', alignItems: 'flex-start',}}>
{isSelectedUser ?
<Text style={styles.selectedText}>{item.name.first} {item.name.last}</Text>
: <Text style={styles.text}>{item.name.first} {item.name.last}</Text>
}
</View>
<View style={{flexDirection: 'row', alignItems: 'flex-start',}}>
<Text style={styles.text}>{item.email}</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
}
render() {
return(
<FlatList style={styles.container}
data={this.state.data}
renderItem={({ item }) => (
this.renderRow(item)
)}
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 50,
},
selectedButton: {
backgroundColor: 'lightgray',
},
normalButton: {
backgroundColor: 'white',
},
listItemContainer: {
flex: 1,
padding: 12,
flexDirection: 'row',
alignItems: 'flex-start',
},
text: {
marginLeft: 12,
fontSize: 16,
},
selectedText: {
marginLeft: 12,
fontSize: 20,
},
photo: {
height: 40,
width: 40,
borderRadius: 20,
},
});
When user taps on an item in the list, "onPress" method is invoked with the information on selected item. But the next step of highlight item in Flatlist does not happen. 'UnderlayColor' is of no help either.
Any help/advice will be much appreciated.
You can do something like:
For the renderItem, use something like a TouchableOpacity with an onPress event passing the index or id of the renderedItem;
Function to add the selected item to a state:
handleSelection = (id) => {
var selectedId = this.state.selectedId
if(selectedId === id)
this.setState({selectedItem: null})
else
this.setState({selectedItem: id})
}
handleSelectionMultiple = (id) => {
var selectedIds = [...this.state.selectedIds] // clone state
if(selectedIds.includes(id))
selectedIds = selectedIds.filter(_id => _id !== id)
else
selectedIds.push(id)
this.setState({selectedIds})
}
FlatList:
<FlatList
data={data}
extraData={
this.state.selectedId // for single item
this.state.selectedIds // for multiple items
}
renderItem={(item) =>
<TouchableOpacity
// for single item
onPress={() => this.handleSelection(item.id)}
style={item.id === this.state.selectedId ? styles.selected : null}
// for multiple items
onPress={() => this.handleSelectionMultiple(item.id)}
style={this.state.selectedIds.includes(item.id) ? styles.selected : null}
>
<Text>{item.name}</Text>
</TouchableOpacity>
}
/>
Make a style for the selected item and that's it!
In place of this.state.selectedItem and setting with/checking for a rowItem.id.value, I would recommend using a Map object with key:value pairs as shown in the RN FlatList docs example: https://facebook.github.io/react-native/docs/flatlist.html. Take a look at the js Map docs as well: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map.
The extraData prop recommended by #j.I-V will ensure re-rendering occurs when this.state.selected changes on selection.
Your onPressAction will obviously change a bit from example below depending on if you want to limit the number of selections at any given time or not allow user to toggle selection, etc.
Additionally, though not necessary by any means, I like to use another class or pure component for the renderItem component; ends up looking something like the following:
export default class BasicFlatList extends Component {
state = {
otherStateStuff: ...,
selected: (new Map(): Map<string, boolean>) //iterable object with string:boolean key:value pairs
}
onPressAction = (key: string) => {
this.setState((state) => {
//create new Map object, maintaining state immutability
const selected = new Map(state.selected);
//remove key if selected, add key if not selected
this.state.selected.has(key) ? selected.delete(key) : selected.set(key, !selected.get(key));
return {selected};
});
}
renderRow = (item) => {
return (
<RowItem
{...otherProps}
item={item}
onPressItem={this.onPressAction}
selected={!!this.state.selected.get(item.key)} />
);
}
render() {
return(
<FlatList style={styles.container}
data={this.state.data}
renderItem={({ item }) => (
this.renderRow(item)
)}
extraData={this.state}
/>
);
}
}
class RowItem extends Component {
render(){
//render styles and components conditionally using this.props.selected ? _ : _
return (
<TouchableOpacity onPress={this.props.onPressItem}>
...
</TouchableOpacity>
)
}
}
You should pass an extraData prop to your FlatList so that it will rerender your items based on your selection
Here :
<FlatList style={styles.container}
data={this.state.data}
extraData={this.state.selectedItem}
renderItem={({ item }) => (
this.renderRow(item)
)}
/>
Source : https://facebook.github.io/react-native/docs/flatlist
Make sure that everything your renderItem function depends on is passed as a prop (e.g. extraData) that is not === after updates, otherwise your UI may not update on changes
First
constructor() {
super();
this.state = {
selectedIds:[]
};
}
Second
handleSelectionMultiple = async (id) => {
var selectedIds = [...this.state.selectedIds] // clone state
if(selectedIds.includes(id))
selectedIds = selectedIds.filter(_id => _id !== id)
else
selectedIds.push(id)
await this.setState({selectedIds})
}
Third
<CheckBox
checked={this.state.selectedIds.includes(item.expense_detail_id) ? true : false}
onPress={()=>this.handleSelectionMultiple(item.expense_detail_id)}
/>
Finally i got the solution to my problem from the answer given by Maicon Gilton

Access section data from section items in react native SectionList

I need to access the information regarding the section (index, value) inside the renderItem in react-native SectionList. According to http://docs.w3cub.com/react_native/sectionlist/#renderitem section details can be passed via renderItem function. But in below code except the item all other values will be set to undefined. Is there any other possible way of doing it?
render(){
return(
<SectionList
sections={this.props.itemList}
renderItem={(item,section) => this._renderNewItem(item,section)}
renderSectionHeader={this._renderSectionHeader}
keyExtractor={(item) => item.id}
/>
)
}
_renderNewItem(item,section){
console.log(item, " ", section)
}
Sample data structure
renderItem prop passes a single parameter to the function. This parameter is an object includes item and section data.
renderItem: (info: { item: Item, index: number, section: SectionT,
separators: { highlight: () => void, unhighlight: () => void,
updateProps: (select: 'leading' | 'trailing', newProps: Object) =>
void, }, }) => ?React.Element
To get the section data you can use it like below
renderItem={({ item, section }) => this._renderNewItem(item,section)}
Update
Adding a sample example to demonstrate how it works. See it on snack.expo.io
import React, { Component } from 'react';
import { Text, View, StyleSheet, SectionList } from 'react-native';
import { Constants } from 'expo';
const data = [{key: 'New', data: [{name: 'Foo1'}, {name: 'Foo2'}]}, {key: 'Old', data: [{name:'Foo3'}, {name: 'Foo4'}]}];
export default class App extends Component {
_renderItem = ({item, section}) => (<Text>{`${item.name}(${section.key})`}</Text>)
_renderSectionHeader = ({section}) => {
return (
<View style={styles.sectionHeader}>
<Text style={styles.header}>{section.key}</Text>
</View>
)
}
render() {
return (
<View style={styles.container}>
<SectionList
sections={data}
renderItem={this._renderItem}
renderSectionHeader={this._renderSectionHeader}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
sectionHeader: {
height: 50,
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
paddingLeft: 10
},
header: {
fontSize: 20,
}
});
Output of this will look like attached image Link
https://i.stack.imgur.com/Y7CLF.png Output of this solution image.
https://pastebin.com/embed_js/7kYrk8kf Dummy JSON File URL Link for this Demo.
I used above mentioned JSON with Section List in following way with the help of #bennygenel code.
renderItem = ({ item, section }) => <Text>{`${item.title}`}</Text>;
renderSectionHeader = ({ section }) => {
return (
/* <View style={styles.sectionHeader}>
<Text style={styles.header}>{section.key}</Text>
</View> */
****Custom Header Component ****
<CellHeader title={section.title} />
);
};
renderSectionList = () => {
return (
<View>
<SectionList
sections={data1.results}
renderItem={this.renderItem}
renderSectionHeader={this.renderSectionHeader}
/>
</View>
);
};