react-native-calendars
react-native-calendars copied to clipboard
`Agenda` list Items incorrectly rendering on update
Hello -- I think I found a bug in the AgendaList
due to the current key extraction.
When I navigate back in the agenda, e.g. from a Monday to Sunday, and if both of those days have arrays of events, the FlatList isn't rendering the correct item. Instead, an item previously rendered gets used. I'm pretty sure this is because of the string coercion of the indices used in the current key extraction:
https://github.com/wix/react-native-calendars/blob/74bc7fe05ed3883d3d8cbd56e3cd5a565543c385/src/agenda/reservation-list/index.tsx#L261:
keyExtractor = (_item: DayAgenda, index: number) => String(index);
this seems to me like a pretty good example of the index-key anti pattern described here: https://robinpokorny.medium.com/index-as-a-key-is-an-anti-pattern-e0349aece318
This seems straightforward to fix, by at least exposing a keyExtractor
prop to the AgendaList
.
I'll put together a minimal reproduction of this when I get the time.
Easiest way to reproduce is to load the agenda example and add
showOnlySelectedDayItems={true}
@Inbal-Tish
@JacobJaffe I've added this pr in the meantime: https://github.com/wix/react-native-calendars/pull/1792
Hi @eladgel ! Thank you for the reproduction. I've opened a new PR that addresses this + other issues with the Agenda
not accepting generic items at: #1794.
@eladgel @JacobJaffe Hi guys. Thank you for opening the issue and PRs - much appreciated! I added a fix to move things faster. You can follow this #1795
^Hi there I have found a potential solution to this issue: can check #1890
Dear Zeen, Regarding your issue above, check .../agenda/reservation-list/index.js, in that file, search for the line of code where ... } else { for (let i = 0; i < 31; i++) { const res = this.getReservationsForDay(iterator, props);
if (res) { reservations = reservations.concat(res); } iterator.addDays(1); } } change it to } else { const res = this.getReservationsForDay(iterator, props); if (res) { reservations = res; } iterator.addDays(1); }
This will render the reservations not in a list of 31 days, but just the item itself on that day. Hope this helps! Sincerely, Donovan Ng
On Fri, 3 Jun 2022 at 17:31, zeentan22 @.***> wrote:
Hi, may I ask how u managed to only show the items for that particular day that was pressed. Currently, items from other days appear in my app which is not what I desire. I would appreciate greatly if you are able to help me. Thanks!
— Reply to this email directly, view it on GitHub https://github.com/wix/react-native-calendars/issues/1791#issuecomment-1145779668, or unsubscribe https://github.com/notifications/unsubscribe-auth/AURSUDFN2GTM7KOYFS7MGN3VNHGGBANCNFSM5ONJ332A . You are receiving this because you commented.Message ID: @.***>
I am still facing the same issue, anyone could find a walk around to it
Hi minaairsupport,
DonovanVA solution is correct and helps me solve the issue.
Just change the last code snippet to this and it should work.
if (sameDate(newSelectedDate, prevState.selectedDay)) { this.setState({ reservations: [] }, () => this.updateReservations(this.props)); }
Thanks, @zeentan22 I wish they could release this fix instead of making a walk around @Inbal-Tish if you don't mind could you merge this fix so we could have it in next release
I think I figure it out we need to override reservationsKeyExtractor
to get the right id from the data
<Agenda
items={selectedDates}
renderItem={renderItem}
showOnlySelectedDayItems={true}
reservationsKeyExtractor={(item) => {
console.log('item', item);
return item?.reservation?.id; ---> replace with proper id name
}}
/>
@minaairsupport Hi. I'm not sure I understand what fix we are talking about. If you need a custom keyExtractor
pass it to the reservationsKeyExtractor
prop. This will return the item and the index as a parameter, much like the keyExtractor
prop:
reservationsKeyExtractor={(item, index) => {
return `${item?.reservation?.day}${index}`;
}}
Hi @Inbal-Tish expose reservationsKeyExtractor is a walk-around to fixing the incorrect view for the list. I wish this fixed by the library itself by doing the right checks.
like this one
if (sameDate(newSelectedDate, prevState.selectedDay)) { this.setState({ reservations: [] }, () => this.updateReservations(this.props)); }
@minaairsupport Hi. Care to submit a PR on this?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Guys i have this issue but im using agenda instead of flat list, how can i fix it?
I think I figure it out we need to override
reservationsKeyExtractor
to get the right id from the data<Agenda items={selectedDates} renderItem={renderItem} showOnlySelectedDayItems={true} reservationsKeyExtractor={(item) => { console.log('item', item); return item?.reservation?.id; ---> replace with proper id name }} />
This worked for me!
if (sameDate(newSelectedDate, prevState.selectedDay)) { this.setState({ reservations: [] }, () => this.updateReservations(this.props)); }
Please where i add above lines of code?