Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditionally use PureComponent instead of Component #1335

Merged
merged 7 commits into from
Sep 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .storybook/config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import React from 'react';
if (process.env.NODE_ENV !== 'production') {
const { whyDidYouUpdate } = require('why-did-you-update');
whyDidYouUpdate(React);
}

import moment from 'moment';
import aphroditeInterface from 'react-with-styles-interface-aphrodite';

Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ Create a CSS file with the contents of `require.resolve('react-dates/lib/css/_da

To see this in action, you can check out https://github.com/majapw/react-dates-demo which adds `react-dates` on top of a simple `create-react-app` setup.

#### Overriding Base Class
By default `react-dates` will use `PureComponent` conditionally if it is available. However, it is possible to override this setting and use `Component` and `shouldComponentUpdate` instead. It is also possible to override the logic in `build/util/baseClass` if you know that you are using a React version with `PureComponent`.
```javascript
import React from 'react';
export default React.PureComponent;
export const pureComponentAvailable = true;
```

#### Overriding styles
Right now, the easiest way to tweak `react-dates` to your heart's content is to create another stylesheet to override the default react-dates styles. For example, you could create a file named `react_dates_overrides.css` with the following contents:

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@
"sinon": "^6.1.5",
"sinon-sandbox": "^2.0.0",
"style-loader": "^0.20.3",
"webpack": "^2.6.1"
"webpack": "^2.6.1",
"why-did-you-update": "^0.1.1"
},
"dependencies": {
"airbnb-prop-types": "^2.10.0",
Expand Down
11 changes: 4 additions & 7 deletions src/components/CalendarDay.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import shallowCompare from 'react-addons-shallow-compare';
import momentPropTypes from 'react-moment-proptypes';
import { forbidExtraProps, nonNegativeInteger } from 'airbnb-prop-types';
import { css, withStyles, withStylesPropTypes } from 'react-with-styles';
Expand All @@ -10,6 +9,7 @@ import { CalendarDayPhrases } from '../defaultPhrases';
import getPhrasePropTypes from '../utils/getPhrasePropTypes';
import getCalendarDaySettings from '../utils/getCalendarDaySettings';
import ModifiersShape from '../shapes/ModifiersShape';
import BaseClass, { pureComponentAvailable } from '../utils/baseClass';

import { DAY_SIZE } from '../constants';

Expand Down Expand Up @@ -48,17 +48,14 @@ const defaultProps = {
phrases: CalendarDayPhrases,
};

class CalendarDay extends React.Component {
/** @extends React.Component */
class CalendarDay extends BaseClass {
constructor(...args) {
super(...args);

this.setButtonRef = this.setButtonRef.bind(this);
}

shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}

componentDidUpdate(prevProps) {
const { isFocused, tabIndex } = this.props;
if (tabIndex === 0) {
Expand Down Expand Up @@ -339,4 +336,4 @@ export default withStyles(({ reactDates: { color, font } }) => ({
CalendarDay__today: {},
CalendarDay__firstDayOfWeek: {},
CalendarDay__lastDayOfWeek: {},
}))(CalendarDay);
}), { pureComponent: pureComponentAvailable })(CalendarDay);
11 changes: 4 additions & 7 deletions src/components/CalendarMonth.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import React from 'react';
import PropTypes from 'prop-types';
import shallowCompare from 'react-addons-shallow-compare';
import momentPropTypes from 'react-moment-proptypes';
import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types';
import { css, withStyles, withStylesPropTypes } from 'react-with-styles';
Expand All @@ -22,6 +21,7 @@ import toISODateString from '../utils/toISODateString';
import ModifiersShape from '../shapes/ModifiersShape';
import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape';
import DayOfWeekShape from '../shapes/DayOfWeekShape';
import BaseClass, { pureComponentAvailable } from '../utils/baseClass';

import {
HORIZONTAL_ORIENTATION,
Expand Down Expand Up @@ -90,7 +90,8 @@ const defaultProps = {
verticalBorderSpacing: undefined,
};

class CalendarMonth extends React.Component {
/** @extends React.Component */
class CalendarMonth extends BaseClass {
constructor(props) {
super(props);

Expand Down Expand Up @@ -132,10 +133,6 @@ class CalendarMonth extends React.Component {
}
}

shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}

componentWillUnmount() {
if (this.setMonthTitleHeightTimeout) {
clearTimeout(this.setMonthTitleHeightTimeout);
Expand Down Expand Up @@ -277,4 +274,4 @@ export default withStyles(({ reactDates: { color, font, spacing } }) => ({
paddingTop: 12,
paddingBottom: 7,
},
}))(CalendarMonth);
}), { pureComponent: pureComponentAvailable })(CalendarMonth);
11 changes: 4 additions & 7 deletions src/components/CalendarMonthGrid.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import shallowCompare from 'react-addons-shallow-compare';
import momentPropTypes from 'react-moment-proptypes';
import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types';
import { css, withStyles, withStylesPropTypes } from 'react-with-styles';
Expand All @@ -22,6 +21,7 @@ import isNextMonth from '../utils/isNextMonth';
import ModifiersShape from '../shapes/ModifiersShape';
import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape';
import DayOfWeekShape from '../shapes/DayOfWeekShape';
import BaseClass, { pureComponentAvailable } from '../utils/baseClass';

import {
HORIZONTAL_ORIENTATION,
Expand Down Expand Up @@ -114,7 +114,8 @@ function getMonths(initialMonth, numberOfMonths, withoutTransitionMonths) {
return months;
}

class CalendarMonthGrid extends React.Component {
/** @extends React.Component */
class CalendarMonthGrid extends BaseClass {
constructor(props) {
super(props);
const withoutTransitionMonths = props.orientation === VERTICAL_SCROLLABLE;
Expand Down Expand Up @@ -180,10 +181,6 @@ class CalendarMonthGrid extends React.Component {
});
}

shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}

componentDidUpdate() {
const {
isAnimating,
Expand Down Expand Up @@ -425,4 +422,4 @@ export default withStyles(({
CalendarMonthGrid_month__hidden: {
visibility: 'hidden',
},
}))(CalendarMonthGrid);
}), { pureComponent: pureComponentAvailable })(CalendarMonthGrid);
11 changes: 4 additions & 7 deletions src/components/CustomizableCalendarDay.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import shallowCompare from 'react-addons-shallow-compare';
import momentPropTypes from 'react-moment-proptypes';
import { forbidExtraProps, nonNegativeInteger, or } from 'airbnb-prop-types';
import { css, withStyles, withStylesPropTypes } from 'react-with-styles';
Expand All @@ -9,6 +8,7 @@ import moment from 'moment';
import { CalendarDayPhrases } from '../defaultPhrases';
import getPhrasePropTypes from '../utils/getPhrasePropTypes';
import getCalendarDaySettings from '../utils/getCalendarDaySettings';
import BaseClass, { pureComponentAvailable } from '../utils/baseClass';

import { DAY_SIZE } from '../constants';
import DefaultTheme from '../theme/DefaultTheme';
Expand Down Expand Up @@ -212,7 +212,8 @@ const defaultProps = {
phrases: CalendarDayPhrases,
};

class CustomizableCalendarDay extends React.Component {
/** @extends React.Component */
class CustomizableCalendarDay extends BaseClass {
constructor(...args) {
super(...args);

Expand All @@ -223,10 +224,6 @@ class CustomizableCalendarDay extends React.Component {
this.setButtonRef = this.setButtonRef.bind(this);
}

shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}

componentDidUpdate(prevProps) {
const { isFocused, tabIndex } = this.props;
if (tabIndex === 0) {
Expand Down Expand Up @@ -369,4 +366,4 @@ export default withStyles(({ reactDates: { font } }) => ({
CalendarDay__defaultCursor: {
cursor: 'default',
},
}))(CustomizableCalendarDay);
}), { pureComponent: pureComponentAvailable })(CustomizableCalendarDay);
6 changes: 4 additions & 2 deletions src/components/DateInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import isTouchDevice from 'is-touch-device';

import getInputHeight from '../utils/getInputHeight';
import openDirectionShape from '../shapes/OpenDirectionShape';
import BaseClass, { pureComponentAvailable } from '../utils/baseClass';
import {
OPEN_DOWN,
OPEN_UP,
Expand Down Expand Up @@ -77,7 +78,8 @@ const defaultProps = {
isFocused: false,
};

class DateInput extends React.Component {
/** @extends React.Component */
class DateInput extends BaseClass {
constructor(props) {
super(props);

Expand Down Expand Up @@ -379,4 +381,4 @@ export default withStyles(({
stroke: color.core.border,
fill: 'transparent',
},
}))(DateInput);
}), { pureComponent: pureComponentAvailable })(DateInput);
11 changes: 4 additions & 7 deletions src/components/DateRangePicker.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import shallowCompare from 'react-addons-shallow-compare';
import moment from 'moment';
import { css, withStyles, withStylesPropTypes } from 'react-with-styles';
import { Portal } from 'react-portal';
Expand All @@ -16,6 +15,7 @@ import getDetachedContainerStyles from '../utils/getDetachedContainerStyles';
import getInputHeight from '../utils/getInputHeight';
import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay';
import disableScroll from '../utils/disableScroll';
import BaseClass, { pureComponentAvailable } from '../utils/baseClass';

import DateRangePickerInputController from './DateRangePickerInputController';
import DayPickerRangeController from './DayPickerRangeController';
Expand Down Expand Up @@ -118,7 +118,8 @@ const defaultProps = {
dayAriaLabelFormat: undefined,
};

class DateRangePicker extends React.Component {
/** @extends React.Component */
class DateRangePicker extends BaseClass {
constructor(props) {
super(props);
this.state = {
Expand Down Expand Up @@ -163,10 +164,6 @@ class DateRangePicker extends React.Component {
this.isTouchDevice = isTouchDevice();
}

shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}

componentDidUpdate(prevProps) {
const { focusedInput } = this.props;
if (!prevProps.focusedInput && focusedInput && this.isOpened()) {
Expand Down Expand Up @@ -674,4 +671,4 @@ export default withStyles(({ reactDates: { color, zIndex } }) => ({
width: 15,
fill: color.core.grayLighter,
},
}))(DateRangePicker);
}), { pureComponent: pureComponentAvailable })(DateRangePicker);
3 changes: 2 additions & 1 deletion src/components/DateRangePickerInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import openDirectionShape from '../shapes/OpenDirectionShape';
import DateInput from './DateInput';
import IconPositionShape from '../shapes/IconPositionShape';
import DisabledShape from '../shapes/DisabledShape';
import { pureComponentAvailable } from '../utils/baseClass';

import RightArrow from './RightArrow';
import LeftArrow from './LeftArrow';
Expand Down Expand Up @@ -396,4 +397,4 @@ export default withStyles(({ reactDates: { border, color, sizing } }) => ({
width: 14,
verticalAlign: 'middle',
},
}))(DateRangePickerInput);
}), { pureComponent: pureComponentAvailable })(DateRangePickerInput);
5 changes: 4 additions & 1 deletion src/components/DateRangePickerInputController.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import toLocalizedDateString from '../utils/toLocalizedDateString';
import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay';
import isBeforeDay from '../utils/isBeforeDay';

import BaseClass from '../utils/baseClass';

import {
START_DATE,
END_DATE,
Expand Down Expand Up @@ -131,7 +133,8 @@ const defaultProps = {
isRTL: false,
};

export default class DateRangePickerInputController extends React.Component {
/** @extends React.Component */
export default class DateRangePickerInputController extends BaseClass {
constructor(props) {
super(props);

Expand Down
11 changes: 4 additions & 7 deletions src/components/DayPicker.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import shallowCompare from 'react-addons-shallow-compare';
import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types';
import { css, withStyles, withStylesPropTypes } from 'react-with-styles';

Expand Down Expand Up @@ -30,6 +29,7 @@ import ModifiersShape from '../shapes/ModifiersShape';
import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape';
import DayOfWeekShape from '../shapes/DayOfWeekShape';
import CalendarInfoPositionShape from '../shapes/CalendarInfoPositionShape';
import BaseClass, { pureComponentAvailable } from '../utils/baseClass';

import {
HORIZONTAL_ORIENTATION,
Expand Down Expand Up @@ -163,7 +163,8 @@ export const defaultProps = {
dayAriaLabelFormat: undefined,
};

class DayPicker extends React.Component {
/** @extends React.Component */
class DayPicker extends BaseClass {
constructor(props) {
super(props);

Expand Down Expand Up @@ -299,10 +300,6 @@ class DayPicker extends React.Component {
}
}

shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}

componentWillUpdate() {
const { transitionDuration } = this.props;

Expand Down Expand Up @@ -1241,4 +1238,4 @@ export default withStyles(({
},
}),
},
}))(DayPicker);
}), { pureComponent: pureComponentAvailable })(DayPicker);
6 changes: 4 additions & 2 deletions src/components/DayPickerKeyboardShortcuts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { css, withStyles, withStylesPropTypes } from 'react-with-styles';

import { DayPickerKeyboardShortcutsPhrases } from '../defaultPhrases';
import getPhrasePropTypes from '../utils/getPhrasePropTypes';
import BaseClass, { pureComponentAvailable } from '../utils/baseClass';

import KeyboardShortcutRow from './KeyboardShortcutRow';
import CloseButton from './CloseButton';
Expand Down Expand Up @@ -72,7 +73,8 @@ function getKeyboardShortcuts(phrases) {
];
}

class DayPickerKeyboardShortcuts extends React.Component {
/** @extends React.Component */
class DayPickerKeyboardShortcuts extends BaseClass {
constructor(...args) {
super(...args);

Expand Down Expand Up @@ -394,4 +396,4 @@ export default withStyles(({ reactDates: { color, font, zIndex } }) => ({
fill: color.core.grayLight,
},
},
}))(DayPickerKeyboardShortcuts);
}), { pureComponent: pureComponentAvailable })(DayPickerKeyboardShortcuts);
3 changes: 2 additions & 1 deletion src/components/DayPickerNavigation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { css, withStyles, withStylesPropTypes } from 'react-with-styles';

import { DayPickerNavigationPhrases } from '../defaultPhrases';
import getPhrasePropTypes from '../utils/getPhrasePropTypes';
import { pureComponentAvailable } from '../utils/baseClass';

import LeftArrow from './LeftArrow';
import RightArrow from './RightArrow';
Expand Down Expand Up @@ -302,4 +303,4 @@ export default withStyles(({ reactDates: { color, zIndex } }) => ({
fill: color.text,
display: 'block',
},
}))(DayPickerNavigation);
}), { pureComponent: pureComponentAvailable })(DayPickerNavigation);
4 changes: 3 additions & 1 deletion src/components/DayPickerRangeController.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import FocusedInputShape from '../shapes/FocusedInputShape';
import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape';
import DayOfWeekShape from '../shapes/DayOfWeekShape';
import CalendarInfoPositionShape from '../shapes/CalendarInfoPositionShape';
import BaseClass from '../utils/baseClass';

import {
START_DATE,
Expand Down Expand Up @@ -173,7 +174,8 @@ const getChooseAvailableDatePhrase = (phrases, focusedInput) => {
return phrases.chooseAvailableDate;
};

export default class DayPickerRangeController extends React.Component {
/** @extends React.Component */
export default class DayPickerRangeController extends BaseClass {
constructor(props) {
super(props);

Expand Down
Loading