Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eslint: add hook rules #771

Merged
merged 5 commits into from May 14, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to鈥
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -19,12 +19,14 @@
},
"sourceType": "module"
},
"plugins": ["prettier", "react", "import", "promise"],
"plugins": ["prettier", "react", "react-hooks", "import", "promise"],
"rules": {
"react/prop-types": 'warn',
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"import/no-unresolved": ["error", { ignore: ["^react(-dom)?$", "^styled-components$"] }],
"promise/no-nesting": ["off"],
"valid-jsdoc": "error",
"react/prop-types": 'warn',
"linebreak-style": ["error", "unix"],
},
"settings": {
@@ -70,6 +70,7 @@
"eslint-plugin-prettier": "^2.7.0",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-react": "^7.5.1",
"eslint-plugin-react-hooks": "^1.6.0",
"eslint-plugin-standard": "^4.0.0",
"husky": "^1.0.1",
"lint-staged": "^8.1.1",
@@ -21,7 +21,7 @@ const ActivityPanel = React.memo(
if (open) {
frameRef.current.focus()
}
}, [frameRef.current, open])
}, [frameRef, open])

This comment has been minimized.

Copy link
@sohkai

sohkai May 8, 2019

Author Member

As it turns out, we're not supposed to use ref.current in the dependency list, but simply ref (e.g. https://reactjs.org/docs/hooks-faq.html#how-to-read-an-often-changing-value-from-usecallback)

This comment has been minimized.

Copy link
@bpierre

bpierre May 8, 2019

Member

TIL, thanks!


const handleBlur = useCallback(
event => {
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useCallback, useEffect } from 'react'
import PropTypes from 'prop-types'
import { LocalIdentityModalContext } from '../LocalIdentityModal/LocalIdentityModalManager'
import { isAddress } from '../../web3-utils'
@@ -11,22 +11,20 @@ import LocalIdentityPopoverTitle from './LocalIdentityPopoverTitle'

const LocalIdentityBadge = ({ entity, ...props }) => {
const address = isAddress(entity) ? entity : null
if (address === null) {
return <IdentityBadgeWithNetwork {...props} customLabel={entity} />
}

const { resolve, identityEvents$ } = React.useContext(IdentityContext)
const { showLocalIdentityModal } = React.useContext(LocalIdentityModalContext)
const [label, setLabel] = React.useState(null)
const handleResolve = async () => {
const handleResolve = useCallback(async () => {
try {
const { name = null } = await resolve(address)
setLabel(name)
} catch (e) {
// address does not resolve to identity
}
}
const handleClick = () => {
}, [address, resolve])

const handleClick = useCallback(() => {
showLocalIdentityModal(address)
.then(handleResolve)
.then(() =>
@@ -35,16 +33,22 @@ const LocalIdentityBadge = ({ entity, ...props }) => {
.catch(e => {
/* user cancelled modify intent */
})
}
const handleEvent = updatedAddress => {
if (updatedAddress.toLowerCase() === address.toLowerCase()) {
handleResolve()
}
}
const clearLabel = () => {
}, [address, identityEvents$, handleResolve, showLocalIdentityModal])

const handleEvent = useCallback(
updatedAddress => {
if (updatedAddress.toLowerCase() === address.toLowerCase()) {
handleResolve()
}
},
[address, handleResolve]
)

const clearLabel = useCallback(() => {
setLabel(null)
}
React.useEffect(() => {
}, [])

useEffect(() => {
handleResolve()
const subscription = identityEvents$.subscribe(event => {
switch (event.type) {
@@ -59,7 +63,11 @@ const LocalIdentityBadge = ({ entity, ...props }) => {
return () => {
subscription.unsubscribe()
}
}, [entity, identityEvents$])
}, [clearLabel, entity, handleEvent, handleResolve, identityEvents$])

if (address === null) {
return <IdentityBadgeWithNetwork {...props} customLabel={entity} />
}

return (
<IdentityBadgeWithNetwork
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useCallback, useEffect } from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { Button, TextInput, breakpoint, font, theme } from '@aragon/ui'
@@ -11,7 +11,7 @@ const LocalIdentityModal = ({ opened, ...props }) => {
const { showModal, hideModal } = React.useContext(ModalContext)
React.useEffect(() => {
opened ? showModal(Modal, props) : hideModal()
}, [opened])
}, [opened, showModal, hideModal, props])

return null
}
@@ -24,10 +24,12 @@ const Modal = ({ address, label, onCancel, onSave }) => {
const [action, setAction] = React.useState(null)
const [error, setError] = React.useState(null)
const labelInput = React.useRef(null)
const handleCancel = () => {

const handleCancel = useCallback(() => {
onCancel()
}
const handleSave = () => {
}, [onCancel])

const handleSave = useCallback(() => {
try {
const label = labelInput.current.value.trim()
if (label) {
@@ -36,21 +38,26 @@ const Modal = ({ address, label, onCancel, onSave }) => {
} catch (e) {
setError(e)
}
}
const handlekeyDown = e => {
if (e.keyCode === keycodes.enter) {
handleSave()
} else if (e.keyCode === keycodes.esc) {
handleCancel()
}
}
React.useEffect(() => {
}, [address, labelInput, onSave])

const handleKeyDown = useCallback(
e => {
if (e.keyCode === keycodes.enter) {
handleSave()
} else if (e.keyCode === keycodes.esc) {
handleCancel()
}
},
[handleCancel, handleSave]
)

useEffect(() => {
setAction(label && label.trim() ? 'Edit' : 'Add')
labelInput.current.focus()
labelInput.current.select()
window.addEventListener('keydown', handlekeyDown)
return () => window.removeEventListener('keydown', handlekeyDown)
}, [])
window.addEventListener('keydown', handleKeyDown)
return () => window.removeEventListener('keydown', handleKeyDown)
}, [label, labelInput, handleKeyDown])

return (
<EscapeOutside onEscapeOutside={onCancel}>
@@ -114,17 +114,20 @@ const LocalIdentities = React.memo(
const { showLocalIdentityModal } = React.useContext(
LocalIdentityModalContext
)
const updateLabel = React.useCallback(address => async () => {
try {
await showLocalIdentityModal(address)
// preferences get all
onModifyEvent()
// for iframe apps
identityEvents$.next({ type: identityEventTypes.MODIFY, address })
} catch (e) {
/* nothing was updated */
}
})
const updateLabel = React.useCallback(
address => async () => {
try {
await showLocalIdentityModal(address)
// preferences get all
onModifyEvent()
// for iframe apps
identityEvents$.next({ type: identityEventTypes.MODIFY, address })
} catch (e) {
/* nothing was updated */
}
},
[identityEvents$, onModifyEvent, showLocalIdentityModal]
)

const [allSelected, someSelected] = React.useMemo(
() => [
@@ -145,7 +148,7 @@ const LocalIdentities = React.memo(
{ type: 'text/json' }
)
saveAs(blob, `aragon-labels_${dao}_${today}.json`)
}, [identities, addressesSelected])
}, [identities, dao, addressesSelected])

if (!identities.length) {
return <EmptyLocalIdentities onImport={onImport} />
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useCallback, useEffect } from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { Transition, animated } from 'react-spring'
@@ -28,47 +28,62 @@ const Preferences = React.memo(({ dao, onClose, smallView, wrapper }) => {
const { identityEvents$ } = React.useContext(IdentityContext)
const [selectedTab, setSelectedTab] = React.useState(0)
const [localIdentities, setLocalIdentities] = React.useState({})
const handleGetAll = async () => {

const handleGetAll = useCallback(async () => {
if (!wrapper) {
return
}
setLocalIdentities(await wrapper.getLocalIdentities())
}
const handleClearAll = async () => {
}, [wrapper])

const handleClearAll = useCallback(async () => {
if (!wrapper) {
return
}
await wrapper.clearLocalIdentities()
setLocalIdentities({})
identityEvents$.next({ type: identityEventTypes.CLEAR })
}
const handleModify = (address, data) => {
if (!wrapper) {
return
}
wrapper.modifyAddressIdentity(address, data)
}
const handleImport = async list => {
if (!wrapper) {
return
}
await wrapper.clearLocalIdentities()
for (const { name, address } of list) {
await wrapper.modifyAddressIdentity(address, { name })
}
setLocalIdentities(await wrapper.getLocalIdentities())
identityEvents$.next({ type: identityEventTypes.IMPORT })
}
const handlekeyDown = e => {
if (e.keyCode === keycodes.esc) {
onClose()
}
}
React.useEffect(() => {
}, [identityEvents$, wrapper])

const handleModify = useCallback(
(address, data) => {
if (!wrapper) {
return
}
wrapper.modifyAddressIdentity(address, data)
},
[wrapper]
)

const handleImport = useCallback(
async list => {
if (!wrapper) {
return
}
await wrapper.clearLocalIdentities()
for (const { name, address } of list) {
await wrapper.modifyAddressIdentity(address, { name })
}
setLocalIdentities(await wrapper.getLocalIdentities())
identityEvents$.next({ type: identityEventTypes.IMPORT })
},
[identityEvents$, wrapper]
)

const handlekeyDown = useCallback(
e => {
if (e.keyCode === keycodes.esc) {
onClose()
}
},
[onClose]
)

useEffect(() => {
handleGetAll()
window.addEventListener('keydown', handlekeyDown)
return () => window.removeEventListener('keydown', handlekeyDown)
}, [])
}, [handleGetAll, handlekeyDown])

return (
<AppView
@@ -21,7 +21,7 @@ const UpgradeModal = React.memo(({ visible, onUpgrade, onClose }) => {
if (visible) {
setStep(0)
}
}, [visible])
}, [setStep, visible])

return (
<Viewport>
@@ -86,7 +86,7 @@ const UpgradeOrganizationPanel = React.memo(
// Or, the user just can't perform this action.
await wrapper.performTransactionPath(upgradePath.path)
}
}, [repos, wrapper])
}, [daoAddress, onClose, repos, wrapper])

return (
<SidePanel
ProTip! Use n and p to navigate between commits in a pull request.
You can鈥檛 perform that action at this time.