From c349d3670d87149456a2e6c6c21b1305adea09e0 Mon Sep 17 00:00:00 2001 From: Alex Kubyshkin Date: Sun, 19 Sep 2021 13:36:25 +0300 Subject: [PATCH 1/3] Add cache for isDayBlocked and isOutsideRange in DayPickerRangeController. --- src/components/DayPickerRangeController.jsx | 57 ++++++++++++++++----- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/src/components/DayPickerRangeController.jsx b/src/components/DayPickerRangeController.jsx index 87c61f0544..6efc6b3ec8 100644 --- a/src/components/DayPickerRangeController.jsx +++ b/src/components/DayPickerRangeController.jsx @@ -213,11 +213,12 @@ export default class DayPickerRangeController extends React.PureComponent { this.isTouchDevice = isTouchDevice(); this.today = moment(); + this.cachedProps = {}; this.modifiers = { today: (day) => this.isToday(day), blocked: (day) => this.isBlocked(day), - 'blocked-calendar': (day) => props.isDayBlocked(day), - 'blocked-out-of-range': (day) => props.isOutsideRange(day), + 'blocked-calendar': (day) => this.getCachedPropByDay(day, 'isDayBlocked'), + 'blocked-out-of-range': (day) => this.getCachedPropByDay(day, 'isOutsideRange'), 'highlighted-calendar': (day) => props.isDayHighlighted(day), valid: (day) => !this.isBlocked(day), 'selected-start': (day) => this.isStartDate(day), @@ -308,17 +309,14 @@ export default class DayPickerRangeController extends React.PureComponent { let recomputeDayHighlighted = false; if (isOutsideRange !== prevIsOutsideRange) { - this.modifiers['blocked-out-of-range'] = (day) => isOutsideRange(day); recomputeOutsideRange = true; } if (isDayBlocked !== prevIsDayBlocked) { - this.modifiers['blocked-calendar'] = (day) => isDayBlocked(day); recomputeDayBlocked = true; } if (isDayHighlighted !== prevIsDayHighlighted) { - this.modifiers['highlighted-calendar'] = (day) => isDayHighlighted(day); recomputeDayHighlighted = true; } @@ -471,7 +469,7 @@ export default class DayPickerRangeController extends React.PureComponent { let isBlocked = false; if (didFocusChange || recomputeOutsideRange) { - if (isOutsideRange(momentObj)) { + if (this.getCachedPropByDay(momentObj, 'isOutsideRange', nextProps, true)) { modifiers = this.addModifier(modifiers, momentObj, 'blocked-out-of-range'); isBlocked = true; } else { @@ -480,7 +478,7 @@ export default class DayPickerRangeController extends React.PureComponent { } if (didFocusChange || recomputeDayBlocked) { - if (isDayBlocked(momentObj)) { + if (this.getCachedPropByDay(momentObj, 'isDayBlocked', nextProps, true)) { modifiers = this.addModifier(modifiers, momentObj, 'blocked-calendar'); isBlocked = true; } else { @@ -1086,6 +1084,7 @@ export default class DayPickerRangeController extends React.PureComponent { } getModifiersForDay(day) { + this.removeCachedProps(day); return new Set(Object.keys(this.modifiers).filter((modifier) => this.modifiers[modifier](day))); } @@ -1111,6 +1110,42 @@ export default class DayPickerRangeController extends React.PureComponent { return { currentMonth, visibleDays }; } + getCachedPropByDay(day, prop, props, forceUpdate = false) { + const key = day.toString(); + const propsStore = props || this.props; + if (!forceUpdate && this.cachedProps[key] && this.cachedProps[key][prop]) { + // Get value from cache + return this.cachedProps[key][prop].value; + } + + // Get new value + const value = propsStore[prop](day); + if (!this.cachedProps[key]) { + this.cachedProps[key] = {}; + } + this.cachedProps[key][prop] = { value }; + + return value; + } + + removeCachedProps(day, prop) { + if (!day) { + // Remove all + this.cachedProps = {}; + } + + const key = day.toString(); + if (prop) { + // Remove by day and prop + if (this.cachedProps[key]) { + delete this.cachedProps[key][prop]; + } + } else { + // Remove by day + delete this.cachedProps[key]; + } + } + shouldDisableMonthNavigation(date, visibleMonth) { if (!date) return false; @@ -1157,7 +1192,6 @@ export default class DayPickerRangeController extends React.PureComponent { doesNotMeetMinimumNights(day) { const { startDate, - isOutsideRange, focusedInput, minimumNights, } = this.props; @@ -1167,7 +1201,7 @@ export default class DayPickerRangeController extends React.PureComponent { const dayDiff = day.diff(startDate.clone().startOf('day').hour(12), 'days'); return dayDiff < minimumNights && dayDiff >= 0; } - return isOutsideRange(moment(day).subtract(minimumNights, 'days')); + return this.getCachedPropByDay(moment(day).subtract(minimumNights, 'days'), 'isOutsideRange'); } doesNotMeetMinNightsForHoveredStartDate(day, hoverDate) { @@ -1239,9 +1273,8 @@ export default class DayPickerRangeController extends React.PureComponent { } isBlocked(day, blockDaysViolatingMinNights = true) { - const { isDayBlocked, isOutsideRange } = this.props; - return isDayBlocked(day) - || isOutsideRange(day) + return this.getCachedPropByDay(day, 'isDayBlocked') + || this.getCachedPropByDay(day, 'isOutsideRange') || (blockDaysViolatingMinNights && this.doesNotMeetMinimumNights(day)); } From 1448932351de825194892fd8d0deb6f042e94710 Mon Sep 17 00:00:00 2001 From: Alexander Kubyshkin Date: Tue, 30 Nov 2021 20:46:00 +0200 Subject: [PATCH 2/3] Update src/components/DayPickerRangeController.jsx Co-authored-by: Jordan Harband --- src/components/DayPickerRangeController.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DayPickerRangeController.jsx b/src/components/DayPickerRangeController.jsx index 6efc6b3ec8..32976fbb00 100644 --- a/src/components/DayPickerRangeController.jsx +++ b/src/components/DayPickerRangeController.jsx @@ -1134,7 +1134,7 @@ export default class DayPickerRangeController extends React.PureComponent { this.cachedProps = {}; } - const key = day.toString(); + const key = String(day); if (prop) { // Remove by day and prop if (this.cachedProps[key]) { From c29f9504d1673f4cbaf8aa598a9ff826646bbf42 Mon Sep 17 00:00:00 2001 From: Alexander Kubyshkin Date: Tue, 30 Nov 2021 20:46:05 +0200 Subject: [PATCH 3/3] Update src/components/DayPickerRangeController.jsx Co-authored-by: Jordan Harband --- src/components/DayPickerRangeController.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DayPickerRangeController.jsx b/src/components/DayPickerRangeController.jsx index 32976fbb00..84ff4767c2 100644 --- a/src/components/DayPickerRangeController.jsx +++ b/src/components/DayPickerRangeController.jsx @@ -1111,7 +1111,7 @@ export default class DayPickerRangeController extends React.PureComponent { } getCachedPropByDay(day, prop, props, forceUpdate = false) { - const key = day.toString(); + const key = String(day); const propsStore = props || this.props; if (!forceUpdate && this.cachedProps[key] && this.cachedProps[key][prop]) { // Get value from cache