Skip to content

Commit 7c1e6a8

Browse files
committed
bug fix setStateSchema not enabling button if there's no error
1 parent 15c288f commit 7c1e6a8

File tree

5 files changed

+44
-37
lines changed

5 files changed

+44
-37
lines changed

src/App.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import Form from './Form';
2+
import Form from './example/Form';
33

44
import logo from './logo.svg';
55
import './App.css';
File renamed without changes.

src/Form/index.js renamed to src/example/Form/index.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect } from 'react';
2-
import useForm from '../useForm';
2+
import useForm from '../../lib';
33
import './index.css';
44

55
function Form() {
@@ -10,7 +10,7 @@ function Form() {
1010
tags: { value: '', error: '' },
1111
};
1212

13-
const delay = () => new Promise(resolve => setTimeout(resolve, 3000));
13+
const delay = () => new Promise((resolve) => setTimeout(resolve, 3000));
1414

1515
// Create your own validationStateSchema
1616
// stateSchema property should be the same in validationStateSchema
@@ -19,21 +19,21 @@ function Form() {
1919
first_name: {
2020
required: true,
2121
validator: {
22-
func: value => /^[a-zA-Z]+$/.test(value),
22+
func: (value) => /^[a-zA-Z]+$/.test(value),
2323
error: 'Invalid first name format.',
2424
},
2525
},
2626
last_name: {
2727
required: true,
2828
validator: {
29-
func: value => /^[a-zA-Z]+$/.test(value),
29+
func: (value) => /^[a-zA-Z]+$/.test(value),
3030
error: 'Invalid last name format.',
3131
},
3232
},
3333
tags: {
34-
required: true,
34+
// required: true,
3535
validator: {
36-
func: value => /^(,?\w{3,})+$/.test(value),
36+
func: (value) => /^(,?\w{3,})+$/.test(value),
3737
error: 'Invalid tag format.',
3838
},
3939
},

src/useForm.js renamed to src/lib/index.js

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,24 @@ function useForm(
2525
// Get a local copy of stateSchema
2626
useEffect(() => {
2727
setStateSchema(stateSchema);
28-
setDisable(true); // Disable button in initial render.
28+
2929
setInitialErrorState();
3030
}, []); // eslint-disable-line
3131

32-
// Set a brand new field values and errors
32+
// Set a brand new field values and errors
3333
// If stateSchema changes
3434
useEffect(() => {
3535
const values = get_prop_values(state, VALUE);
36+
const errors = Object.keys(values).reduce((accu, curr) => {
37+
accu[curr] = validateField(curr, values[curr]);
38+
return accu;
39+
}, {});
40+
41+
// Marked form as dirty if state was changed.
42+
setIsDirty(true);
43+
3644
setValues(values);
37-
setErrors(
38-
Object.keys(values).reduce((accu, curr) => {
39-
accu[curr] = validateField(curr, values[curr]);
40-
return accu;
41-
}, {})
42-
);
45+
setErrors(errors);
4346
}, [state]); // eslint-disable-line
4447

4548
// For every changed in our state this will be fired
@@ -50,35 +53,41 @@ function useForm(
5053
}
5154
}, [errors, isDirty]); // eslint-disable-line
5255

53-
// Set a value of a specific field
56+
// Set field value to specific field.
5457
const setFieldValue = ({ name, value }) => {
55-
setValues(prevState => ({ ...prevState, [name]: value }));
56-
setDirty(prevState => ({ ...prevState, [name]: true }));
58+
setValues((prevState) => ({ ...prevState, [name]: value }));
59+
setDirty((prevState) => ({ ...prevState, [name]: true }));
5760
};
5861

59-
// Set an error of a specific field
60-
const setFieldError = ({ name, error }) =>
61-
setErrors(prevState => ({ ...prevState, [name]: error }));
62+
// Set to specific field.
63+
const setFieldError = ({ name, error }) => {
64+
setErrors((prevState) => ({ ...prevState, [name]: error }));
65+
};
6266

63-
// Validate fields in forms
67+
// Function used to validate form fields
6468
const validateField = useCallback(
6569
(name, value) => {
66-
const validator = stateValidatorSchema;
70+
const fieldValidator = stateValidatorSchema[name];
6771
// Making sure that stateValidatorSchema name is same in
6872
// stateSchema
69-
if (!validator[name]) return;
70-
71-
const field = validator[name];
73+
if (!fieldValidator) {
74+
return;
75+
}
7276

7377
let error = '';
74-
error = is_required(value, field.required);
78+
error = is_required(value, fieldValidator['required']);
7579

76-
if (is_object(field['validator']) && error === '') {
77-
const validateFieldByCallback = field['validator'];
80+
// Bail out if field is not required and no value set.
81+
// To prevent proceeding to validator function
82+
if (!fieldValidator['required'] && !value) {
83+
return error;
84+
}
7885

86+
// Run custom validator function
87+
if (error === '' && is_object(fieldValidator['validator'])) {
7988
// Test the function callback if the value is meet the criteria
80-
if (!validateFieldByCallback['func'](value, values)) {
81-
error = validateFieldByCallback['error'];
89+
if (!fieldValidator['validator']['func'](value, values)) {
90+
error = fieldValidator['validator']['error'];
8291
}
8392
}
8493

@@ -90,7 +99,7 @@ function useForm(
9099
// Set Initial Error State
91100
// When hooks was first rendered...
92101
const setInitialErrorState = useCallback(() => {
93-
Object.keys(errors).map(name =>
102+
Object.keys(errors).map((name) =>
94103
setFieldError({ name, error: validateField(name, values[name]) })
95104
);
96105
}, [errors, values, validateField]);
@@ -100,14 +109,14 @@ function useForm(
100109
// Wrapped in useCallback to cached the function to avoid intensive memory leaked
101110
// in every re-render in component
102111
const validateErrorState = useCallback(
103-
() => Object.values(errors).some(error => error),
112+
() => Object.values(errors).some((error) => error),
104113
[errors]
105114
);
106115

107116
// Use this callback function to safely submit the form
108117
// without any errors in state...
109118
const handleOnSubmit = useCallback(
110-
event => {
119+
(event) => {
111120
event.preventDefault();
112121

113122
// Making sure that there's no error in the state
@@ -121,9 +130,7 @@ function useForm(
121130

122131
// Event handler for handling changes in input.
123132
const handleOnChange = useCallback(
124-
event => {
125-
setIsDirty(true);
126-
133+
(event) => {
127134
const name = event.target.name;
128135
const value = event.target.value;
129136

File renamed without changes.

0 commit comments

Comments
 (0)