Improve shouldComponentUpdate for status and status_action_bar (#3323)

This commit is contained in:
Nolan Lawson 2017-05-26 05:05:52 -07:00 committed by Eugen Rochko
parent 7c67cb5997
commit b00cb2aed3
2 changed files with 39 additions and 9 deletions

View file

@ -44,6 +44,35 @@ class Status extends ImmutablePureComponent {
isHidden: false, isHidden: false,
} }
// Avoid checking props that are functions (and whose equality will always
// evaluate to false. See react-immutable-pure-component for usage.
updateOnProps = [
'status',
'account',
'wrapped',
'me',
'boostModal',
'autoPlayGif',
'muted',
]
updateOnStates = []
shouldComponentUpdate (nextProps, nextState) {
if (nextProps.isIntersecting === false && nextState.isHidden) {
// It's only if we're not intersecting (i.e. offscreen) and isHidden is true
// that either "isIntersecting" or "isHidden" matter, and then they're
// the only things that matter.
return this.props.isIntersecting !== false || !this.state.isHidden;
} else if (nextProps.isIntersecting !== false && this.props.isIntersecting === false) {
// If we're going from a non-intersecting state to an intersecting state,
// (i.e. offscreen to onscreen), then we definitely need to re-render
return true;
}
// Otherwise, diff based on "updateOnProps" and "updateOnStates"
return super.shouldComponentUpdate(nextProps, nextState);
}
componentWillReceiveProps (nextProps) { componentWillReceiveProps (nextProps) {
if (nextProps.isIntersecting === false && this.props.isIntersecting !== false) { if (nextProps.isIntersecting === false && this.props.isIntersecting !== false) {
requestIdleCallback(() => this.setState({ isHidden: true })); requestIdleCallback(() => this.setState({ isHidden: true }));
@ -52,14 +81,6 @@ class Status extends ImmutablePureComponent {
} }
} }
shouldComponentUpdate (nextProps, nextState) {
if (nextProps.isIntersecting === false && this.props.isIntersecting !== false) {
return nextState.isHidden;
}
return true;
}
handleRef = (node) => { handleRef = (node) => {
if (this.props.onRef) { if (this.props.onRef) {
this.props.onRef(node); this.props.onRef(node);

View file

@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import IconButton from './icon_button'; import IconButton from './icon_button';
import DropdownMenu from './dropdown_menu'; import DropdownMenu from './dropdown_menu';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
const messages = defineMessages({ const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' }, delete: { id: 'status.delete', defaultMessage: 'Delete' },
@ -21,7 +22,7 @@ const messages = defineMessages({
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' }, unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
}); });
class StatusActionBar extends React.PureComponent { class StatusActionBar extends ImmutablePureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,
@ -43,6 +44,14 @@ class StatusActionBar extends React.PureComponent {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
}; };
// Avoid checking props that are functions (and whose equality will always
// evaluate to false. See react-immutable-pure-component for usage.
updateOnProps = [
'status',
'me',
'withDismiss',
]
handleReplyClick = () => { handleReplyClick = () => {
this.props.onReply(this.props.status, this.context.router); this.props.onReply(this.props.status, this.context.router);
} }