After the code below executes, if the submit button is pressed without touching any fields, it runs the handleSubmit()
function. But the problem is when that is done, it prints the errors twice. Why is that?
import React, { useState, useEffect, useRef } from "react";
import { TextField, Box, Button } from "@mui/material";
const ValidatedTextField = ({
fieldValue = "",
label,
validator,
onChange,
required,
}) => {
const [value, setValue] = useState(fieldValue);
const [error, setError] = useState(false);
useEffect(() => {
if (value === "" && required) {
const errMsg = "This field is required!";
if (errMsg != error) {
setError(errMsg);
onChange("", errMsg);
}
}
}, [required]);
const handleChange = (e) => {
const newValue = e.target.value;
const errorMessage = validator(newValue);
setValue(newValue);
setError(errorMessage);
onChange(newValue, errorMessage);
};
return (
<TextField
label={label}
value={value}
onChange={handleChange}
error={!!error}
helperText={error}
/>
);
};
const nameValidator = (value) => {
if (value.length == 0) return "Name must not be empty";
if (value.length < 3) return "Name must be at least 3 characters long";
if (value.length > 20) return "Name must be less than 20 characters long";
if (!/^[a-zA-Z ]+$/.test(value))
return "Name must contain only letters and spaces";
return false;
};
const emailValidator = (value) => {
if (!/^[a-zA-Z0-9._:$!%-]+@[a-zA-Z0-9.-]+.[a-zA-Z]+$/.test(value))
return "Invalid email address";
return false;
};
export default function CreateView() {
const [checkEmptyFields, setCheckEmptyFields] = useState(false);
const formDataRef = useRef({});
const errorsRef = useRef({});
const setDataWithErros = (val, err, key) => {
formDataRef.current = { ...formDataRef.current, [key]: val };
errorsRef.current = { ...errorsRef.current, [key]: err };
};
const handleSubmit = (e) => {
e.preventDefault();
if (checkEmptyFields != true) setCheckEmptyFields(true);
setTimeout(() => {
console.log("errors", errorsRef.current);
}, 0);
};
return (
<Box component="form" onSubmit={handleSubmit} noValidate>
<ValidatedTextField
label="Name"
validator={nameValidator}
onChange={(val, err) => setDataWithErros(val, err, "name")}
required={checkEmptyFields}
/>
<ValidatedTextField
label="Email"
validator={emailValidator}
onChange={(val, err) => setDataWithErros(val, err, "email")}
/>
<Button type="submit" variant="contained">
Submit
</Button>
</Box>
);
}
I expect it to print the error once.
2
Answers
Search for <React.StrictMode> and remove it along with its closing tag. This is likely to be in a file named something like app.jsx
I have tried to reporoduce but your code is working fine for my project. Coulpd you polease share some more detail
screenshot attached