Agenda renders items under wrong date when navigating to a date other than the initial selected

Author: clivegrossCreated Apr 21, 2026Updated Apr 21, 2026

Description

When the Agenda component is mounted with a selected date (e.g. today), then the user navigates to a different date, items from the original date appear under the wrong date section header. The symptoms shift depending on which date is selected, making the bug look like a data problem rather than a rendering one.

Root cause

Two issues combine to produce the bug:

1. Reservation.shouldComponentUpdate ignores item content when date is undefined

javascript
// reservation-list/reservation.js
if (!d1 && !d2) {
    changed = false;
}

Only the first item in each day's group receives a date prop; all subsequent items always have date: undefined. When the list shifts to a new selectedDay, React reuses existing Reservation instances (matched by key). For any reused instance where both the old and new date are undefined, shouldComponentUpdate returns false — even when the actual item (reservation content) has changed. The component keeps rendering the stale item.

2. The default keyExtractor produces non-unique keys for custom item types

javascript
keyExtractor = (item, index) => {
    return this.props.reservationsKeyExtractor?.(item, index) || `${item?.reservation?.day}${index}`;
};

item.reservation.day is undefined for any item type that doesn't match the built-in AgendaEntry shape ({ name, height, day }). This causes all keys to be "undefined0", "undefined1", etc. — purely positional — so React reuses the wrong component instances when the list shifts, triggering the shouldComponentUpdate bug above.

Steps to reproduce

  1. Mount <Agenda selected="2024-01-05" items={...} /> where the items for 2024-01-05 have multiple entries (e.g. 4 items) and the previous day (2024-01-04) also has items.
  2. Use custom item objects that don't have a day property (i.e. anything other than the built-in AgendaEntry shape).
  3. Navigate to 2024-01-04 (e.g. via onDayPress).
  4. Observe that items from 2024-01-05 appear in the 2024-01-04 section.

Expected behaviour

Items for 2024-01-04 appear under the 2024-01-04 section header after navigation.

Actual behaviour

Some items from 2024-01-05 remain visible under the 2024-01-04 section header. The number of incorrect items equals the number of non-first items in the original day's group (i.e. items 2–N, which all have date: undefined).

Workaround

Pass a reservationsKeyExtractor prop that returns a unique key per item. This forces React to create fresh Reservation instances when the list shifts, bypassing the shouldComponentUpdate guard entirely:

javascript
<Agenda
    reservationsKeyExtractor={(item, index) => item?.id ?? String(index)}
    ...
/>

Where item is your agenda item object. Any field that uniquely identifies the item works — item?.id, item?.name, etc.

Proposed fix

shouldComponentUpdate should include the item content in its change check when date is undefined, not short-circuit to false:

javascript
shouldComponentUpdate(nextProps) {
    const d1 = this.props.date;
    const d2 = nextProps.date;
    if (!d1 && !d2) {
        // date didn't change, but the item content might have
        if (isFunction(this.props.rowHasChanged)) {
            return this.props.rowHasChanged(this.props.item, nextProps.item);
        }
        return this.props.item !== nextProps.item;
    }
    // ... existing logic
}

Version

react-native-calendars 1.1314.0

Environment

  • Platform: iOS
  • react-native-calendars: 1.1314.0
  • React Native: 0.79.6
  • Expo SDK: 53.0.27

Source: wix/react-native-calendars