When using a class ponent with a FlatList I know that to get a re-render you need to use extraData-{this.state}
I am using a functional ponent with Hooks. I have a state
const [selectedGuests, setSelectedGuests] = useState([]);
and a Flatlist
<FlatList
data={contactsData}
renderItem={renderItem}
extraData={selectedGuests}
keyExtractor={(item, index) => index.toString()}
>
but when I change the state's array nothing changes. Well, it works if I add an item but not when deleting an item from the array so I am assuming that the extraData is not working as I have it at the moment.
What I am trying to do is to change the background colour of an item in a FlatList to show that it was selected. It works if I add the item id to an array:
<View style={{ other style stuff then.. backgroundColor: selectedGuests.find(k => k === item.id) ? "#ffe5e5" : "#eee"}}
Then in the function called by clicking a button to select the item
const addToList = (guestIDnum) => {
const guestArray = selectedGuests;
guestArray.push(guestIDnum);
const mySortedList = guestArray.sort();
const sortedNoDupes = Array.from(new Set(mySortedList));
setSelectedGuests(sortedNoDupes);
}
Which works. Removing items is like so:
const removeFromList = (guestIDnum) => {
const guestArray = selectedGuests;
const itemIndex = guestArray.indexOf(guestIDnum);
if (itemIndex > -1) {
guestArray.splice(itemIndex, 1);
setSelectedGuests(guestArray);
}
}
While I can see in the console that items are being added and removed, the colour changes only when an item is added, or if I remove one item then select a new one the screen re-renders correctly.
When using a class ponent with a FlatList I know that to get a re-render you need to use extraData-{this.state}
I am using a functional ponent with Hooks. I have a state
const [selectedGuests, setSelectedGuests] = useState([]);
and a Flatlist
<FlatList
data={contactsData}
renderItem={renderItem}
extraData={selectedGuests}
keyExtractor={(item, index) => index.toString()}
>
but when I change the state's array nothing changes. Well, it works if I add an item but not when deleting an item from the array so I am assuming that the extraData is not working as I have it at the moment.
What I am trying to do is to change the background colour of an item in a FlatList to show that it was selected. It works if I add the item id to an array:
<View style={{ other style stuff then.. backgroundColor: selectedGuests.find(k => k === item.id) ? "#ffe5e5" : "#eee"}}
Then in the function called by clicking a button to select the item
const addToList = (guestIDnum) => {
const guestArray = selectedGuests;
guestArray.push(guestIDnum);
const mySortedList = guestArray.sort();
const sortedNoDupes = Array.from(new Set(mySortedList));
setSelectedGuests(sortedNoDupes);
}
Which works. Removing items is like so:
const removeFromList = (guestIDnum) => {
const guestArray = selectedGuests;
const itemIndex = guestArray.indexOf(guestIDnum);
if (itemIndex > -1) {
guestArray.splice(itemIndex, 1);
setSelectedGuests(guestArray);
}
}
While I can see in the console that items are being added and removed, the colour changes only when an item is added, or if I remove one item then select a new one the screen re-renders correctly.
Share Improve this question edited May 28, 2020 at 8:10 user11141611 asked May 27, 2020 at 20:04 Kelvin AitkenKelvin Aitken 4438 silver badges18 bronze badges1 Answer
Reset to default 8When you const guestArray = selectedGuests;
means you point guestArray
to selectedGuests
, so they are pointing to the same array (location). When deleting an item, you are actually manipulate selectedGuests
then call setSelectedGuests(guestArray);
, it will not re-render because the array location is not change (that are how React update state and re-render, shallowly pare object)
Try this:
const removeFromList = (guestIDnum) => {
// Clone guestArray
const guestArray = [...selectedGuests];
const itemIndex = guestArray.indexOf(guestIDnum);
if (itemIndex > -1) {
guestArray.splice(itemIndex, 1);
setSelectedGuests(guestArray);
}
}