diff --git a/packages/page-toolbox/src/Hash.tsx b/packages/page-toolbox/src/Hash.tsx index 49d6f85e77..668eeb544f 100644 --- a/packages/page-toolbox/src/Hash.tsx +++ b/packages/page-toolbox/src/Hash.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 { Input, Output, Static } from '@polkadot/react-components'; import { hexToU8a, isHex, stringToU8a } from '@polkadot/util'; import { blake2AsHex } from '@polkadot/util-crypto'; @@ -15,7 +15,7 @@ interface State { isHexData: boolean; } -function Hash (): React.ReactElement<{}> { +function Hash (): React.ReactElement { const { t } = useTranslation(); const [{ data, hash, isHexData }, setState] = useState({ data: '', @@ -23,20 +23,23 @@ function Hash (): React.ReactElement<{}> { isHexData: false }); - const _onChangeData = (data: string): void => { - const isHexData = isHex(data); + const _onChangeData = useCallback( + (data: string): void => { + const isHexData = isHex(data); - setState({ - data, - hash: blake2AsHex( + setState({ + data, + hash: blake2AsHex( + isHexData + ? hexToU8a(data) + : stringToU8a(data), + 256 + ), isHexData - ? hexToU8a(data) - : stringToU8a(data), - 256 - ), - isHexData - }); - }; + }); + }, + [] + ); return (
diff --git a/packages/page-toolbox/src/Rpc/Account.tsx b/packages/page-toolbox/src/Rpc/Account.tsx index 57fd0f3399..d59eced767 100644 --- a/packages/page-toolbox/src/Rpc/Account.tsx +++ b/packages/page-toolbox/src/Rpc/Account.tsx @@ -3,7 +3,7 @@ // of the Apache-2.0 license. See the LICENSE file for details. import BN from 'bn.js'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { InputAddress, Labelled } from '@polkadot/react-components'; import { Nonce } from '@polkadot/react-query'; @@ -22,15 +22,9 @@ function Account ({ className, defaultValue, isError, onChange }: Props): React. const [accountId, setAccountId] = useState(defaultValue); const [accountNonce, setAccountNonce] = useState(new BN(0)); - const _onChangeAccountId = (accountId: string | null): void => { - setAccountId(accountId); + useEffect((): void => { onChange(accountId, accountNonce); - }; - - const _onChangeAccountNonce = (accountNonce: BN): void => { - setAccountNonce(accountNonce); - onChange(accountId, accountNonce); - }; + }, [accountId, accountNonce, onChange]); return (
@@ -39,7 +33,7 @@ function Account ({ className, defaultValue, isError, onChange }: Props): React. defaultValue={defaultValue} isError={isError} label={t('sign data from account')} - onChange={_onChangeAccountId} + onChange={setAccountId} placeholder='0x...' type='account' /> @@ -50,7 +44,7 @@ function Account ({ className, defaultValue, isError, onChange }: Props): React. label={t('with an index of')} > diff --git a/packages/page-toolbox/src/Rpc/Results.tsx b/packages/page-toolbox/src/Rpc/Results.tsx index 397d705f1a..d87f3f278d 100644 --- a/packages/page-toolbox/src/Rpc/Results.tsx +++ b/packages/page-toolbox/src/Rpc/Results.tsx @@ -15,9 +15,7 @@ interface Props extends BareProps { function Results ({ queue = [] }: Props): React.ReactElement | null { const filtered = queue - .filter(({ error, result }): boolean => - !isUndefined(error) || !isUndefined(result) - ) + .filter(({ error, result }) => !isUndefined(error) || !isUndefined(result)) .reverse(); if (!filtered.length) { diff --git a/packages/page-toolbox/src/Rpc/Selection.tsx b/packages/page-toolbox/src/Rpc/Selection.tsx index 9d11340f9d..691e92d850 100644 --- a/packages/page-toolbox/src/Rpc/Selection.tsx +++ b/packages/page-toolbox/src/Rpc/Selection.tsx @@ -3,20 +3,19 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { ParamDef, RawParam } from '@polkadot/react-params/types'; -import { I18nProps } from '@polkadot/react-components/types'; import { QueueTxRpcAdd } from '@polkadot/react-components/Status/types'; import { DefinitionRpcExt } from '@polkadot/types/types'; -import React from 'react'; -import { Button, InputRpc, TxComponent } from '@polkadot/react-components'; +import React, { useCallback, useState } from 'react'; +import { Button, InputRpc } from '@polkadot/react-components'; import Params from '@polkadot/react-params'; import jsonrpc from '@polkadot/types/interfaces/jsonrpc'; import { getTypeDef } from '@polkadot/types'; import { isNull } from '@polkadot/util'; -import translate from '../translate'; +import { useTranslation } from '../translate'; -interface Props extends I18nProps { +interface Props { queueRpc: QueueTxRpcAdd; } @@ -29,57 +28,21 @@ interface State { const defaultMethod = jsonrpc.author.submitExtrinsic; -class Selection extends TxComponent { - public state: State = { +function Selection ({ queueRpc }: Props): React.ReactElement { + const { t } = useTranslation(); + const [{ accountId, isValid, rpc, values }, setState] = useState({ accountId: null, isValid: false, rpc: defaultMethod, values: [] - }; + }); - public render (): React.ReactNode { - const { t } = this.props; - const { isValid, rpc } = this.state; - const params = rpc.params.map(({ isOptional, name, type }): ParamDef => ({ - name, - type: getTypeDef(isOptional ? `Option<${type}>` : type) - })); - - return ( -
- - - -
- ); - } - - private nextState (newState: Partial): void { - this.setState( - (prevState: State): State => { + const _nextState = useCallback( + (newState: Partial): void => + setState((prevState: State): State => { const { accountId = prevState.accountId, rpc = prevState.rpc, values = prevState.values } = newState; const reqCount = rpc.params.reduce((count, { isOptional }): number => count + (isOptional ? 0 : 1), 0); - const isValid = values.reduce((isValid, value): boolean => { - return isValid && value.isValid === true; - }, reqCount <= values.length); + const isValid = values.reduce((isValid, value) => isValid && value.isValid === true, reqCount <= values.length); return { accountId, @@ -87,33 +50,59 @@ class Selection extends TxComponent { rpc, values }; - } - ); - } + }), + [] + ); - private onChangeMethod = (rpc: DefinitionRpcExt): void => { - this.nextState({ - rpc, - values: [] as RawParam[] - }); - } + const _onChangeMethod = useCallback( + (rpc: DefinitionRpcExt): void => _nextState({ rpc, values: [] }), + [_nextState] + ); - private onChangeValues = (values: RawParam[]): void => { - this.nextState({ values }); - } + const _onChangeValues = useCallback( + (values: RawParam[]): void => _nextState({ values }), + [_nextState] + ); - private onSubmit = (): void => { - const { queueRpc } = this.props; - const { accountId, rpc, values } = this.state; - - queueRpc({ + const _onSubmit = useCallback( + (): void => queueRpc({ accountId, rpc, values: values .filter(({ value }): boolean => !isNull(value)) .map(({ value }): any => value) - }); - } + }), + [accountId, queueRpc, rpc, values] + ); + + const params = rpc.params.map(({ isOptional, name, type }): ParamDef => ({ + name, + type: getTypeDef(isOptional ? `Option<${type}>` : type) + })); + + return ( +
+ + + +
+ ); } -export default translate(Selection); +export default React.memo(Selection); diff --git a/packages/page-toolbox/src/Rpc/index.tsx b/packages/page-toolbox/src/Rpc/index.tsx index c2af472142..ca6c5c13b0 100644 --- a/packages/page-toolbox/src/Rpc/index.tsx +++ b/packages/page-toolbox/src/Rpc/index.tsx @@ -2,24 +2,20 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { QueueProps } from '@polkadot/react-components/Status/types'; - -import React from 'react'; -import { QueueConsumer } from '@polkadot/react-components/Status/Context'; +import React, { useContext } from 'react'; +import { StatusContext } from '@polkadot/react-components'; import Results from './Results'; import Selection from './Selection'; function RpcApp (): React.ReactElement { + const { queueRpc, txqueue } = useContext(StatusContext); + return ( - - {({ queueRpc, txqueue }: QueueProps): React.ReactNode => ( - <> - - - - )} - + <> + + + ); } diff --git a/packages/react-components/src/InputRpc/index.tsx b/packages/react-components/src/InputRpc/index.tsx index cc27b1ce27..43c39c18cd 100644 --- a/packages/react-components/src/InputRpc/index.tsx +++ b/packages/react-components/src/InputRpc/index.tsx @@ -7,7 +7,7 @@ import { DefinitionRpcExt } from '@polkadot/types/types'; import { DropdownOptions } from '../util/types'; -import React, { useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { useApi } from '@polkadot/react-hooks'; import jsonrpc from '@polkadot/types/interfaces/jsonrpc'; @@ -34,26 +34,35 @@ function InputRpc ({ className, defaultValue, help, label, onChange, style, with const [optionsSection] = useState(sectionOptions(api)); const [value, setValue] = useState((): DefinitionRpcExt => defaultValue); - const _onMethodChange = (newValue: DefinitionRpcExt): void => { - if (value.section === newValue.section && value.method === newValue.method) { - return; - } + useEffect((): void => { + onChange && onChange(value); + }, [onChange, value]); - // set via callback since the method is a function itself - setValue((): DefinitionRpcExt => newValue); - onChange && onChange(newValue); - }; + const _onMethodChange = useCallback( + (newValue: DefinitionRpcExt): void => { + if (value.section === newValue.section && value.method === newValue.method) { + return; + } - const _onSectionChange = (section: string): void => { - if (section === value.section) { - return; - } + // set via callback since the method is a function itself + setValue((): DefinitionRpcExt => newValue); + }, + [value] + ); - const optionsMethod = methodOptions(api, section); + const _onSectionChange = useCallback( + (section: string): void => { + if (section === value.section) { + return; + } - setOptionsMethod(optionsMethod); - _onMethodChange(jsonrpc[section][optionsMethod[0].value]); - }; + const optionsMethod = methodOptions(api, section); + + setOptionsMethod(optionsMethod); + _onMethodChange(jsonrpc[section][optionsMethod[0].value]); + }, + [_onMethodChange, api, value] + ); return (