Some additional useCallback (#2525)

This commit is contained in:
Jaco Greeff 2020-04-07 15:13:53 +02:00 committed by GitHub
parent a4f8f6ecbe
commit bca904838c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 226 additions and 164 deletions

View File

@ -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<Props> {
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 (
<Modal

View File

@ -8,11 +8,11 @@ import { KeypairType } from '@polkadot/util-crypto/types';
import { ModalProps } from '../../types';
import FileSaver from 'file-saver';
import React, { useMemo, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import styled from 'styled-components';
import { DEV_PHRASE } from '@polkadot/keyring/defaults';
import { AddressRow, Button, Dropdown, Expander, Input, InputAddress, Modal, Password } from '@polkadot/react-components';
import { useApi } from '@polkadot/react-hooks';
import { useApi, useToggle } from '@polkadot/react-hooks';
import keyring from '@polkadot/ui-keyring';
import uiSettings from '@polkadot/ui-settings';
import { isHex, u8aToHex } from '@polkadot/util';
@ -160,7 +160,7 @@ function Create ({ className, onClose, onStatusChange, seed: propsSeed, type: pr
const { t } = useTranslation();
const { api, isDevelopment } = useApi();
const [{ address, deriveError, derivePath, isSeedValid, pairType, seed, seedType }, setAddress] = useState<AddressState>(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 (
<Modal
@ -221,7 +235,7 @@ function Create ({ className, onClose, onStatusChange, seed: propsSeed, type: pr
<CreateConfirmation
address={address}
name={name}
onClose={_toggleConfirmation}
onClose={toggleConfirmation}
onCommit={_onCommit}
/>
)}
@ -318,7 +332,7 @@ function Create ({ className, onClose, onStatusChange, seed: propsSeed, type: pr
isDisabled={!isValid}
isPrimary
label={t('Save')}
onClick={_toggleConfirmation}
onClick={toggleConfirmation}
/>
</Modal.Actions>
</Modal>

View File

@ -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<DeriveAddress>({ 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 = (
<InputAddress
@ -152,7 +162,7 @@ function Derive ({ className, from, onClose }: Props): React.ReactElement {
<CreateConfirmation
address={address}
name={name}
onClose={_toggleConfirmation}
onClose={toggleConfirmation}
onCommit={_onCommit}
/>
)}
@ -231,7 +241,7 @@ function Derive ({ className, from, onClose }: Props): React.ReactElement {
isDisabled={!isValid}
isPrimary
label={t('Save')}
onClick={_toggleConfirmation}
onClick={toggleConfirmation}
/>
)
}

View File

@ -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<Scanned | null>(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 (
<Modal

View File

@ -5,7 +5,7 @@
import { ActionStatus } from '@polkadot/react-components/Status/types';
import { ModalProps as Props } from '../../types';
import React, { useState } from 'react';
import React, { useCallback, useState } from 'react';
import { AddressRow, Button, Input, InputAddress, Modal } from '@polkadot/react-components';
import keyring from '@polkadot/ui-keyring';
@ -18,63 +18,72 @@ function Create ({ onClose, onStatusChange }: Props): React.ReactElement<Props>
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 (
<Modal header={t('Add an address')}>

View File

@ -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 (
<UIParams
isDisabled={isDisabled}

View File

@ -4,7 +4,7 @@
import { CodeStored } from '@polkadot/app-contracts/types';
import React from 'react';
import React, { useCallback } from 'react';
import { Button, Modal } from '@polkadot/react-components';
import CodeRow from './CodeRow';
@ -19,10 +19,13 @@ interface Props {
function RemoveABI ({ code, onClose, onRemove }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const _onRemove = (): void => {
onClose && onClose();
onRemove();
};
const _onRemove = useCallback(
(): void => {
onClose && onClose();
onRemove();
},
[onClose, onRemove]
);
return (
<Modal

View File

@ -4,7 +4,7 @@
import { AccountId, Hash, Proposal, ProposalIndex } from '@polkadot/types/interfaces';
import React, { useState } from 'react';
import React, { useCallback, useState } from 'react';
import { Button, Icon, Modal, ProposedAction, VoteAccount, VoteActions, VoteToggle } from '@polkadot/react-components';
import { useAccounts, useToggle } from '@polkadot/react-hooks';
import { isBoolean } from '@polkadot/util';
@ -27,11 +27,15 @@ function Voting ({ hash, idNumber, isDisabled, members, prime, proposal }: Props
const [accountId, setAccountId] = useState<string | null>(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 (

View File

@ -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<Pro
const { t } = useTranslation();
const [{ isValid, value }, setState] = useState(stateFromValue(propsValue || ''));
const _setHash = (value: string): void => 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 (
<FilterOverlay className={className}>