skip to Main Content

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


  1. 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

    Login or Signup to reply.
  2. I have tried to reporoduce but your code is working fine for my project. Coulpd you polease share some more detail
    screenshot attached

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search