diff --git a/src/components/DayPickerRangeController.jsx b/src/components/DayPickerRangeController.jsx index 2383ab0277..83aaa21b9a 100644 --- a/src/components/DayPickerRangeController.jsx +++ b/src/components/DayPickerRangeController.jsx @@ -40,6 +40,7 @@ import { import DayPicker from './DayPicker'; import getPreviousMonthMemoLast from '../utils/getPreviousMonthMemoLast'; +import getPooledMoment from '../utils/getPooledMoment'; const propTypes = forbidExtraProps({ startDate: momentPropTypes.momentObj, @@ -394,7 +395,7 @@ export default class DayPickerRangeController extends React.PureComponent { if (didFocusChange || recomputePropModifiers) { values(visibleDays).forEach((days) => { Object.keys(days).forEach((day) => { - const momentObj = moment(day); + const momentObj = getPooledMoment(day); let isBlocked = false; if (didFocusChange || recomputeOutsideRange) { diff --git a/src/components/DayPickerSingleDateController.jsx b/src/components/DayPickerSingleDateController.jsx index c6b9642706..24649038fd 100644 --- a/src/components/DayPickerSingleDateController.jsx +++ b/src/components/DayPickerSingleDateController.jsx @@ -31,6 +31,7 @@ import { import DayPicker from './DayPicker'; import getPreviousMonthMemoLast from '../utils/getPreviousMonthMemoLast'; +import getPooledMoment from '../utils/getPooledMoment'; const propTypes = forbidExtraProps({ date: momentPropTypes.momentObj, @@ -268,7 +269,7 @@ export default class DayPickerSingleDateController extends React.PureComponent { if (didFocusChange || recomputePropModifiers) { values(visibleDays).forEach((days) => { Object.keys(days).forEach((day) => { - const momentObj = moment(day); + const momentObj = getPooledMoment(day); if (this.isBlocked(momentObj)) { modifiers = this.addModifier(modifiers, momentObj, 'blocked'); } else { diff --git a/src/utils/getPooledMoment.js b/src/utils/getPooledMoment.js new file mode 100644 index 0000000000..38cd9fd25e --- /dev/null +++ b/src/utils/getPooledMoment.js @@ -0,0 +1,10 @@ +import moment from 'moment'; + +const momentPool = new Map(); +export default function getPooledMoment(dayString) { + if (!momentPool.has(dayString)) { + momentPool.set(dayString, moment(dayString)); + } + + return momentPool.get(dayString); +} diff --git a/test/utils/getPooledMoment_spec.js b/test/utils/getPooledMoment_spec.js new file mode 100644 index 0000000000..7c28318270 --- /dev/null +++ b/test/utils/getPooledMoment_spec.js @@ -0,0 +1,24 @@ +import { expect } from 'chai'; +import moment from 'moment'; + +import getPooledMoment from '../../src/utils/getPooledMoment'; + +describe('getPooledMoment', () => { + it('returns a moment given a day string', () => { + const momentObj = getPooledMoment('2017-12-10'); + expect(moment.isMoment(momentObj)).to.equal(true); + expect(momentObj.format('YYYY MM DD')).to.equal('2017 12 10'); + }); + + it('returns the same moment given the same day string', () => { + const momentObj1 = getPooledMoment('2017-12-10'); + const momentObj2 = getPooledMoment('2017-12-10'); + expect(momentObj1).to.equal(momentObj2); + }); + + it('returns a different moment given a different day string', () => { + const momentObj1 = getPooledMoment('2017-12-10'); + const momentObj2 = getPooledMoment('2017-12-11'); + expect(momentObj1).not.to.equal(momentObj2); + }); +});