Skip to content

Conditionally use PureComponent instead of Component#1335

Merged
majapw merged 7 commits intoreact-dates:masterfrom
getaroom:PureComponent-Upgrade
Sep 4, 2018
Merged

Conditionally use PureComponent instead of Component#1335
majapw merged 7 commits intoreact-dates:masterfrom
getaroom:PureComponent-Upgrade

Conversation

@AntiFish03
Copy link
Copy Markdown
Contributor

Working to resolve #1297. Conditionally using React.PureComponent instead of React.Component

@coveralls
Copy link
Copy Markdown

coveralls commented Aug 30, 2018

Coverage Status

Coverage increased (+0.2%) to 84.875% when pulling 88fc16a on getaroom:PureComponent-Upgrade into ebf83a1 on airbnb:master.

class CalendarDay extends React.Component {
const BaseClass = baseClass();

class CalendarDay extends BaseClass {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is going to break react linting; we'll need a jsdoc comment to indicate that it extends React.Component

Comment thread src/components/CalendarDay.jsx Outdated
};

class CalendarDay extends React.Component {
const BaseClass = baseClass();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extends baseClass() works too

Comment thread src/utils/baseClass.js Outdated

export const pureComponentAvailable = typeof React.PureComponent !== 'undefined';

export default function baseClass(pureComponent = pureComponentAvailable) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is baseClass a function, but pureComponentAvailable is not?

I'd expect either both to be a function (to support polyfilling of PureComponent, i assume), or neither.

  - Both `pureComponentAvailable` and `baseClass` are now functions
  - Using `extends baseClass()` instead of defining `BaseClass = baseClass()`
  - Fixing the lint on `DayPickerRangeController` for `pureComponentAvailable` being defined but not used
@AntiFish03
Copy link
Copy Markdown
Contributor Author

@ljharb what does the jsdoc comment need to be? Your linting system is different than I am used to working with.

@AntiFish03
Copy link
Copy Markdown
Contributor Author

Also, @majapw this PR only resolves most of the avoidable re-rendering issue. As I mentioned in #1297, I was not able to resolve some re-rendering on DayPickerNavigation or on DayPicker

@ljharb
Copy link
Copy Markdown
Member

ljharb commented Aug 30, 2018

(what are you used to working with that’s not eslint?) i believe it’s /** @extends React.Component */ but I’ll have to check the docs and get back to you. You can test by introducing a lint error, verifying that it fails when it extends React.Component, verify that it passes when extending baseClass, and then verify that it fails with the JSdoc comment.

@AntiFish03
Copy link
Copy Markdown
Contributor Author

@ljharb not in that way. I guess I never knew about being able to do that is a better way of describing it.

@ljharb
Copy link
Copy Markdown
Member

ljharb commented Aug 30, 2018

@AntiFish03 here's an example: jsx-eslint/eslint-plugin-react#513 (comment)

@ljharb
Copy link
Copy Markdown
Member

ljharb commented Aug 30, 2018

@AntiFish03 what's the reasoning that the baseClass stuff needs to be in a function, instead of caching it once at module load time?

@AntiFish03
Copy link
Copy Markdown
Contributor Author

It doesn't have to be. Just trying to keep it similar to what is used in react-with-styles as was requested.

@AntiFish03
Copy link
Copy Markdown
Contributor Author

travis-ci decided to have some timeout issues there for no apparent reason... @ljharb care to restart that and everything should be good to go

@ljharb
Copy link
Copy Markdown
Member

ljharb commented Aug 30, 2018

After a few discussions, i wonder if it'd be worth it to try something like this?

/** @extends React.Component */
class Foo extends React.PureComponent || React.Component {
  [React.PureComponent || 'shouldComponentUpdate'](nextProps, nextState) {
     return shallowCompare(this, nextProps, nextState);		
  }
}

Otherwise, your change LGTM.

@AntiFish03
Copy link
Copy Markdown
Contributor Author

@ljharb, Change made as requested anything else?

Copy link
Copy Markdown
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With appropriate documentation - including telling people that they can overwrite build/utils/baseClass.js with module.exports = React.PureComponent if they know they're using a newer React - this LGTM.

@ljharb ljharb requested review from lencioni and majapw August 31, 2018 23:20
@AntiFish03
Copy link
Copy Markdown
Contributor Author

@ljharb, Readme updated.

Copy link
Copy Markdown
Collaborator

@majapw majapw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Thank you so much for making this change.

Comment thread .storybook/config.js Outdated
@@ -1,4 +1,9 @@
import React from 'react';
if (process.env.NODE_ENV !== 'production') {
const {whyDidYouUpdate} = require('why-did-you-update');
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: spaces around the whyDidYouUpdate

const { whyDidYouUpdate } = require('why-did-you-update');

Comment thread src/utils/baseClass.js Outdated
import shallowCompare from 'react-addons-shallow-compare';

class BaseClass extends (React.PureComponent || React.Component) {
[React.PureComponent || 'shouldComponentUpdate'](nextProps, nextState) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I fully understand what this will do in the case that React.PureComponent is defined

Copy link
Copy Markdown
Member

@ljharb ljharb Sep 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right, this should be React.PureComponent && - so that it's undefined in that case, instead of the method name

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't it actually be !React.PureComponent && so that it injects the shouldComponentUpdate when PureComponent isn't available.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha, yes, that's better. coding is hard.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're all tired. :P

Copy link
Copy Markdown
Collaborator

@majapw majapw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gonna put an X on this temporarily so that || doesn't accidentally get merged in

@AntiFish03
Copy link
Copy Markdown
Contributor Author

@majapw, @ljharb There you go both of those pieces should be fixed now

Copy link
Copy Markdown
Collaborator

@majapw majapw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@majapw majapw merged commit f2536b6 into react-dates:master Sep 4, 2018
@majapw majapw added the semver-patch: fixes/refactors/etc Anything that's not major or minor. label Sep 5, 2018
@majapw
Copy link
Copy Markdown
Collaborator

majapw commented Sep 12, 2018

So fun fact, I believe that this breaks react-dates in IE10. sigh It seems to be related to how this is transformed by babel (current working theory is something about the double-extends).
I'm seeing Cannot call a class as a function coming from https://unpkg.com/react-dates@18.0.2/lib/utils/baseClass.js.

majapw added a commit that referenced this pull request Sep 12, 2018
majapw added a commit that referenced this pull request Sep 13, 2018
@AntiFish03
Copy link
Copy Markdown
Contributor Author

@majapw all of a sudden I am getting

Warning: DateRangePickerInputController has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.

Is this something you are seeing also?

@majapw
Copy link
Copy Markdown
Collaborator

majapw commented Sep 24, 2018

@AntiFish03 locally or in storybook? on the latest version?

@AntiFish03
Copy link
Copy Markdown
Contributor Author

@majapw, Locally from master.

teleaziz pushed a commit to teleaziz/react-dates that referenced this pull request Jul 4, 2025
teleaziz pushed a commit to teleaziz/react-dates that referenced this pull request Jul 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

semver-patch: fixes/refactors/etc Anything that's not major or minor.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Performance Issues

4 participants