From 1548695c8300618d44efa8785f5c6eb7b3a86917 Mon Sep 17 00:00:00 2001 From: Sorin Davidoi Date: Fri, 19 May 2017 20:58:12 +0200 Subject: [PATCH] Avoid useless renders (#3141) * feat(eslint): Set react/jsx-no-bind: error * refactor(notifications/setting_toggle): Do not use bind * refactor(components/dropdown_menu): Do not use bind * refactor(components/autosuggest_textarea): Do not use bind * refactor(compose/privacy_dropdown): Do not use bind * refactor(compose/upload_form): Do not use bind * refactor(components/status): Do not use bind * refactor(components/onboarding_modal): Do not use bind * refactor: PR feedback * chore(notifications/setting_toggle): Lint * refactor: PR feedback --- .eslintrc.yml | 1 + .../components/autosuggest_textarea.js | 6 ++- .../mastodon/components/dropdown_menu.js | 5 ++- app/javascript/mastodon/components/status.js | 7 ++-- .../compose/components/privacy_dropdown.js | 5 ++- .../compose/components/upload_form.js | 9 ++++- .../components/setting_toggle.js | 38 ++++++++++++------- .../ui/components/onboarding_modal.js | 38 ++++++++++--------- 8 files changed, 68 insertions(+), 41 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index aa23bebbfc5..12bdf342a8b 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -49,6 +49,7 @@ rules: no-trailing-spaces: warn react/jsx-wrap-multilines: error + react/jsx-no-bind: error react/self-closing-comp: error react/prop-types: error react/no-multi-comp: off diff --git a/app/javascript/mastodon/components/autosuggest_textarea.js b/app/javascript/mastodon/components/autosuggest_textarea.js index b3d62ec3a65..24fa2b92057 100644 --- a/app/javascript/mastodon/components/autosuggest_textarea.js +++ b/app/javascript/mastodon/components/autosuggest_textarea.js @@ -145,7 +145,8 @@ class AutosuggestTextarea extends ImmutablePureComponent { }, 100); } - onSuggestionClick (suggestion, e) { + onSuggestionClick (e) { + const suggestion = Number(e.currentTarget.getAttribute('data-index')); e.preventDefault(); this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); this.textarea.focus(); @@ -204,8 +205,9 @@ class AutosuggestTextarea extends ImmutablePureComponent { role='button' tabIndex='0' key={suggestion} + data-index={suggestion} className={`autosuggest-textarea__suggestions__item ${i === selectedSuggestion ? 'selected' : ''}`} - onClick={this.onSuggestionClick.bind(this, suggestion)}> + onClick={this.onSuggestionClick}> ))} diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js index 99432463c19..4b6168f435a 100644 --- a/app/javascript/mastodon/components/dropdown_menu.js +++ b/app/javascript/mastodon/components/dropdown_menu.js @@ -24,7 +24,8 @@ class DropdownMenu extends React.PureComponent { this.dropdown = c; } - handleClick = (i, e) => { + handleClick = (e) => { + const i = Number(e.currentTarget.getAttribute('data-index')); const { action } = this.props.items[i]; if (typeof action === 'function') { @@ -43,7 +44,7 @@ class DropdownMenu extends React.PureComponent { return (
  • - + {text}
  • diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index d2049c44a48..bd62a1e2896 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -43,8 +43,9 @@ class Status extends ImmutablePureComponent { this.context.router.push(`/statuses/${status.getIn(['reblog', 'id'], status.get('id'))}`); } - handleAccountClick = (id, e) => { + handleAccountClick = (e) => { if (e.button === 0) { + const id = Number(e.currentTarget.getAttribute('data-id')); e.preventDefault(); this.context.router.push(`/accounts/${id}`); } @@ -72,7 +73,7 @@ class Status extends ImmutablePureComponent {
    - }} /> + }} />
    @@ -103,7 +104,7 @@ class Status extends ImmutablePureComponent {
    - +
    {statusAvatar}
    diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js index 22bbe68adb5..1e0bb3d0978 100644 --- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js @@ -36,7 +36,8 @@ class PrivacyDropdown extends React.PureComponent { this.setState({ open: !this.state.open }); } - handleClick = (value, e) => { + handleClick = (e) => { + const value = e.currentTarget.getAttribute('data-index'); e.preventDefault(); this.setState({ open: false }); this.props.onChange(value); @@ -80,7 +81,7 @@ class PrivacyDropdown extends React.PureComponent {
    {options.map(item => -
    +
    {item.shortText} diff --git a/app/javascript/mastodon/features/compose/components/upload_form.js b/app/javascript/mastodon/features/compose/components/upload_form.js index f1bd9b7ec00..f2579bf6003 100644 --- a/app/javascript/mastodon/features/compose/components/upload_form.js +++ b/app/javascript/mastodon/features/compose/components/upload_form.js @@ -18,6 +18,11 @@ class UploadForm extends React.PureComponent { intl: PropTypes.object.isRequired }; + onRemoveFile = (e) => { + const id = Number(e.currentTarget.parentElement.getAttribute('data-id')); + this.props.onRemoveFile(id); + } + render () { const { intl, media } = this.props; @@ -25,8 +30,8 @@ class UploadForm extends React.PureComponent {
    {({ scale }) => -
    - +
    +
    } diff --git a/app/javascript/mastodon/features/notifications/components/setting_toggle.js b/app/javascript/mastodon/features/notifications/components/setting_toggle.js index 080804a40e0..80404953125 100644 --- a/app/javascript/mastodon/features/notifications/components/setting_toggle.js +++ b/app/javascript/mastodon/features/notifications/components/setting_toggle.js @@ -3,19 +3,31 @@ import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import Toggle from 'react-toggle'; -const SettingToggle = ({ settings, settingKey, label, onChange, htmlFor = '' }) => ( - -); +class SettingToggle extends React.PureComponent { -SettingToggle.propTypes = { - settings: ImmutablePropTypes.map.isRequired, - settingKey: PropTypes.array.isRequired, - label: PropTypes.node.isRequired, - onChange: PropTypes.func.isRequired, - htmlFor: PropTypes.string -}; + static propTypes = { + settings: ImmutablePropTypes.map.isRequired, + settingKey: PropTypes.array.isRequired, + label: PropTypes.node.isRequired, + onChange: PropTypes.func.isRequired, + htmlFor: PropTypes.string + } + + onChange = (e) => { + this.props.onChange(this.props.settingKey, e.target.checked); + } + + render () { + const { settings, settingKey, label, onChange, htmlFor = '' } = this.props; + + return ( + + ); + } + +} export default SettingToggle; diff --git a/app/javascript/mastodon/features/ui/components/onboarding_modal.js b/app/javascript/mastodon/features/ui/components/onboarding_modal.js index 889ecaaff59..d83a3d5c4f6 100644 --- a/app/javascript/mastodon/features/ui/components/onboarding_modal.js +++ b/app/javascript/mastodon/features/ui/components/onboarding_modal.js @@ -11,6 +11,8 @@ import NavigationBar from '../../compose/components/navigation_bar'; import ColumnHeader from './column_header'; import Immutable from 'immutable'; +const noop = () => { }; + const messages = defineMessages({ home_title: { id: 'column.home', defaultMessage: 'Home' }, notifications_title: { id: 'column.notifications', defaultMessage: 'Notifications' }, @@ -48,14 +50,14 @@ const PageTwo = ({ me }) => ( suggestions={Immutable.List()} mentionedDomains={[]} spoiler={false} - onChange={() => {}} - onSubmit={() => {}} - onPaste={() => {}} - onPickEmoji={() => {}} - onChangeSpoilerText={() => {}} - onClearSuggestions={() => {}} - onFetchSuggestions={() => {}} - onSuggestionSelected={() => {}} + onChange={noop} + onSubmit={noop} + onPaste={noop} + onPickEmoji={noop} + onChangeSpoilerText={noop} + onClearSuggestions={noop} + onFetchSuggestions={noop} + onSuggestionSelected={noop} />
    @@ -72,10 +74,10 @@ const PageThree = ({ me, domain }) => (
    {}} - onSubmit={() => {}} - onClear={() => {}} - onShow={() => {}} + onChange={noop} + onSubmit={noop} + onClear={noop} + onShow={noop} />
    - {pages.map((_, i) =>
    )} + {pages.map((_, i) =>
    )}