-
Notifications
You must be signed in to change notification settings - Fork 0
/
useFieldError.ts
75 lines (66 loc) · 1.81 KB
/
useFieldError.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { useMemo } from "react";
import { UseMainContextArg, UseMainContextReturn } from "./useMainContext";
import { get, isEqual } from "lodash";
import { ValuesFields } from "../types/ValuesFields";
import useEventCallback from "use-event-callback";
import { BaseValues } from "../types/BaseValues";
export interface UseFieldErrorArg<Name> {
name: Name;
}
export interface UseFieldErrorReturn {
error: string | undefined;
/**
* Set the fields error state.
*
* @param {string|undefined} error
*/
changeError: (error: string | undefined) => void;
}
/**
* @private
*/
export interface CreateUseFieldErrorDependencies<
Values extends BaseValues,
ExtraContext extends Record<string, unknown>
> {
useMainContext: (
arg: UseMainContextArg<Values, ExtraContext>
) => UseMainContextReturn<Values, ExtraContext>;
}
/**
* @private
*/
export const createUseFieldError = <
Values extends BaseValues,
ExtraContext extends Record<string, unknown>
>({
useMainContext,
}: CreateUseFieldErrorDependencies<Values, ExtraContext>) => {
/**
* Get or change the fields error.
*
* @param {UseFieldErrorArg<Name>} arg
* @returns {UseFieldErrorReturn}
*/
const useFieldError = <Name extends ValuesFields<Values>>({
name,
}: UseFieldErrorArg<Name>): UseFieldErrorReturn => {
const { errors, setFieldError } = useMainContext({
shouldUpdate: (oldValue, newValue) => {
return !isEqual(get(oldValue.errors, name), get(newValue.errors, name));
},
});
const error = useMemo(() => errors[name], [errors, name]);
const changeError = useEventCallback((newError: string | undefined) => {
setFieldError(name, newError);
});
return useMemo(
() => ({
error,
changeError,
}),
[error, changeError]
);
};
return useFieldError;
};