Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

Commit

Permalink
Merge pull request #93 from wellyshen/feature/unset
Browse files Browse the repository at this point in the history
feat: use unset for clear error
  • Loading branch information
wellyshen authored Nov 12, 2020
2 parents 4df385a + 27a6c50 commit 43f351f
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changeset/tasty-colts-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-cool-form": patch
---

feat: use unset for clear error
33 changes: 17 additions & 16 deletions examples/src/BasicForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,16 @@ export default (): JSX.Element => {
console.log(
"LOG ===> formState: ",
getState({
values: "values",
touched: "touched",
// values: "values",
// touched: "touched",
errors: "errors",
isDirty: "isDirty",
dirtyFields: "dirtyFields",
isValidating: "isValidating",
isValid: "isValid",
isSubmitting: "isSubmitting",
isSubmitted: "isSubmitted",
submitCount: "submitCount",
// isDirty: "isDirty",
// dirtyFields: "dirtyFields",
// isValidating: "isValidating",
// isValid: "isValid",
// isSubmitting: "isSubmitting",
// isSubmitted: "isSubmitted",
// submitCount: "submitCount",
})
);

Expand Down Expand Up @@ -181,7 +181,8 @@ export default (): JSX.Element => {
};

const handleClearErrorsClick = (): void => {
setFieldError("text.nest");
// setFieldError("text.nest");
setFieldError("number");
};

const handleValidateClick = (): void => {
Expand Down Expand Up @@ -232,9 +233,9 @@ export default (): JSX.Element => {
<Input
label="Hidden Text 1:"
name="hiddenText1"
/* ref={validate(async (value) => {
ref={validate(async (value) => {
return value.length <= 5 ? "Field error" : "";
})} */
})}
/>
</div>
)}
Expand All @@ -243,9 +244,9 @@ export default (): JSX.Element => {
<Input
label="Hidden Text 2:"
name="hiddenText2"
/* ref={validate(async (value) => {
ref={validate(async (value) => {
return value.length <= 5 ? "Field error" : "";
})} */
})}
/>
</div>
)}
Expand All @@ -254,9 +255,9 @@ export default (): JSX.Element => {
label="Number:"
type="number"
name="number"
/* ref={validate((value) => {
ref={validate((value) => {
return value <= 5 ? "Field error" : "";
})} */
})}
/>
<Input label="Range:" type="range" name="range" />
<Input label="Checkbox:" type="checkbox" name="checkbox" />
Expand Down
9 changes: 6 additions & 3 deletions src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
isRangeField,
isUndefined,
set,
unset,
warn,
} from "./utils";

Expand Down Expand Up @@ -215,14 +216,16 @@ export default <V extends FormValues = FormValues>({
? error(get(stateRef.current.errors, name))
: error;

if (isKey(name) && !error) {
if (error) {
setStateRef(`errors.${name}`, error);
} else {
setErrors((prevErrors) => {
if (!isKey(name)) return unset(prevErrors, name, true);

const nextErrors = { ...prevErrors };
delete nextErrors[name];
return nextErrors;
});
} else {
setStateRef(`errors.${name}`, error || undefined);
}
},
[setErrors, setStateRef, stateRef]
Expand Down
37 changes: 32 additions & 5 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,50 @@ const cloneObject = (object: unknown): any => {
};

export const set: Set = (object, path, value, immutable = false) => {
if (!isPlainObject(object)) return object;
if (!isPlainObject(object)) throw new TypeError("Expected an object.");

const tempPath = String(path)
const segs = String(path)
.split(/[.[\]]+/)
.filter(Boolean);
const newObject = immutable ? cloneObject(object) : object;

tempPath.slice(0, -1).reduce((obj, key, idx) => {
segs.slice(0, -1).reduce((obj, key, idx) => {
if (isObject(obj[key])) return obj[key];
const next = Number(tempPath[idx + 1]);
const next = Number(segs[idx + 1]);
obj[key] = Number.isInteger(next) && next >= 0 ? [] : {};
return obj[key];
}, newObject)[tempPath[tempPath.length - 1] || ""] = value;
}, newObject)[segs[segs.length - 1] || ""] = value;

return newObject;
};

export const unset = (object: any, path: string, immutable = false): any => {
if (!isPlainObject(object)) throw new TypeError("Expected an object.");

const refObject = immutable ? cloneObject(object) : object;
let newObject = refObject;

// eslint-disable-next-line no-prototype-builtins
if (newObject.hasOwnProperty(path)) {
delete newObject[path];
return refObject;
}

if (!isUndefined(get(newObject, path))) {
const segs = path.split(".");
let last = segs.pop() as string;

while (segs.length && segs[segs.length - 1].slice(-1) === "\\")
last = `${(segs.pop() as string).slice(0, -1)}.${last}`;

while (segs.length) newObject = newObject[(path = segs.shift() as string)];

delete newObject[last];
}

return refObject;
};

export const deepMerge = (...objects: any[]) =>
objects.reduce((prev, obj) => {
Object.keys(obj).forEach((key) => {
Expand Down

0 comments on commit 43f351f

Please sign in to comment.