'ReactJS: Handling form validations

I have created the following UI:

enter image description here

Initially I want Movie Name, Ratings and Durations column to have a black border while if a user enters an invalid input (or empty), it should be red. As you can see, Ratings is still red despite the fact that the page has just refreshed. It should be black like its siblings. Can anyone point out why is this happening? Perhaps there is a different way to handle validations in React because of state hooks?

Initial State:

const [validations, setValidations] = useState({
    isNameValid: true,
    isRatingValid: true,
    isDurationValid: true,
  });

Submit form if it's valid:

const handleFormSubmit = (event) => {
    event.preventDefault();
    if (validateInput(newMovie)) {
      props.onSubmit(newMovie);
      setNewMovie(emptyObject);
    }
  };

CSS Rule(s):

.invalid {
  border-color: rgb(238, 90, 90);
}

validateInput function:

const validateInput = (movieObject) => {
    if (movieObject.name.length === 0) {
      setValidations((prevState) => {
        return { ...prevState, isNameValid: false };
      });
    } else {
      setValidations((prevState) => {
        return { ...prevState, isNameValid: true };
      });
    }
    if (movieObject.ratings.length === 0) {
      setValidations((prevState) => {
        return { ...prevState, isRatingValid: false };
      });
    } else if (
      parseInt(movieObject.ratings) >= 0 &&
      parseInt(movieObject.ratings) <= 100
    ) {
      setValidations((prevState) => {
        return { ...prevState, isRatingValid: true };
      });
    }
    if (movieObject.duration.length === 0) {
      setValidations((prevState) => {
        return { ...prevState, isDurationValid: false };
      });
    } else {
      setValidations((prevState) => {
        return { ...prevState, isDurationValid: true };
      });
    }

    console.log(validations);
    return (
      validations.isNameValid &&
      validations.isRatingValid &&
      validations.isDurationValid
    );
  };

Based on validations state, className is applied (or not):

<form onSubmit={handleFormSubmit}>
          <div className="layout-column mb-15">
            <label htmlFor="name" className="mb-3">
              Movie Name
            </label>
            <input
              className={`${!validations.isNameValid ? "invalid" : ""}`}
              type="text"
              id="name"
              placeholder="Enter Movie Name"
              data-testid="nameInput"
              value={newMovie.name}
              onChange={handleChangeEvent}
            />
          </div>
          <div className="layout-column mb-15">
            <label htmlFor="ratings" className="mb-3">
              Ratings
            </label>
            <input
              className={!validations.isRatingsValid ? "invalid" : ""}
              type="number"
              id="ratings"
              placeholder="Enter Rating on a scale of 1 to 100"
              data-testid="ratingsInput"
              value={newMovie.ratings}
              onChange={handleChangeEvent}
            />
          </div>
          <div className="layout-column mb-30">
            <label htmlFor="duration" className="mb-3">
              Duration
            </label>
            <input
              className={!validations.isDurationValid ? "invalid" : ""}
              type="text"
              id="duration"
              placeholder="Enter duration in hours or minutes"
              data-testid="durationInput"
              value={newMovie.duration}
              onChange={handleChangeEvent}
            />
          </div>
          <div className="layout-row justify-content-end">
            <button type="submit" className="mx-0" data-testid="addButton">
              Add Movie
            </button>
          </div>
        </form>

Anybody can point out a better way to apply validations? I feel like there is a lot of repetition here and the fact that Ratings has a red border even at the start, how can this be fixed?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source