From b2d32b2a7ae860e91e67ef5d7e9312a4e4e09645 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sun, 12 Nov 2017 17:05:17 -0800 Subject: [PATCH] Removes all uses of setState, less confusing as we open source --- app/components/DocumentViews/DocumentViews.js | 12 +-- app/components/DropToImport/DropToImport.js | 18 ++-- .../Editor/components/Toolbar/Toolbar.js | 95 +++++++++---------- app/components/Modal/Modal.js | 1 + app/scenes/Settings/Settings.js | 30 +++--- 5 files changed, 70 insertions(+), 86 deletions(-) diff --git a/app/components/DocumentViews/DocumentViews.js b/app/components/DocumentViews/DocumentViews.js index 6a6db851..f98c054b 100644 --- a/app/components/DocumentViews/DocumentViews.js +++ b/app/components/DocumentViews/DocumentViews.js @@ -1,5 +1,6 @@ // @flow import React, { Component } from 'react'; +import { observable } from 'mobx'; import { observer } from 'mobx-react'; import Popover from 'components/Popover'; import styled from 'styled-components'; @@ -27,13 +28,10 @@ type Props = { @observer class DocumentViews extends Component { + @observable opened: boolean = false; anchor: HTMLElement; store: DocumentViewersStore; props: Props; - state: { - opened: boolean, - }; - state = {}; constructor(props: Props) { super(props); @@ -41,11 +39,11 @@ class DocumentViews extends Component { } openPopover = () => { - this.setState({ opened: true }); + this.opened = true; }; closePopover = () => { - this.setState({ opened: false }); + this.opened = false; }; setRef = (ref: HTMLElement) => { @@ -58,7 +56,7 @@ class DocumentViews extends Component { Viewed {this.props.count} {this.props.count === 1 ? 'time' : 'times'} - {this.state.opened && ( + {this.opened && ( { const reader = new FileReader(); @@ -67,7 +65,7 @@ class DropToImport extends Component { }; onDropAccepted = async (files = []) => { - this.setState({ isImporting: true }); + this.isImporting = true; try { let collectionId = this.props.collectionId; @@ -86,7 +84,7 @@ class DropToImport extends Component { } catch (err) { // TODO: show error alert. } finally { - this.setState({ isImporting: false }); + this.isImporting = false; } }; @@ -115,7 +113,7 @@ class DropToImport extends Component { ref={this.props.dropzoneRef} {...props} > - {this.state.isImporting && } + {this.isImporting && } {this.props.children} ); diff --git a/app/components/Editor/components/Toolbar/Toolbar.js b/app/components/Editor/components/Toolbar/Toolbar.js index 7e424099..696e3ed4 100644 --- a/app/components/Editor/components/Toolbar/Toolbar.js +++ b/app/components/Editor/components/Toolbar/Toolbar.js @@ -1,5 +1,7 @@ // @flow import React, { Component } from 'react'; +import { observable } from 'mobx'; +import { observer } from 'mobx-react'; import { Portal } from 'react-portal'; import styled from 'styled-components'; import _ from 'lodash'; @@ -7,28 +9,20 @@ import type { State } from '../../types'; import FormattingToolbar from './components/FormattingToolbar'; import LinkToolbar from './components/LinkToolbar'; +@observer export default class Toolbar extends Component { + @observable active: boolean = false; + @observable focused: boolean = false; + @observable link: ?React$Element; + @observable top: string = ''; + @observable left: string = ''; + props: { state: State, - onChange: Function, + onChange: (state: State) => void, }; menu: HTMLElement; - state: { - active: boolean, - focused: boolean, - link: React$Element, - top: string, - left: string, - }; - - state = { - active: false, - focused: false, - link: null, - top: '', - left: '', - }; componentDidMount = () => { this.update(); @@ -39,11 +33,11 @@ export default class Toolbar extends Component { }; handleFocus = () => { - this.setState({ focused: true }); + this.focused = true; }; handleBlur = () => { - this.setState({ focused: false }); + this.focused = false; }; get linkInSelection(): any { @@ -66,8 +60,11 @@ export default class Toolbar extends Component { const link = this.linkInSelection; if (state.isBlurred || (state.isCollapsed && !link)) { - if (this.state.active && !this.state.focused) { - this.setState({ active: false, link: null, top: '', left: '' }); + if (this.active && !this.focused) { + this.active = false; + this.link = undefined; + this.top = ''; + this.left = ''; } return; } @@ -79,32 +76,25 @@ export default class Toolbar extends Component { // don't display toolbar for code blocks if (state.startBlock.type === 'code') return; - const data = { - ...this.state, - active: true, - link, - focused: !!link, - }; + this.active = true; + this.focused = !!link; + this.link = link; - if (!_.isEqual(data, this.state)) { - const padding = 16; - const selection = window.getSelection(); - const range = selection.getRangeAt(0); - const rect = range.getBoundingClientRect(); + const padding = 16; + const selection = window.getSelection(); + const range = selection.getRangeAt(0); + const rect = range.getBoundingClientRect(); - if (rect.top === 0 && rect.left === 0) { - this.setState(data); - return; - } - - const left = - rect.left + window.scrollX - this.menu.offsetWidth / 2 + rect.width / 2; - data.top = `${Math.round( - rect.top + window.scrollY - this.menu.offsetHeight - )}px`; - data.left = `${Math.round(Math.max(padding, left))}px`; - this.setState(data); + if (rect.top === 0 && rect.left === 0) { + return; } + + const left = + rect.left + window.scrollX - this.menu.offsetWidth / 2 + rect.width / 2; + this.top = `${Math.round( + rect.top + window.scrollY - this.menu.offsetHeight + )}px`; + this.left = `${Math.round(Math.max(padding, left))}px`; }; setRef = (ref: HTMLElement) => { @@ -112,20 +102,21 @@ export default class Toolbar extends Component { }; render() { - const link = this.state.link; - const style = { - top: this.state.top, - left: this.state.left, + top: this.top, + left: this.left, }; return ( - - {link && ( - - )} - {!link && ( + + {this.link ? ( + + ) : ( void, }; +// eslint-disable-next-line injectGlobal` .ReactModal__Overlay { z-index: 100; diff --git a/app/scenes/Settings/Settings.js b/app/scenes/Settings/Settings.js index cb02c89f..6650bc65 100644 --- a/app/scenes/Settings/Settings.js +++ b/app/scenes/Settings/Settings.js @@ -1,5 +1,6 @@ // @flow -import React from 'react'; +import React, { Component } from 'react'; +import { observable } from 'mobx'; import { observer } from 'mobx-react'; import { Link } from 'react-router-dom'; import styled from 'styled-components'; @@ -15,7 +16,7 @@ import { Label } from 'components/Labeled'; import SlackAuthLink from 'components/SlackAuthLink'; @observer -class Settings extends React.Component { +class Settings extends Component { store: SettingsStore; constructor() { @@ -89,7 +90,8 @@ class Settings extends React.Component { } } -class InlineForm extends React.Component { +@observer +class InlineForm extends Component { props: { placeholder: string, buttonLabel: string, @@ -99,11 +101,9 @@ class InlineForm extends React.Component { onSubmit: Function, disabled?: ?boolean, }; - validationTimeout: number; - state = { - validationError: false, - }; + @observable validationError: boolean = false; + validationTimeout: number; componentWillUnmount() { clearTimeout(this.validationTimeout); @@ -114,14 +114,9 @@ class InlineForm extends React.Component { if (this.props.value) { this.props.onSubmit(); } else { - this.setState({ - validationError: true, - }); + this.validationError = true; this.validationTimeout = setTimeout( - () => - this.setState({ - validationError: false, - }), + () => (this.validationError = false), 2500 ); } @@ -129,17 +124,18 @@ class InlineForm extends React.Component { render() { const { placeholder, value, onChange, buttonLabel } = this.props; - const { validationError } = this.state; return (