Jananath Banuka
Jananath Banuka

Reputation: 3873

How to use the callback function in ReactJS Hooks

I have a form with several fields. And I am doing the validation as well.

So on the onSubmit it calls to a function handleSubmit and there I am doing the validation.

So if there are any empty fields, they will produce an error and will be shown below each field. If there are NO errors, it will be route to the /register-success component.

Now my problem is, if there are any empty fields when I click on Register button, those respective errors are being set using setErrors. But it is not being updated to the errors variable right after it is being set.

So unlike in class components I could have used a callback function with setState but in hooks I saw a workaround to use useEffect. It is working, but now I don't know how to redirect the page to /register-success within the useEffect because I can't do it within the handleSubmit because of the errors are not getting updated even after the setErrors

So How can I do the callback operation using react hooks or how can I redirect the page within the useEffect?

Here's my code:

import React, { useState, useEffect } from "react";
import { Link, useHistory } from "react-router-dom";

function Register() {
  const [values, setValues] = useState({});
  const [errors, setErrors] = useState({});

  const handleChange = (event) => {
    event.persist();
    setValues((values) => ({
      ...values,
      [event.target.name]: event.target.value,
    }));
  };

  useEffect(() => {
    if (Object.keys(errors).length === 0) {

      // RIDERECT TO THE /register-success  ==============================
    } else {
      // alert("Errors found");
    }
  }, [errors]);

  const validateForm = (values) => {
    let allErrors = {};
    if (!values.name) {
      allErrors.name = "User name is required!";
    }
    if (!values.phonenumber) {
      allErrors.phonenumber = "Phone number is required!";
    }

    if (!values.email) {
      allErrors.email = "Email address is required!";
    } else if (!/\S+@\S+\.\S+/.test(values.email)) {
      allErrors.email = "Email address is invalid!";
    }

    if (!values.password) {
      allErrors.password = "Please provide the password!";
    }

    if (!values.confirmpassword) {
      allErrors.confirmpassword = "Please confirm the password is the same!";
    }

    return allErrors;
  };

  const handleSubmit = (event) => {
    if (event) event.preventDefault();
    setErrors(validateForm(values));

    
  };

  return (
    <form onSubmit={handleSubmit}>
      <div className="container login-container">
        <div className="row">
          <div className="col-md-6 login-form-2">
            <h3>Register to post your ad</h3>
            <div className="form-group">
              <input
                onChange={handleChange}
                type="text"
                className="form-control"
                placeholder="Name *"
                name="name"
                value={values.name || ""}
              />
              {errors.name && (
                <div class="alert alert-danger" role="alert">
                  {errors.name}
                </div>
              )}
            </div>
            <div className="form-group">
              <input
                onChange={handleChange}
                type="text"
                name="phonenumber"
                className="form-control"
                placeholder="Phone Number *"
                value={values.phonenumber || ""}
              />
              {errors.phonenumber && (
                <div class="alert alert-danger" role="alert">
                  {errors.phonenumber}
                </div>
              )}
            </div>

            <div className="form-group">
              <input
                onChange={handleChange}
                type="text"
                name="email"
                className="form-control"
                placeholder="Your Email *"
                value={values.email || ""}
              />
              {errors.email && (
                <div class="alert alert-danger" role="alert">
                  {errors.email}
                </div>
              )}
            </div>
            <div className="form-group">
              <input
                onChange={handleChange}
                type="password"
                name="password"
                className="form-control"
                placeholder="Password *"
                value={values.password || ""}
              />
              {errors.password && (
                <div class="alert alert-danger" role="alert">
                  {errors.password}
                </div>
              )}
            </div>
            <div className="form-group">
              <input
                onChange={handleChange}
                type="password"
                className="form-control"
                placeholder="Confirm Password *"
                name="confirmpassword"
                value={values.confirmpassword || ""}
              />
              {errors.confirmpassword && (
                <div class="alert alert-danger" role="alert">
                  {errors.confirmpassword}
                </div>
              )}
            </div>
            <div className="form-group">
              {/* <Link to="/register-success"> */}
              <input type="submit" className="btnSubmit" value="Register" />
              {/* </Link> */}
            </div>
            <div className="form-group btnForgetPwd">
              By clicking "Register" you are agreeing to our{" "}
              <Link target="_blank" to="/terms-and-conditions">
                <a
                  style={{
                    color: "white",
                    textDecoration: "underline",
                    fontStyle: "italic",
                  }}
                >
                  Terms and Conditions
                </a>
              </Link>
            </div>
          </div>

          <div className="col-md-6 login-form-1">
            <div className="login-logo">
              <img src="https://image.ibb.co/n7oTvU/logo_white.png" alt="" />
            </div>

            {/* Register  */}
            <h3>Already a member? Login</h3>

            <div className="form-group text-center pt-5">
              <Link to="/login">
                <input type="button" className="btnSubmit" value="Login" />
              </Link>
            </div>
          </div>
        </div>
      </div>
    </form>
  );
}

export default Register;

Upvotes: 0

Views: 135

Answers (1)

Not the best answer
Not the best answer

Reputation: 301

You can do something like that :

const handleSubmit = (event) => {
    if (event) event.preventDefault();
    const validationErrors = validateForm(values)
    if(Object.keys(validationErrors).length > 0) {
      setErrors(validationErrors);
      return;
    }
    // REDIRECT TO THE /register-success  ==============================
  };

If you've got errors redirection won't be triggered and component will re-render with errors updated

Upvotes: 1

Related Questions