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

Add React.PureComponent #7195

Merged
merged 1 commit into from Jul 6, 2016
Merged

Add React.PureComponent #7195

merged 1 commit into from Jul 6, 2016

Conversation

@sophiebits
Copy link
Collaborator

@sophiebits sophiebits commented Jul 5, 2016

This provides an easy way to indicate that components should only rerender when given new props, like PureRenderMixin. If you rely on mutation in your React components, you can continue to use React.Component.

Inheriting from React.PureComponent indicates to React that your component doesn't need to rerender when the props are unchanged. We'll compare the old and new props before each render and short-circuit if they're unchanged. It's like an automatic shouldComponentUpdate.

);
}
}
} else {
Copy link
Member

@gaearon gaearon Jul 5, 2016

Choose a reason for hiding this comment

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

Nit: could be else if for less nesting?

Loading

Copy link
Collaborator Author

@sophiebits sophiebits Jul 5, 2016

Choose a reason for hiding this comment

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

It could be but I prefer parallel structure in my if/else-if cases so I left it like this.

Loading

Copy link
Contributor

@zzz6519003 zzz6519003 Jul 12, 2019

Choose a reason for hiding this comment

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

It could be but I prefer parallel structure in my if/else-if cases so I left it like this.

IMO, always good to use least syntax~

Loading

@syranide
Copy link
Contributor

@syranide syranide commented Jul 6, 2016

When documenting this I'd say it's important to note that callback handlers that are bound in render will always fail shallowEqual, many people are unaware of this and there has previously been discussions about ignoring functions in the comparison (I know this was recommended at some point).

Loading

@jimfb
Copy link
Contributor

@jimfb jimfb commented Jul 6, 2016

In addition to event handlers bound in render, it is probably also worth mentioning that any component which takes jsx children will also always fail shallowEqual, since the children elements will be re-created for every render. I think most people don't realize this.

Loading

ReactComponent.call(this, props, context, updater);
}

Object.assign(ReactPureComponent.prototype, ReactComponent.prototype);
Copy link
Member

@sebmarkbage sebmarkbage Jul 6, 2016

Choose a reason for hiding this comment

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

Should we extend ReactComponent? What about people doing instanceof React.Component even though they shouldn't?

Loading

Copy link
Collaborator Author

@sophiebits sophiebits Jul 6, 2016

Choose a reason for hiding this comment

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

All right.

Loading

This provides an easy way to indicate that components should only rerender when given new props, like PureRenderMixin. If you rely on mutation in your React components, you can continue to use `React.Component`.

Inheriting from `React.PureComponent` indicates to React that your component doesn't need to rerender when the props are unchanged. We'll compare the old and new props before each render and short-circuit if they're unchanged. It's like an automatic shouldComponentUpdate.
@sophiebits sophiebits merged commit c8fbdac into facebook:master Jul 6, 2016
@STRML
Copy link
Contributor

@STRML STRML commented Jul 7, 2016

@jimfb This is mitigated somewhat in production by the babel constant elements transform, no?

Loading

@zpao zpao added this to the 15-next milestone Jul 7, 2016
usmanajmal added a commit to usmanajmal/react that referenced this issue Jul 11, 2016
This provides an easy way to indicate that components should only rerender when given new props, like PureRenderMixin. If you rely on mutation in your React components, you can continue to use `React.Component`.

Inheriting from `React.PureComponent` indicates to React that your component doesn't need to rerender when the props are unchanged. We'll compare the old and new props before each render and short-circuit if they're unchanged. It's like an automatic shouldComponentUpdate.
@zpao zpao removed this from the 15-next milestone Jul 13, 2016
@zpao zpao added this to the 15.3.0 milestone Jul 13, 2016
@zpao zpao added this to the 15.3.0 milestone Jul 13, 2016
@zpao zpao removed this from the 15-next milestone Jul 13, 2016
zpao added a commit that referenced this issue Jul 13, 2016
This provides an easy way to indicate that components should only rerender when given new props, like PureRenderMixin. If you rely on mutation in your React components, you can continue to use `React.Component`.

Inheriting from `React.PureComponent` indicates to React that your component doesn't need to rerender when the props are unchanged. We'll compare the old and new props before each render and short-circuit if they're unchanged. It's like an automatic shouldComponentUpdate.
(cherry picked from commit c8fbdac)
@vlucas
Copy link

@vlucas vlucas commented Jul 14, 2016

Is there also going to be a React.createClass({ ... }) way to do this?

Loading

@gaearon
Copy link
Member

@gaearon gaearon commented Jul 14, 2016

@vlucas

For React.createClass(), you can either use PureRenderMixin or shallowCompare (both are available as addons).

Loading

@developit
Copy link
Contributor

@developit developit commented Jul 15, 2016

@gaearon / @spicyj - are you guys able to confirm this will land in 15.x with the shallowEqual() approach taken in this PR?

Loading

@sophiebits
Copy link
Collaborator Author

@sophiebits sophiebits commented Jul 15, 2016

That's the plan.

Loading

@developit
Copy link
Contributor

@developit developit commented Jul 15, 2016

Great, thanks.

Loading

@slmgc
Copy link

@slmgc slmgc commented Jul 15, 2016

@spicyj don't you think ReactPureComponent and isPureReactComponent look a little bit inconsistent? Could isReactPureComponent be a better name?

Loading

@sebmarkbage
Copy link
Member

@sebmarkbage sebmarkbage commented Jul 15, 2016

Actually, that's a good point. We should make it a worse name so that nobody relies on this implementation detail. :)

Loading

@brycehanscomb
Copy link

@brycehanscomb brycehanscomb commented Jul 30, 2016

Why was the decision to implement this class favoured over making React better equipped to deal with functional stateless components?

Loading

@Jessidhia
Copy link
Contributor

@Jessidhia Jessidhia commented Jul 30, 2016

@brycehanscomb I believe the intention is to add this as a non-breaking opt-in change, and then in React 16 change the internal SFC wrapper class to derive from React.PureComponent. I am just guessing, though.

Loading

@gaearon
Copy link
Member

@gaearon gaearon commented Jul 30, 2016

It's a stepping stone. We'll keep thinking about optimizing functional stateless components.

However just making every one of them work like PureComponent can slow down your app. Please don't think shallow equality checks are extremely cheap. They can help your app when placed strategically but just making every single component pure can actually make your app slower. Tradeoffs.

For now we added a base class because we wanted an official way of marking component as compatible with shallow equality checks, without using mixins. We'll see how and if we want to extend this behavior in some cases to functional components but it's not as straightforward as just making them behave the same.

Loading

@Andarist
Copy link
Contributor

@Andarist Andarist commented Jul 30, 2016

I remember from the other discussion thread that SFC were supposed to check the nearest class parent and based on it being Pure or not should opt in the being pure themselves.

Is it the part of this release?

Loading

@gaearon
Copy link
Member

@gaearon gaearon commented Jul 30, 2016

No, we decided to not proceed with this because the community discussion around it was controversial. These heuristics would be far from obvious, and we feel that this is not a good time to introduce them. Maybe we’ll figure out something more explicit in the future.

Loading

@raphaguasta
Copy link

@raphaguasta raphaguasta commented Aug 23, 2016

Hi @gaearon!

In the Changelog of react 15.3 (https://github.com/facebook/react/blob/v15.3.0/CHANGELOG.md), says that React.PureComponent was added, and refers this discussion. But here you said that this feature didn't was incorporated.

After all, it's in the React 15.3 or not? Is there some documentation about this?

Thanks :)

Loading

@sophiebits
Copy link
Collaborator Author

@sophiebits sophiebits commented Aug 23, 2016

PureComponent is included; the heuristics for stateless functional components are not.

Loading

@gaearon
Copy link
Member

@gaearon gaearon commented Aug 23, 2016

The feature is incorporated. My comment referred specifically to the previous comment: #7195 (comment).

I remember from the other discussion thread that SFC were supposed to check the nearest class parent and based on it being Pure or not should opt in the being pure themselves.

So “heuristics” for functional components are not in, but PureComponent is.

Loading

@raphaguasta
Copy link

@raphaguasta raphaguasta commented Aug 23, 2016

Great! Thanks guys! :)

Loading

@mmcgahan
Copy link

@mmcgahan mmcgahan commented Aug 23, 2016

Is there a plan to add docs to https://facebook.github.io/react/docs about PureComponent?

I'm running into some unexpected SyntaxError: Unexpected token import errors when running my Jest unit tests on a component that just changed from class Avatar extends React.Component to class Avatar extends React.PureComponent - no other code was touched but I'm not sure where to tweak my configuration without reference docs.

Loading

@koba04
Copy link
Contributor

@koba04 koba04 commented Aug 24, 2016

@mmcgahan #7379

Loading

@gaearon
Copy link
Member

@gaearon gaearon commented Aug 24, 2016

I'm running into some unexpected SyntaxError: Unexpected token import errors when running my Jest unit tests on a component that just changed from class Avatar extends React.Component to class Avatar extends React.PureComponent - no other code was touched but I'm not sure where to tweak my configuration without reference docs.

This seems like something you’d want to file with Jest.

Loading

*/
function ReactPureComponent(props, context, updater) {
// Duplicated from ReactComponent.
this.props = props;
Copy link
Contributor

@zzz6519003 zzz6519003 Jul 5, 2019

Choose a reason for hiding this comment

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

it's not a duplication, right? 🍺

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet