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

Conversation

AntiFish03
Copy link
Contributor

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

@coveralls
Copy link

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
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

@@ -48,17 +48,15 @@ const defaultProps = {
phrases: CalendarDayPhrases,
};

class CalendarDay extends React.Component {
const BaseClass = baseClass();
Copy link
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


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

export default function baseClass(pureComponent = pureComponentAvailable) {
Copy link
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
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
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
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
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
Member

ljharb commented Aug 30, 2018

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

@ljharb
Copy link
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
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
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
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
Contributor Author

@ljharb, Change made as requested anything else?

Copy link
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 majapw and lencioni August 31, 2018 23:20
@AntiFish03
Copy link
Contributor Author

@ljharb, Readme updated.

Copy link
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.

@@ -1,4 +1,9 @@
import React from 'react';
if (process.env.NODE_ENV !== 'production') {
const {whyDidYouUpdate} = require('why-did-you-update');
Copy link
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');

import shallowCompare from 'react-addons-shallow-compare';

class BaseClass extends (React.PureComponent || React.Component) {
[React.PureComponent || 'shouldComponentUpdate'](nextProps, nextState) {
Copy link
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
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
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
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
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
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
Contributor Author

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

Copy link
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
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
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
Collaborator

majapw commented Sep 24, 2018

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

@AntiFish03
Copy link
Contributor Author

@majapw, Locally from master.

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