Trouble limiting re-rendering to a single item in a FlatList (React Native)
The issue is that anytime I tap a ListItem (which adds or removes the ListItem's id from the selectedList state array which is used to highlight the selected items) the whole list (and every item in it) re-renders. I would like to re-render only the item that is selected in that moment.
I have (at least) 2 points of confusion with this. For one, this re-render happens whether or not I pass the selectedList array into the FlatList's extraData prop, and everything I'm reading is saying that the FlatList shouldn't know anything has changed unless I give it the extraData prop. In the example below I don't have the extraData prop shown because like I said, the behavior was the same for me.
The second point of confusion for me is that even if FlatList wants to re-render with each tap, what is the prescribed way to control whether the individual items re-render or not? I assume the reason why mine are re-rendering is because, since my Flatlist is re-rendering, it's calling my renderItem function for each item which is returning new components for each one. But it seems that people aren't using shouldComponentUpdate anymore now that hooks are around, so how could I compare new/old props to choose when to render? (also, where should I make this call? In the renderItem function, or inside the ListItem component itself?)
I feel like the answer lies somewhere between my two areas of confusion here. Please check out my example code below.
export default function ListScreen() {
const [selectedList, setSelectedList] = React.useState([])
const data = [
{id:0, name:'Bob', date: moment().format('MMM Do YYYY')},
{id:1, name:'George', date: moment().format('MMM Do YYYY')}
]
function itemSelected(id) {
const index = selectedList.indexOf(id)
if (index === -1) {
// if item isn't already selected, add id to list
setSelectedList([...selectedList, id])
} else {
// else if id is in list, remove id from array
setSelectedList(selectedList.filter(el => el !== id))
}
}
function renderItem({ item }) {
const selected = selectedList.includes(item.id)
return (
<ListItem
item={item}
onPress={() => itemSelected(item.id)}
selected={selected}
/>
)
}
return (
<View>
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={({id}) => id && id.toString()}
/>
</View>
)
}
const ListItem = ({item, onPress, selected}) => {
const {date, name} = item
console.log('Item rendering') // this always gets called twice, no matter which item I tap on.
return (
<TouchableRipple onPress={onPress}>
<View style={selected ? styles.selected : styles.unselected}>
<Text>{name}</Text>
<Text>{date}</Text>
</View>
</TouchableRipple>
)
}
from Recent Questions - Stack Overflow https://ift.tt/34t3OCz
https://ift.tt/eA8V8J
Comments
Post a Comment