diff options
author | Nolan Lawson <nolan@nolanlawson.com> | 2017-05-26 05:05:52 -0700 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2017-05-26 14:05:52 +0200 |
commit | b00cb2aed3634ad6624e144b99d538eb85c58c12 (patch) | |
tree | 2975b9811f64cf18e334734e74c202f20e0b69cb | |
parent | 7c67cb599713cfeec4bdcb5447f36718886da2be (diff) |
Improve shouldComponentUpdate for status and status_action_bar (#3323)
-rw-r--r-- | app/javascript/mastodon/components/status.js | 37 | ||||
-rw-r--r-- | app/javascript/mastodon/components/status_action_bar.js | 11 |
2 files changed, 39 insertions, 9 deletions
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index a1f52226f..5405ddfd1 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -44,6 +44,35 @@ class Status extends ImmutablePureComponent { 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) { if (nextProps.isIntersecting === false && this.props.isIntersecting !== false) { 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) => { if (this.props.onRef) { this.props.onRef(node); diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js index 5457dabac..064d841b8 100644 --- a/app/javascript/mastodon/components/status_action_bar.js +++ b/app/javascript/mastodon/components/status_action_bar.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import IconButton from './icon_button'; import DropdownMenu from './dropdown_menu'; import { defineMessages, injectIntl } from 'react-intl'; +import ImmutablePureComponent from 'react-immutable-pure-component'; const messages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, @@ -21,7 +22,7 @@ const messages = defineMessages({ unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' }, }); -class StatusActionBar extends React.PureComponent { +class StatusActionBar extends ImmutablePureComponent { static contextTypes = { router: PropTypes.object, @@ -43,6 +44,14 @@ class StatusActionBar extends React.PureComponent { 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 = () => { this.props.onReply(this.props.status, this.context.router); } |