From bca904838c4332ea9f124c16bb213a51ce057fca Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Tue, 7 Apr 2020 15:13:53 +0200 Subject: [PATCH] Some additional useCallback (#2525) --- .../src/Accounts/modals/Backup.tsx | 48 ++++++---- .../src/Accounts/modals/Create.tsx | 70 ++++++++------ .../src/Accounts/modals/Derive.tsx | 70 ++++++++------ .../page-accounts/src/Accounts/modals/Qr.tsx | 55 ++++++----- .../src/Contacts/modals/Create.tsx | 95 ++++++++++--------- packages/page-contracts/src/Params.tsx | 11 ++- packages/page-contracts/src/RemoveABI.tsx | 13 ++- packages/page-council/src/Motions/Voting.tsx | 8 +- packages/page-explorer/src/Query.tsx | 20 ++-- 9 files changed, 226 insertions(+), 164 deletions(-) diff --git a/packages/page-accounts/src/Accounts/modals/Backup.tsx b/packages/page-accounts/src/Accounts/modals/Backup.tsx index 627bea593e..87e8502b48 100644 --- a/packages/page-accounts/src/Accounts/modals/Backup.tsx +++ b/packages/page-accounts/src/Accounts/modals/Backup.tsx @@ -5,7 +5,7 @@ import { BareProps } from '@polkadot/react-components/types'; import FileSaver from 'file-saver'; -import React, { useState, useMemo } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { AddressRow, Button, Modal, Password } from '@polkadot/react-components'; import keyring from '@polkadot/ui-keyring'; @@ -34,31 +34,37 @@ function Backup ({ address, onClose }: Props): React.ReactElement { keyring.isPassValid(password) && !backupFailed, [password, backupFailed]); - const _onChangePass = (value: string): void => { - if (!isPassTouched) { - setIsPassTouched(true); - } + const _onChangePass = useCallback( + (value: string): void => { + if (!isPassTouched) { + setIsPassTouched(true); + } - setBackupFailed(false); - setPassword(value); - }; + setBackupFailed(false); + setPassword(value); + }, + [isPassTouched] + ); - const _doBackup = (): void => { - try { - const addressKeyring = address && keyring.getPair(address); - const json = addressKeyring && keyring.backupAccount(addressKeyring, password); - const blob = new Blob([JSON.stringify(json)], { type: 'application/json; charset=utf-8' }); + const _doBackup = useCallback( + (): void => { + try { + const addressKeyring = address && keyring.getPair(address); + const json = addressKeyring && keyring.backupAccount(addressKeyring, password); + const blob = new Blob([JSON.stringify(json)], { type: 'application/json; charset=utf-8' }); - FileSaver.saveAs(blob, `${address}.json`); - } catch (error) { - setBackupFailed(true); - console.error(error); + FileSaver.saveAs(blob, `${address}.json`); + } catch (error) { + setBackupFailed(true); + console.error(error); - return; - } + return; + } - onClose(); - }; + onClose(); + }, + [address, onClose, password] + ); return ( (generateSeed(propsSeed, '', propsSeed ? 'raw' : 'bip', propsType)); - const [isConfirmationOpen, setIsConfirmationOpen] = useState(false); + const [isConfirmationOpen, toggleConfirmation] = useToggle(); const [{ isNameValid, name }, setName] = useState({ isNameValid: false, name: '' }); const [{ isPassValid, password }, setPassword] = useState({ isPassValid: false, password: '' }); const [{ isPass2Valid, password2 }, setPassword2] = useState({ isPass2Valid: false, password2: '' }); @@ -174,20 +174,30 @@ function Create ({ className, onClose, onStatusChange, seed: propsSeed, type: pr { text: t('Raw seed'), value: 'raw' } ), [isDevelopment, t]); - const _onChangePass = (password: string): void => - setPassword({ isPassValid: keyring.isPassValid(password), password }); + const _onChangePass = useCallback( + (password: string) => setPassword({ isPassValid: keyring.isPassValid(password), password }), + [] + ); - const _onChangePass2 = (password2: string): void => - setPassword2({ isPass2Valid: keyring.isPassValid(password2) && (password2 === password), password2 }); + const _onChangePass2 = useCallback( + (password2: string) => setPassword2({ isPass2Valid: keyring.isPassValid(password2) && (password2 === password), password2 }), + [password] + ); - const _onChangeDerive = (newDerivePath: string): void => - setAddress(updateAddress(seed, newDerivePath, seedType, pairType)); + const _onChangeDerive = useCallback( + (newDerivePath: string) => setAddress(updateAddress(seed, newDerivePath, seedType, pairType)), + [pairType, seed, seedType] + ); - const _onChangeSeed = (newSeed: string): void => - setAddress(updateAddress(newSeed, derivePath, seedType, pairType)); + const _onChangeSeed = useCallback( + (newSeed: string) => setAddress(updateAddress(newSeed, derivePath, seedType, pairType)), + [derivePath, pairType, seedType] + ); - const _onChangePairType = (newPairType: KeypairType): void => - setAddress(updateAddress(seed, derivePath, seedType, newPairType)); + const _onChangePairType = useCallback( + (newPairType: KeypairType) => setAddress(updateAddress(seed, derivePath, seedType, newPairType)), + [derivePath, seed, seedType] + ); const _selectSeedType = (newSeedType: SeedType): void => { if (newSeedType !== seedType) { @@ -195,22 +205,26 @@ function Create ({ className, onClose, onStatusChange, seed: propsSeed, type: pr } }; - const _onChangeName = (name: string): void => setName({ isNameValid: !!name.trim(), name }); + const _onChangeName = useCallback( + (name: string) => setName({ isNameValid: !!name.trim(), name }), + [] + ); - const _toggleConfirmation = (): void => setIsConfirmationOpen(!isConfirmationOpen); + const _onCommit = useCallback( + (): void => { + if (!isValid) { + return; + } - const _onCommit = (): void => { - if (!isValid) { - return; - } + const options = { genesisHash: isDevelopment ? undefined : api.genesisHash.toString(), name: name.trim() }; + const status = createAccount(`${seed}${derivePath}`, pairType, options, password, t('created account')); - const options = { genesisHash: isDevelopment ? undefined : api.genesisHash.toString(), name: name.trim() }; - const status = createAccount(`${seed}${derivePath}`, pairType, options, password, t('created account')); - - _toggleConfirmation(); - onStatusChange(status); - onClose(); - }; + toggleConfirmation(); + onStatusChange(status); + onClose(); + }, + [api, derivePath, isDevelopment, isValid, name, onClose, onStatusChange, pairType, password, seed, t, toggleConfirmation] + ); return ( )} @@ -318,7 +332,7 @@ function Create ({ className, onClose, onStatusChange, seed: propsSeed, type: pr isDisabled={!isValid} isPrimary label={t('Save')} - onClick={_toggleConfirmation} + onClick={toggleConfirmation} /> diff --git a/packages/page-accounts/src/Accounts/modals/Derive.tsx b/packages/page-accounts/src/Accounts/modals/Derive.tsx index c5cd89ea4c..d4ed79e81f 100644 --- a/packages/page-accounts/src/Accounts/modals/Derive.tsx +++ b/packages/page-accounts/src/Accounts/modals/Derive.tsx @@ -6,9 +6,9 @@ import { KeyringPair } from '@polkadot/keyring/types'; import { ActionStatus } from '@polkadot/react-components/Status/types'; import { KeypairType } from '@polkadot/util-crypto/types'; -import React, { useContext, useEffect, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useState } from 'react'; import { AddressRow, Button, Input, InputAddress, Modal, Password, StatusContext } from '@polkadot/react-components'; -import { useDebounce } from '@polkadot/react-hooks'; +import { useDebounce, useToggle } from '@polkadot/react-hooks'; import keyring from '@polkadot/ui-keyring'; import { keyExtractPath } from '@polkadot/util-crypto'; @@ -72,7 +72,7 @@ function Derive ({ className, from, onClose }: Props): React.ReactElement { const { queueAction } = useContext(StatusContext); const [source] = useState(keyring.getPair(from)); const [{ address, deriveError }, setDerive] = useState({ address: null, deriveError: null }); - const [isConfirmationOpen, setIsConfirmationOpen] = useState(false); + const [isConfirmationOpen, toggleConfirmation] = useToggle(); const [isLocked, setIsLocked] = useState(source.isLocked); const [{ isNameValid, name }, setName] = useState({ isNameValid: false, name: '' }); const [{ isPassValid, password }, setPassword] = useState({ isPassValid: false, password: '' }); @@ -101,38 +101,48 @@ function Derive ({ className, from, onClose }: Props): React.ReactElement { }); }, [debouncedSuri, source]); - const _onChangeName = (name: string): void => - setName({ isNameValid: !!name.trim(), name }); + const _onChangeName = useCallback( + (name: string) => setName({ isNameValid: !!name.trim(), name }), + [] + ); - const _onChangePass = (password: string): void => - setPassword({ isPassValid: keyring.isPassValid(password), password }); + const _onChangePass = useCallback( + (password: string) => setPassword({ isPassValid: keyring.isPassValid(password), password }), + [] + ); - const _onChangePass2 = (password2: string): void => - setPassword2({ isPass2Valid: keyring.isPassValid(password2) && (password2 === password), password2 }); + const _onChangePass2 = useCallback( + (password2: string) => setPassword2({ isPass2Valid: keyring.isPassValid(password2) && (password2 === password), password2 }), + [password] + ); - const _toggleConfirmation = (): void => setIsConfirmationOpen(!isConfirmationOpen); + const _onUnlock = useCallback( + (): void => { + try { + source.decodePkcs8(rootPass); + } catch (error) { + console.error(error); + } - const _onUnlock = (): void => { - try { - source.decodePkcs8(rootPass); - } catch (error) { - console.error(error); - } + setIsLocked(source.isLocked); + }, + [rootPass, source] + ); - setIsLocked(source.isLocked); - }; + const _onCommit = useCallback( + (): void => { + if (!isValid) { + return; + } - const _onCommit = (): void => { - if (!isValid) { - return; - } + const status = createAccount(source, suri, name, password, t('created account')); - const status = createAccount(source, suri, name, password, t('created account')); - - _toggleConfirmation(); - queueAction(status); - onClose(); - }; + toggleConfirmation(); + queueAction(status); + onClose(); + }, + [isValid, name, onClose, password, queueAction, source, suri, t, toggleConfirmation] + ); const sourceStatic = ( )} @@ -231,7 +241,7 @@ function Derive ({ className, from, onClose }: Props): React.ReactElement { isDisabled={!isValid} isPrimary label={t('Save')} - onClick={_toggleConfirmation} + onClick={toggleConfirmation} /> ) } diff --git a/packages/page-accounts/src/Accounts/modals/Qr.tsx b/packages/page-accounts/src/Accounts/modals/Qr.tsx index c7d9ea7ab6..256ab4923a 100644 --- a/packages/page-accounts/src/Accounts/modals/Qr.tsx +++ b/packages/page-accounts/src/Accounts/modals/Qr.tsx @@ -4,7 +4,7 @@ import { ModalProps } from '../../types'; -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import styled from 'styled-components'; import { AddressRow, Button, Input, InputAddress, Modal } from '@polkadot/react-components'; import { QrScanAddress } from '@polkadot/react-qr'; @@ -27,34 +27,43 @@ function QrModal ({ className, onClose, onStatusChange }: Props): React.ReactEle const [{ isNameValid, name }, setName] = useState({ isNameValid: false, name: '' }); const [scanned, setScanned] = useState(null); - const _onNameChange = (name: string): void => setName({ isNameValid: !!name.trim(), name }); + const _onNameChange = useCallback( + (name: string) => setName({ isNameValid: !!name.trim(), name }), + [] + ); - const _onScan = (scanned: Scanned): void => { - setScanned(scanned); + const _onScan = useCallback( + (scanned: Scanned): void => { + setScanned(scanned); - if (scanned.name) { - _onNameChange(scanned.name); - } - }; + if (scanned.name) { + _onNameChange(scanned.name); + } + }, + [_onNameChange] + ); - const _onSave = (): void => { - if (!scanned || !isNameValid) { - return; - } + const _onSave = useCallback( + (): void => { + if (!scanned || !isNameValid) { + return; + } - const { address, genesisHash } = scanned; + const { address, genesisHash } = scanned; - keyring.addExternal(address, { genesisHash, name: name.trim() }); - InputAddress.setLastValue('account', address); + keyring.addExternal(address, { genesisHash, name: name.trim() }); + InputAddress.setLastValue('account', address); - onStatusChange({ - account: address, - action: 'create', - message: t('created account'), - status: 'success' - }); - onClose(); - }; + onStatusChange({ + account: address, + action: 'create', + message: t('created account'), + status: 'success' + }); + onClose(); + }, + [isNameValid, name, onClose, onStatusChange, scanned, t] + ); return ( const [{ address, isAddressExisting, isAddressValid }, setAddress] = useState<{ address: string; isAddressExisting: boolean; isAddressValid: boolean }>({ address: '', isAddressExisting: false, isAddressValid: false }); const isValid = isAddressValid && isNameValid; - const _onChangeAddress = (input: string): void => { - let address = ''; - let isAddressValid = true; - let isAddressExisting = false; + const _onChangeAddress = useCallback( + (input: string): void => { + let address = ''; + let isAddressValid = true; + let isAddressExisting = false; - try { - address = keyring.encodeAddress( - keyring.decodeAddress(input) - ); - isAddressValid = keyring.isAvailable(address); + try { + address = keyring.encodeAddress( + keyring.decodeAddress(input) + ); + isAddressValid = keyring.isAvailable(address); - if (!isAddressValid) { - const old = keyring.getAddress(address); + if (!isAddressValid) { + const old = keyring.getAddress(address); - if (old) { - const newName = old.meta.name || name; + if (old) { + const newName = old.meta.name || name; - isAddressExisting = true; - isAddressValid = true; + isAddressExisting = true; + isAddressValid = true; - setName({ isNameValid: !!(newName || '').trim(), name: newName }); + setName({ isNameValid: !!(newName || '').trim(), name: newName }); + } } + } catch (error) { + isAddressValid = false; } - } catch (error) { - isAddressValid = false; - } - setAddress({ address: address || input, isAddressExisting, isAddressValid }); - }; + setAddress({ address: address || input, isAddressExisting, isAddressValid }); + }, + [name] + ); - const _onChangeName = (name: string): void => setName({ isNameValid: !!name.trim(), name }); + const _onChangeName = useCallback( + (name: string) => setName({ isNameValid: !!name.trim(), name }), + [] + ); - const _onCommit = (): void => { - const status = { action: 'create' } as ActionStatus; + const _onCommit = useCallback( + (): void => { + const status = { action: 'create' } as ActionStatus; - if (!isValid) { - return; - } + if (!isValid) { + return; + } - try { - keyring.saveAddress(address, { genesisHash: keyring.genesisHash, name: name.trim(), tags: [] }); + try { + keyring.saveAddress(address, { genesisHash: keyring.genesisHash, name: name.trim(), tags: [] }); - status.account = address; - status.status = address ? 'success' : 'error'; - status.message = isAddressExisting - ? t('address edited') - : t('address created'); + status.account = address; + status.status = address ? 'success' : 'error'; + status.message = isAddressExisting + ? t('address edited') + : t('address created'); - InputAddress.setLastValue('address', address); - } catch (error) { - status.status = 'error'; - status.message = error.message; - } + InputAddress.setLastValue('address', address); + } catch (error) { + status.status = 'error'; + status.message = error.message; + } - onStatusChange(status); - onClose(); - }; + onStatusChange(status); + onClose(); + }, + [address, isAddressExisting, isValid, name, onClose, onStatusChange, t] + ); return ( diff --git a/packages/page-contracts/src/Params.tsx b/packages/page-contracts/src/Params.tsx index 9215367d4f..d23a1e9f45 100644 --- a/packages/page-contracts/src/Params.tsx +++ b/packages/page-contracts/src/Params.tsx @@ -6,7 +6,7 @@ import { ContractABIFnArg } from '@polkadot/api-contract/types'; import { TypeDef } from '@polkadot/types/types'; import { RawParams } from '@polkadot/react-params/types'; -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import UIParams from '@polkadot/react-params'; interface Props { @@ -28,14 +28,15 @@ function Params ({ isDisabled, onChange, onEnter, params: propParams }: Props): propParams && setParams(propParams); }, [propParams]); + const _onChange = useCallback( + (values: RawParams) => onChange(values.map(({ value }): any => value)), + [onChange] + ); + if (!params.length) { return null; } - const _onChange = (values: RawParams): void => { - onChange(values.map(({ value }): any => value)); - }; - return ( { const { t } = useTranslation(); - const _onRemove = (): void => { - onClose && onClose(); - onRemove(); - }; + const _onRemove = useCallback( + (): void => { + onClose && onClose(); + onRemove(); + }, + [onClose, onRemove] + ); return ( (null); const [voteValue, setVoteValue] = useState(true); + const _onChangeVote = useCallback( + (vote?: boolean) => setVoteValue(isBoolean(vote) ? vote : true), + [] + ); + if (!hasAccounts) { return null; } - const _onChangeVote = (vote?: boolean): void => setVoteValue(isBoolean(vote) ? vote : true); const isPrime = prime?.toString() === accountId; return ( diff --git a/packages/page-explorer/src/Query.tsx b/packages/page-explorer/src/Query.tsx index 10982f0294..60dc936f82 100644 --- a/packages/page-explorer/src/Query.tsx +++ b/packages/page-explorer/src/Query.tsx @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import styled from 'styled-components'; import { Button, FilterOverlay, Input } from '@polkadot/react-components'; import { isHex } from '@polkadot/util'; @@ -30,13 +30,19 @@ function Query ({ className, value: propsValue }: Props): React.ReactElement setState(stateFromValue(value)); + const _setHash = useCallback( + (value: string): void => setState(stateFromValue(value)), + [] + ); - const _onQuery = (): void => { - if (isValid && value.length !== 0) { - window.location.hash = `/explorer/query/${value}`; - } - }; + const _onQuery = useCallback( + (): void => { + if (isValid && value.length !== 0) { + window.location.hash = `/explorer/query/${value}`; + } + }, + [isValid, value] + ); return (