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 #91 from wellyshen/feature/refine-reset
Browse files Browse the repository at this point in the history
Feature/refine reset
  • Loading branch information
wellyshen committed Nov 12, 2020
2 parents 4531319 + f9bc03e commit 47452ba
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 80 deletions.
5 changes: 5 additions & 0 deletions .changeset/honest-lies-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-cool-form": patch
---

refactor: use reset() instead of resetStateRef()
36 changes: 18 additions & 18 deletions examples/src/BasicForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export interface FormValues {
}

const initialValues = {
text: { nest: "" },
controller: "",
text: { nest: "test" },
controller: "test",
hiddenText1: "test",
hiddenText2: "test",
password: "test",
Expand Down Expand Up @@ -125,21 +125,21 @@ export default (): JSX.Element => {
});

// console.log("LOG ===> Re-render");
// console.log(
// "LOG ===> formState: ",
// getState({
// // values: "values",
// // touched: "touched",
// // errors: "errors",
// // isDirty: "isDirty",
// // dirtyFields: "dirtyFields",
// // isValidating: "isValidating",
// // isValid: "isValid",
// // isSubmitting: "isSubmitting",
// // isSubmitted: "isSubmitted",
// // submitCount: "submitCount",
// })
// );
console.log(
"LOG ===> formState: ",
getState({
values: "values",
touched: "touched",
errors: "errors",
isDirty: "isDirty",
dirtyFields: "dirtyFields",
isValidating: "isValidating",
isValid: "isValid",
isSubmitting: "isSubmitting",
isSubmitted: "isSubmitted",
submitCount: "submitCount",
})
);

useEffect(() => {
// validateField("text.nest");
Expand Down Expand Up @@ -321,7 +321,7 @@ export default (): JSX.Element => {
Validate
</button>
<button type="button" onClick={handleResetClick}>
Reset Method
Reset
</button>
<button type="button" onClick={handleSubmit}>
My Submit
Expand Down
9 changes: 0 additions & 9 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,13 @@ export interface SetStateRef {
(path: string, value?: any): void;
}

export interface ResetStateRef<V> {
(
values: V | undefined,
exclude: (keyof FormState<V>)[],
callback: (nextValues: V) => void
): void;
}

export interface SetUsedStateRef {
(path: string): void;
}

export interface FormStateReturn<V> {
stateRef: StateRef<V>;
setStateRef: SetStateRef;
resetStateRef: ResetStateRef<V>;
setUsedStateRef: SetUsedStateRef;
}

Expand Down
49 changes: 37 additions & 12 deletions src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
FieldElement,
Fields,
FieldValidator,
FormState,
FormValues,
GetState,
Reset,
Expand Down Expand Up @@ -111,8 +112,20 @@ const useForm = <V extends FormValues = FormValues>({
const onErrorRef = useLatest(onError);
const ignoreFieldsRef = useRef<UsedRef>(arrayToObject(ignoreFields));
const changedFieldRef = useRef<string>();
const { stateRef, setStateRef, resetStateRef, setUsedStateRef } = useState<V>(
initialValues,
const initialStateRef = useRef<FormState<V>>({
values: initialValues,
touched: {},
errors: {},
isDirty: false,
dirtyFields: {},
isValidating: false,
isValid: true,
isSubmitting: false,
isSubmitted: false,
submitCount: 0,
});
const { stateRef, setStateRef, setUsedStateRef } = useState<V>(
initialStateRef.current,
debug
);

Expand Down Expand Up @@ -447,18 +460,30 @@ const useForm = <V extends FormValues = FormValues>({
if (e?.preventDefault) e.preventDefault();
if (e?.stopPropagation) e.stopPropagation();

resetStateRef(
isFunction(values)
? values(stateRef.current.values)
: values || undefined,
exclude || [],
(nextValues) => setAllDomsValue(nextValues)
);
const state = { ...stateRef.current };
const skip = arrayToObject(exclude || []);

Object.keys(stateRef.current).forEach((key) => {
if (skip[key]) return;

if (key === "values") {
values = isFunction(values)
? values(stateRef.current.values)
: values || initialStateRef.current.values;

state[key] = values;
setAllDomsValue(values);
} else {
// @ts-expect-error
state[key] = initialStateRef.current[key];
}
});

setStateRef("", state);

if (onResetRef.current)
onResetRef.current(stateRef.current.values, getOptions(), e);
if (onResetRef.current) onResetRef.current(state.values, getOptions(), e);
},
[getOptions, onResetRef, resetStateRef, setAllDomsValue, stateRef]
[getOptions, onResetRef, setAllDomsValue, setStateRef, stateRef]
);

const submit = useCallback<Submit<V>>(
Expand Down
58 changes: 17 additions & 41 deletions src/useState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,44 @@ import {
Debug,
FormState,
FormStateReturn,
ResetStateRef,
SetStateRef,
UsedRef,
} from "./types";
import useLatest from "./useLatest";
import { get, isEmptyObject, set } from "./utils";

export default <V>(
initialValues: V,
initialState: FormState<V>,
onChange?: Debug<V>
): FormStateReturn<V> => {
const [, forceUpdate] = useReducer((c) => c + 1, 0);
const initialStateRef = useRef<FormState<V>>({
values: initialValues,
touched: {},
errors: {},
isDirty: false,
dirtyFields: {},
isValidating: false,
isValid: true,
isSubmitting: false,
isSubmitted: false,
submitCount: 0,
});
const initialStateRef = useRef(initialState);
const stateRef = useRef(initialStateRef.current);
const usedStateRef = useRef<UsedRef>({});
const onChangeRef = useLatest(onChange);

const setStateRef = useCallback<SetStateRef>(
(path, value) => {
const key = path.split(".")[0];
const shouldUpdate =
key === "values" || !isEqual(get(stateRef.current, path), value);

if (shouldUpdate) {
const nextState = set(stateRef.current, path, value, true);
if (!key) {
if (!isEqual(stateRef.current, value)) {
stateRef.current = value;
forceUpdate();
}

return;
}

if (key === "values" || !isEqual(get(stateRef.current, path), value)) {
const state = set(stateRef.current, path, value, true);
const {
values,
errors,
isDirty: prevIsDirty,
isValid: prevIsValid,
} = nextState;
let { submitCount: prevSubmitCount } = nextState;
} = state;
let { submitCount: prevSubmitCount } = state;
const isDirty =
key === "values"
? !isEqual(values, initialStateRef.current.values)
Expand All @@ -58,7 +53,7 @@ export default <V>(
? (prevSubmitCount += 1)
: prevSubmitCount;

stateRef.current = { ...nextState, isDirty, isValid, submitCount };
stateRef.current = { ...state, isDirty, isValid, submitCount };

if (onChangeRef.current) onChangeRef.current(stateRef.current);

Expand All @@ -75,28 +70,9 @@ export default <V>(
[onChangeRef]
);

const resetStateRef = useCallback<ResetStateRef<V>>(
(values = initialStateRef.current.values, exclude, callback) => {
Object.keys(initialStateRef.current)
.filter((key) => !exclude.includes(key as keyof FormState<V>))
.forEach((key) => {
if (key === "values") {
stateRef.current[key] = values;
callback(values);
} else {
// @ts-expect-error
stateRef.current[key] = initialStateRef.current[key];
}
});

forceUpdate();
},
[]
);

const setUsedStateRef = useCallback((path: string) => {
usedStateRef.current[path] = true;
}, []);

return { stateRef, setStateRef, resetStateRef, setUsedStateRef };
return { stateRef, setStateRef, setUsedStateRef };
};

0 comments on commit 47452ba

Please sign in to comment.