From 0c4cb602fd23d1e0367d5b1b2bbf76c71184341a Mon Sep 17 00:00:00 2001 From: Chika Date: Wed, 9 Sep 2020 22:26:16 +0300 Subject: [PATCH] refactor useValidation hook --- src/client/Elements/Input.jsx | 35 ++++++--------- src/client/hooks/useValidation.js | 11 ----- src/client/hooks/useValidation.ts | 47 +++++++++++++++++++++ src/client/stores/CalculationStore/index.ts | 23 ++++++---- src/core/types/stores.ts | 13 +++--- 5 files changed, 84 insertions(+), 45 deletions(-) delete mode 100644 src/client/hooks/useValidation.js create mode 100644 src/client/hooks/useValidation.ts diff --git a/src/client/Elements/Input.jsx b/src/client/Elements/Input.jsx index 2a741fe..0daeca8 100644 --- a/src/client/Elements/Input.jsx +++ b/src/client/Elements/Input.jsx @@ -12,6 +12,7 @@ const Input = ({ readonly, type, validation, + rules, pattern, prefix, suffix, @@ -19,38 +20,30 @@ const Input = ({ addonBefore, addonAfter, valueName, - computedValue + computedValue, }) => { const { value, setCurrentValue, debouncedValue } = useStoreValue({ computedValue, valueName, - debounceDelay: TEXT_INPUT_DEBOUNCE_DELAY + debounceDelay: TEXT_INPUT_DEBOUNCE_DELAY, }); const { status } = useStatus(name); - const { errorMessage, validator } = validation || { - errorMessage: '', - validator: () => {} - }; - const { isValid } = useValidation({ value: debouncedValue, validator }); - const getValidateStatus = () => { - if (!debouncedValue) { - return undefined; - } - return isValid === false ? 'error' : 'success'; - }; - const getHelpMessage = () => { - if (!debouncedValue) { - return undefined; - } - return isValid === false && errorMessage; - }; + const { isValid, validateStatus, message } = useValidation({ + elementName: name, + value: debouncedValue, + validation: validation || { + errorMessage: '', + validator: () => {}, + }, + }); return ( { - const [isValid, setIsValid] = useState(false); - useEffect(() => { - const validationResult = validator(value); - setIsValid(validationResult); - }, [value, validator]); - - return { isValid }; -}; diff --git a/src/client/hooks/useValidation.ts b/src/client/hooks/useValidation.ts new file mode 100644 index 0000000..906d634 --- /dev/null +++ b/src/client/hooks/useValidation.ts @@ -0,0 +1,47 @@ +import { ValidateStatus } from 'antd/lib/form/FormItem'; +import { ElementsNames } from 'core/types/elements'; +import { useEffect, useState } from 'react'; +import { useStores } from './useStores'; + +interface IUseValidationArgs { + elementName: ElementsNames; + value: any; + validation: { errorMessage: string; validator: Function }; +} + +export const useValidation = ({ + elementName, + value, + validation: { validator, errorMessage }, +}: IUseValidationArgs) => { + const [isValid, setIsValid] = useState(false); + const { calculationStore } = useStores(); + + useEffect(() => { + const validationResult = validator(value); + setIsValid(validationResult); + calculationStore.setValidation(elementName, validationResult); + }, [value, validator, calculationStore, elementName]); + + const getValidateStatus = (): ValidateStatus | undefined => { + if (!value) { + return undefined; + } + return isValid === false ? 'error' : 'success'; + }; + + const getMessage = (): string | undefined => { + if (!value) { + return undefined; + } + if (isValid === false) { + return errorMessage; + } + }; + + return { + isValid, + validateStatus: getValidateStatus(), + message: getMessage(), + }; +}; diff --git a/src/client/stores/CalculationStore/index.ts b/src/client/stores/CalculationStore/index.ts index 128aa55..6cda8a0 100644 --- a/src/client/stores/CalculationStore/index.ts +++ b/src/client/stores/CalculationStore/index.ts @@ -16,25 +16,32 @@ import { ICalculationStore } from 'core/types/stores'; const CalculationStore: ICalculationStore = observable( assignProperties( { - statuses: initialStatuses, - validations: {}, values: initialValues, - options: initialOptions, - filters: {}, - getValue(sourceValueName: ValuesNames) { return this.values[sourceValueName]; }, + setValue(sourceValueName: ValuesNames, newValue: any) { + this.values[sourceValueName] = newValue; + }, + + statuses: initialStatuses, getStatus(elementName: ElementsNames) { return this.statuses[elementName]; }, - setValue(sourceValueName: ValuesNames, newValue: any) { - this.values[sourceValueName] = newValue; - }, setStatus(elementName: ElementsNames, status: Status) { this.statuses[elementName] = status; }, + + validations: {}, + getValidation(elementName: ElementsNames) { + return this.validations[elementName]; + }, + setValidation(elementName: ElementsNames, validation: boolean) { + this.validations[elementName] = validation; + }, + options: initialOptions, + filters: {}, }, computedEffects, ), diff --git a/src/core/types/stores.ts b/src/core/types/stores.ts index aac30b9..7cbb079 100644 --- a/src/core/types/stores.ts +++ b/src/core/types/stores.ts @@ -3,15 +3,18 @@ import { TElements, ElementsNames } from './elements'; import { TStatuses, Status } from './statuses'; export interface ICalculationStore { - statuses: TStatuses; - validations: TElements; - values: TValues; options: TElements; filters: TElements; + values: TValues; getValue: (sourceValueName: ValuesNames) => any; - getStatus: (elementName: ElementsNames) => Status; - setValue: (sourceValueName: ValuesNames, newValue: any) => void; + + statuses: TStatuses; + getStatus: (elementName: ElementsNames) => Status; setStatus: (elementName: ElementsNames, status: Status) => void; + + validations: TElements; + getValidation: (elementName: ElementsNames) => boolean; + setValidation: (elementName: ElementsNames, validation: boolean) => void; }