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

Conversation

Projects
None yet
@sophiebits
Member

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 {

This comment has been minimized.

@gaearon

gaearon Jul 5, 2016

Member

Nit: could be else if for less nesting?

@gaearon

gaearon Jul 5, 2016

Member

Nit: could be else if for less nesting?

This comment has been minimized.

@sophiebits

sophiebits Jul 5, 2016

Member

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

@sophiebits

sophiebits Jul 5, 2016

Member

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

if (this._compositeType === CompositeTypes.PureClass) {
shouldUpdate =
!shallowEqual(prevProps, nextProps) ||
!shallowEqual(inst.state, nextState);

This comment has been minimized.

@gaearon

gaearon Jul 5, 2016

Member

Did you abandon the idea of comparing state by reference?

@gaearon

gaearon Jul 5, 2016

Member

Did you abandon the idea of comparing state by reference?

This comment has been minimized.

@sophiebits

sophiebits Jul 5, 2016

Member

For now. There's a bunch of our internal components that rely on it so probably externally too. (FB-only link: https://fburl.com/373836543.)

@sophiebits

sophiebits Jul 5, 2016

Member

For now. There's a bunch of our internal components that rely on it so probably externally too. (FB-only link: https://fburl.com/373836543.)

This comment has been minimized.

@morenoh149

morenoh149 Aug 8, 2016

Contributor

Do you have to be a fb employee to see the internal link?

@morenoh149

morenoh149 Aug 8, 2016

Contributor

Do you have to be a fb employee to see the internal link?

This comment has been minimized.

@sophiebits

sophiebits Aug 8, 2016

Member

Yes, that's what I meant by "internal".

@sophiebits

sophiebits Aug 8, 2016

Member

Yes, that's what I meant by "internal".

This comment has been minimized.

@kevinSuttle
@kevinSuttle

kevinSuttle Sep 21, 2016

Contributor
@syranide

This comment has been minimized.

Show comment
Hide comment
@syranide

syranide Jul 6, 2016

Contributor

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

Contributor

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

@jimfb

This comment has been minimized.

Show comment
Hide comment
@jimfb

jimfb Jul 6, 2016

Contributor

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.

Contributor

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.

Add React.PureComponent
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

This comment has been minimized.

Show comment
Hide comment
@STRML

STRML Jul 7, 2016

Contributor

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

Contributor

STRML commented Jul 7, 2016

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

@zpao zpao added this to the 15-next milestone Jul 7, 2016

@zpao zpao added the semver-minor label Jul 7, 2016

usmanajmal added a commit to usmanajmal/react that referenced this pull request Jul 11, 2016

Add React.PureComponent (facebook#7195)
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 modified the milestones: 15-next, 15.3.0 Jul 13, 2016

zpao added a commit that referenced this pull request Jul 13, 2016

Add React.PureComponent (#7195)
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

This comment has been minimized.

Show comment
Hide comment
@vlucas

vlucas Jul 14, 2016

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

vlucas commented Jul 14, 2016

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

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Jul 14, 2016

Member

@vlucas

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

Member

gaearon commented Jul 14, 2016

@vlucas

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

@developit

This comment has been minimized.

Show comment
Hide comment
@developit

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

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?

@sophiebits

This comment has been minimized.

Show comment
Hide comment
@sophiebits

sophiebits Jul 15, 2016

Member

That's the plan.

Member

sophiebits commented Jul 15, 2016

That's the plan.

@developit

This comment has been minimized.

Show comment
Hide comment
@developit

developit Jul 15, 2016

Great, thanks.

developit commented Jul 15, 2016

Great, thanks.

@slmgc

This comment has been minimized.

Show comment
Hide comment
@slmgc

slmgc Jul 15, 2016

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

slmgc commented Jul 15, 2016

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

@sebmarkbage

This comment has been minimized.

Show comment
Hide comment
@sebmarkbage

sebmarkbage Jul 15, 2016

Member

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

Member

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. :)

@brycehanscomb

This comment has been minimized.

Show comment
Hide comment
@brycehanscomb

brycehanscomb Jul 30, 2016

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

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?

@Kovensky

This comment has been minimized.

Show comment
Hide comment
@Kovensky

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

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

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Jul 30, 2016

Member

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.

Member

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.

@Andarist

This comment has been minimized.

Show comment
Hide comment
@Andarist

Andarist Jul 30, 2016

Contributor

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?

Contributor

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?

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Jul 30, 2016

Member

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.

Member

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.

@mattkrick mattkrick referenced this pull request Jul 30, 2016

Closed

Upgrade to React 15.3 #132

@raphaguasta

This comment has been minimized.

Show comment
Hide comment
@raphaguasta

raphaguasta 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 :)

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

@sophiebits

This comment has been minimized.

Show comment
Hide comment
@sophiebits

sophiebits Aug 23, 2016

Member

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

Member

sophiebits commented Aug 23, 2016

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

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Aug 23, 2016

Member

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.

Member

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.

@raphaguasta

This comment has been minimized.

Show comment
Hide comment
@raphaguasta

raphaguasta Aug 23, 2016

Great! Thanks guys! :)

raphaguasta commented Aug 23, 2016

Great! Thanks guys! :)

@mmcgahan

This comment has been minimized.

Show comment
Hide comment
@mmcgahan

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

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.

@koba04

This comment has been minimized.

Show comment
Hide comment
@koba04
Contributor

koba04 commented Aug 24, 2016

@mmcgahan #7379

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Aug 24, 2016

Member

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.

Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment