From 53638356d2b261839241da0469065d74b2318e0b Mon Sep 17 00:00:00 2001 From: Marcelo Terreiro Prado Date: Tue, 27 Feb 2024 22:13:48 -0300 Subject: [PATCH] Ensures Calendar.List always show the right active date ranges (#14) --- .changeset/silent-balloons-sniff.md | 5 +++ .../CalendarListGithubIssues.stories.tsx | 35 +++++++++++++++++++ .../PerfTestCalendar/PerfTestCalendar.tsx | 18 ++++++++-- .../src/components/Calendar.tsx | 16 +++++++-- 4 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 .changeset/silent-balloons-sniff.md create mode 100644 apps/example/src/components/GithubIssues/CalendarListGithubIssues.stories.tsx diff --git a/.changeset/silent-balloons-sniff.md b/.changeset/silent-balloons-sniff.md new file mode 100644 index 0000000..c61f33d --- /dev/null +++ b/.changeset/silent-balloons-sniff.md @@ -0,0 +1,5 @@ +--- +"@marceloterreiro/flash-calendar": patch +--- + +Fix `` losing track of the active date ranges when the list is scrolled past certain amount diff --git a/apps/example/src/components/GithubIssues/CalendarListGithubIssues.stories.tsx b/apps/example/src/components/GithubIssues/CalendarListGithubIssues.stories.tsx new file mode 100644 index 0000000..db84b2b --- /dev/null +++ b/apps/example/src/components/GithubIssues/CalendarListGithubIssues.stories.tsx @@ -0,0 +1,35 @@ +import { Calendar } from "@marceloterreiro/flash-calendar"; +import type { Meta } from "@storybook/react"; + +const CalendarMeta: Meta = { + title: "Calendar.List/Github Issues", + decorators: [], +}; + +export default CalendarMeta; + +// See more: https://github.com/MarceloPrado/flash-calendar/issues/11 +export const Issue11 = () => { + const act = [ + { endId: "2024-01-31", startId: "2024-01-30" }, + { endId: "2024-01-12", startId: "2024-01-10" }, + { endId: "2024-03-07", startId: "2024-02-28" }, + { endId: "2024-04-10", startId: "2024-04-01" }, + { endId: "2024-01-19", startId: "2024-01-18" }, + { endId: "2024-02-06", startId: "2024-02-02" }, + { endId: "2024-01-26", startId: "2024-01-25" }, + { endId: "2024-01-05", startId: "2024-01-02" }, + ]; + const dis = ["2024-02-02", "2024-02-06", "2024-02-19", "2024-02-27"]; + + return ( + { + console.log("pressed"); + }} + /> + ); +}; diff --git a/apps/example/src/components/PerfTestCalendar/PerfTestCalendar.tsx b/apps/example/src/components/PerfTestCalendar/PerfTestCalendar.tsx index 604761c..f3a794e 100644 --- a/apps/example/src/components/PerfTestCalendar/PerfTestCalendar.tsx +++ b/apps/example/src/components/PerfTestCalendar/PerfTestCalendar.tsx @@ -94,15 +94,27 @@ const BasePerfTestCalendar = memo( BasePerfTestCalendar.displayName = "BasePerfTestCalendar"; export const PerfTestCalendar = memo( - ({ calendarActiveDateRanges, ...props }: CalendarProps) => { + ({ calendarActiveDateRanges, calendarMonthId, ...props }: CalendarProps) => { useEffect(() => { activeDateRangesEmitter.emit( "onSetActiveDateRanges", calendarActiveDateRanges ?? [] ); - }, [calendarActiveDateRanges]); + /** + * While `calendarMonthId` is not used by the effect, we still need it in + * the dependency array since [FlashList uses recycling + * internally](https://shopify.github.io/flash-list/docs/recycling). + * + * This means `Calendar` can re-render with different props instead of + * getting re-mounted. Without it, we would see staled/invalid data, as + * reported by + * [#11](https://github.com/MarceloPrado/flash-calendar/issues/11). + */ + }, [calendarActiveDateRanges, calendarMonthId]); - return ; + return ( + + ); } ); PerfTestCalendar.displayName = "PerfTestCalendar"; diff --git a/packages/flash-calendar/src/components/Calendar.tsx b/packages/flash-calendar/src/components/Calendar.tsx index 8e1e72b..3f98e81 100644 --- a/packages/flash-calendar/src/components/Calendar.tsx +++ b/packages/flash-calendar/src/components/Calendar.tsx @@ -150,15 +150,25 @@ const BaseCalendar = memo( BaseCalendar.displayName = "BaseCalendar"; export const Calendar = memo( - ({ calendarActiveDateRanges, ...props }: CalendarProps) => { + ({ calendarActiveDateRanges, calendarMonthId, ...props }: CalendarProps) => { useEffect(() => { activeDateRangesEmitter.emit( "onSetActiveDateRanges", calendarActiveDateRanges ?? [] ); - }, [calendarActiveDateRanges]); + /** + * While `calendarMonthId` is not used by the effect, we still need it in + * the dependency array since [FlashList uses recycling + * internally](https://shopify.github.io/flash-list/docs/recycling). + * + * This means `Calendar` can re-render with different props instead of + * getting re-mounted. Without it, we would see staled/invalid data, as + * reported by + * [#11](https://github.com/MarceloPrado/flash-calendar/issues/11). + */ + }, [calendarActiveDateRanges, calendarMonthId]); - return ; + return ; } );