Reputation: 149
I am using React Hooks - useState and useEffect - to grab email/password form input from text fields provided by Material UI (specifically using the BootstrapInput
under "Customized Inputs" on that page).
I have looked at similar StackOverflow questions about getting form values with React Hooks. Unfortunately, these solutions do not work for me as I believe my problem is with the Material UI Text Field I am using. In the other questions' solutions, the code uses a simple unstyled input
tag.
I've tried putting the handleChange
function in InputField.js
- in this case, values.email and values.password are updated and printed correctly. However, validation (with the validate
function) must be kept within Form.js
. handleChange
uses useState (setValues
) to set the values
variable, and validate
uses values
. Therefore handleChange
must be kept in Form.js
which is where I am having my problem.
Working demo here: https://glitch.com/~blue-peridot (click Show on the top-left corner, next to the project name and open your actual browser console to see output... ignore warnings from browser)
Firstly:
From Form.js - I expect values.email and values.password (lines 29-30) to be printed to console as they are entered in the InputField
.
Actual output - undefined
Secondly:
isSubmitting
is one step behind. I expect the value of isSubmitting
to be set to True after clicking Login once (provided the input is valid). However, the value is not updated until after the second click.
Upvotes: 0
Views: 2667
Reputation: 2679
A few things in Form.js:
useEffect
hook is missing dependencies on both isSubmitting
and handleChange
.validate
outside of the component.handleChange
and handleSubmit
to other components, it will boost performance to wrap them in useCallback
hooks, likeconst handleChange = useCallback((event) => {
event.persist();
setValues(values => ({ ...values, [event.target.name]: event.target.value }));
}, [values]);
const handleSubmit = useCallback((event) => {
if (event) event.preventDefault();
setErrors(validate(values));
setIsSubmitting(true);
}, [values]);
If you have ESLint setup or can, eslint-plugin-react-hooks helps to catch these issues.
Upvotes: 1
Reputation: 852
You need to pass your props through on your InputField
component. Currently, you only have label
as a prop.
e.g.
const InputField = ({
label,
...others
}) => {
const classes = useStyles();
return (
<div className={classes.root}>
<FormControl className={classes.margin}>
<InputLabel className={classes.label} shrink htmlFor="bootstrap-input">
{label}
</InputLabel>
<BootstrapInput {...others} />
</FormControl>
</div>
)
}
Or you can only pass specific props through.
Upvotes: 1