How to use the callback function in ReactJS Hooks - reactjs

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;

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

Related

How to Redirect a Register Page to another Page using React & Formik

The page is not responding after clicking the sign up button, I wonder what went wrong with the code. I want it to redirect to "dashboards/elearning" page. The NavLink points not to the Sign Up button, and if I add a NavLink around sign up button, the validation would be pointless.
Below is the register.js file.
import React from 'react';
import { NavLink } from 'react-router-dom';
import { Button, Form } from 'react-bootstrap';
import * as Yup from 'yup';
import { useFormik } from 'formik';
import LayoutFullpage from 'layout/LayoutFullpage';
import CsLineIcons from 'cs-line-icons/CsLineIcons';
import HtmlHead from 'components/html-head/HtmlHead';
const Register = () => {
const title = 'Register';
const description = 'Register Page';
const validationSchema = Yup.object().shape({
name: Yup.string().required('Name is required'),
email: Yup.string().email().required('Email is required'),
password: Yup.string().min(6, 'Must be at least 6 chars!').required('Password is required'),
terms: Yup.bool().required().oneOf([true], 'Terms must be accepted'),
});
const initialValues = { name: '', email: '', password: '', terms: false };
const onSubmit = (values) => console.log('submit form', values);
const formik = useFormik({ initialValues, validationSchema, onSubmit });
const { handleSubmit, handleChange, values, touched, errors } = formik;
const leftSide = (
<div className="min-h-100 d-flex align-items-center">
<div className="w-100 w-lg-75 w-xxl-50">
<div>
<div className="mb-5">
<h1 className="display-3 text-white">Multiple Niches</h1>
<h1 className="display-3 text-white">Ready for Your Project</h1>
</div>
<p className="h6 text-white lh-1-5 mb-5">
Dynamically target high-payoff intellectual capital for customized technologies. Objectively integrate emerging core competencies before
process-centric communities...
</p>
<div className="mb-5">
<Button size="lg" variant="outline-white" href="/">
Learn More
</Button>
</div>
</div>
</div>
</div>
);
// if <NavLink to="/dashboards/elearning"> Sign up </NavLink>, all other validation mathods invalid
const rightSide = (
<div className="sw-lg-70 min-h-100 bg-foreground d-flex justify-content-center align-items-center shadow-deep py-5 full-page-content-right-border">
<div className="sw-lg-50 px-5">
<div className="sh-11">
<NavLink to="/dashboards/elearning">
<div className="logo-default" />
</NavLink>
</div>
<div className="mb-5">
<h2 className="cta-1 mb-0 text-primary">Welcome,</h2>
<h2 className="cta-1 text-primary">let's get the ball rolling!</h2>
</div>
<div className="mb-5">
<p className="h6">Please use the form to register.</p>
<p className="h6">
If you are a member, please <NavLink to="/login">login</NavLink>.
</p>
</div>
<div>
<form id="registerForm" className="tooltip-end-bottom" onSubmit={handleSubmit}>
<div className="mb-3 filled form-group tooltip-end-top">
<CsLineIcons icon="user" />
<Form.Control type="text" name="name" placeholder="Name" value={values.name} onChange={handleChange} />
{errors.name && touched.name && <div className="d-block invalid-tooltip">{errors.name}</div>}
</div>
<div className="mb-3 filled form-group tooltip-end-top">
<CsLineIcons icon="email" />
<Form.Control type="text" name="email" placeholder="Email" value={values.email} onChange={handleChange} />
{errors.email && touched.email && <div className="d-block invalid-tooltip">{errors.email}</div>}
</div>
<div className="mb-3 filled form-group tooltip-end-top">
<CsLineIcons icon="lock-off" />
<Form.Control type="password" name="password" onChange={handleChange} value={values.password} placeholder="Password" />
{errors.password && touched.password && <div className="d-block invalid-tooltip">{errors.password}</div>}
</div>
<div className="mb-3 position-relative form-group">
<div className="form-check">
<input type="checkbox" className="form-check-input" name="terms" onChange={handleChange} value={values.terms} />
<label className="form-check-label">
I have read and accept the{' '}
<NavLink to="/dashboards/elearning" target="_blank">
terms and conditions.
</NavLink>
</label>
{errors.terms && touched.terms && <div className="d-block invalid-tooltip">{errors.terms}</div>}
</div>
</div>
<Button size="lg" type="submit">
Signup
</Button>
</form>
</div>
</div>
</div>
);
return (
<>
<HtmlHead title={title} description={description} />
<LayoutFullpage left={leftSide} right={rightSide} />
</>
);
};
export default Register;
You can use the useNavigate hook from react-router-dom
Please find the necessary snippet below.
import { useNavigate } from 'react-router-dom';
...
const navigate = useNavigate();
const onSubmit = (values) => {
console.log('submit form', values);
navigate('dashboards/elearning');
};
...

How to check if an input is empty to apply a specific class?

I am new on react. I am creating a view "login", I have two fields in the form, email and password. I need to check when these inputs are empty to apply a specific icon class, and if they are not empty apply another actived class.
<span className={emailIsEmpty ? "icon" : "icon actived"}>
This class is simply to change the color of the icons when the user is entering data into the inputs.
I Create a "useEffect" for each field.
If the element changes, it will check if the input is empty and will return a boolean indicating the current state.
// Email Field
useEffect(() => {
if (email === "") {
emailIsEmpty = true;
} else {
emailIsEmpty = false;
}
}, [email]);
but I am unable to perform this functionality
Line 33:25: Assignments to the 'passwordIsEmpty' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside useEffect
Line 24:22: Assignments to the 'emailIsEmpty' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside useEffect
LoginView.js
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
const LoginView = function () {
let emailIsEmpty,
passwordIsEmpty = null;
const [formState, setFormState] = useState({
email: "",
password: "",
});
const { email, password } = formState;
const handleInputChange = function (e) {
setFormState({
...formState,
[e.target.name]: e.target.value,
});
};
// Email Field
useEffect(() => {
if (email === "") {
emailIsEmpty = true;
} else {
emailIsEmpty = false;
}
}, [email]);
// Password Field
useEffect(() => {
if (password === "") {
passwordIsEmpty = true;
} else {
passwordIsEmpty = false;
}
}, [password]);
return (
<div className="container">
<div className="card-login">
<div className="card-img">
<img src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="profile-img" className="profile-img-card" />
<h1>Login</h1>
</div>
<form>
<div className="form-input">
<span className={emailIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-envelope-open-text"></i>
</span>
<input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
</div>
<div>
<div className="form-input">
<span className={passwordIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-key"></i>
</span>
<input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
</div>
</div>
<div>
<button className="button response">Login</button>
</div>
<div className="forget-password">
<Link to="/">Forgot password?</Link>
</div>
</form>
</div>
</div>
);
};
export default LoginView;
In my opinion, you don't need two flags(emailIsEmpty and passwordIsEmpty). Rather, you can use the state itself to add the class conditionally.
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
const LoginView = function () {
const [formState, setFormState] = useState({
email: "",
password: "",
});
const handleInputChange = function (e) {
setFormState({
...formState,
[e.target.name]: e.target.value,
});
};
return (
<div className="container">
<div className="card-login">
<div className="card-img">
<img src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="profile-img" className="profile-img-card" />
<h1>Login</h1>
</div>
<form>
<div className="form-input">
<span className={!formState.email? "icon" : "icon actived"}>
<i class="fas fa-envelope-open-text"></i>
</span>
<input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
</div>
<div>
<div className="form-input">
<span className={!formState.password ? "icon" : "icon actived"}>
<i class="fas fa-key"></i>
</span>
<input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
</div>
</div>
<div>
<button className="button response">Login</button>
</div>
<div className="forget-password">
<Link to="/">Forgot password?</Link>
</div>
</form>
</div>
</div>
);
};
export default LoginView;
Remove UseEffect in your code for changing input value its not a better approach it will re render the component every time value change.
this can be possible if you make you can simply apply check on your formState.email
or formState password.
Now in your onChnageHandler function.
const handleInputChange = function (e) {
setFormState({
...formState,
[e.target.name]: e.target.value,
});
//put your condition here
if (formState.email=="")
{
setEmailisEmpty(true);
}
else{
setEmailisEmpty(false);
}
};
<form>
<div className="form-input">
<span className={emailIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-envelope-open-text"></i>
</span>
<input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
</div>
<div>
<div className="form-input">
<span className={passwordIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-key"></i>
</span>
<input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
</div>
</div>
<div>
<button className="button response">Login</button>
</div>
<div className="forget-password">
<Link to="/">Forgot password?</Link>
</div>
</form>
You are updating a variable inside the useEffect function which will not work on render. Because react component only render based on state or props changes.
So You can check the constant variable before the return but not inside useEffect.
emailIsEmpty = email === "";
passwordIsEmpty = password === "";
return (
....
So your component should be look like-
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
const LoginView = function () {
let emailIsEmpty,
passwordIsEmpty = null;
const [formState, setFormState] = useState({
email: "",
password: "",
});
const { email, password } = formState;
const handleInputChange = function (e) {
setFormState({
...formState,
[e.target.name]: e.target.value,
});
};
emailIsEmpty = email === "";
passwordIsEmpty = password === "";
return (
<div className="container">
<div className="card-login">
<div className="card-img">
<img src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="profile-img" className="profile-img-card" />
<h1>Login</h1>
</div>
<form>
<div className="form-input">
<span className={emailIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-envelope-open-text"></i>
</span>
<input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
</div>
<div>
<div className="form-input">
<span className={passwordIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-key"></i>
</span>
<input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
</div>
</div>
<div>
<button className="button response">Login</button>
</div>
<div className="forget-password">
<Link to="/">Forgot password?</Link>
</div>
</form>
</div>
</div>
);
};
export default LoginView;
For the multiple classes, you can use a package called classnames for joining multiple classes together.

Error while creating validations for react-hook-form

I am trying to create validations for my react-hook-form but when I go try to display the errors on the front end I receive this error.
×
TypeError: Cannot read properties of undefined (reading 'name')
It seems like everything is working until I try to display it with the following code
{errors.name && errors.name.message}
import emailjs from "emailjs-com";
import { useForm } from "react-hook-form";
const Contact = () => {
const [successMessage, setSuccessMessage] = useState("");
const { register, handleSubmit, errors } = useForm();
const serviceID = "s_ID";
const templateID = "t_ID";
const userID = "user_12345";
const onSubmit = (data, r) => {
sendEmail(
serviceID,
templateID,
{
name: data.name,
email: data.email,
subject: data.subject,
description: data.description,
},
userID
)
r.target.reset();
}
const sendEmail = (serviceID, templateID, variables, userID) => {
emailjs.send(serviceID, templateID, variables, userID)
.then(() => {
setSuccessMessage("Form sent successfully! I'll contact you as soon as possible");
}).catch(err => console.error(`Something went wrong ${err}`));
};
return (
<div className="contacts">
<div className="text-center">
<h1 className="bold upper-case">contact me</h1>
</div>
<div className="container">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="row">
<div className="col-md-6 col-xs-12">
{/* Name Input */}
<input type="text" className="form-control" placeholder="Name" name="name"
{
...register("name", {
required: "Please enter your name",
maxLength: {
value: 20,
message: "Name must not be longer than 20 characters",
}
})
} />
<span className="error-message">
<p> {errors.name && errors.name.message} </p>
</span>
{/* Email Input */}
<input type="email" className="form-control" placeholder="E-mail" name="email" />
{/* Subject Input */}
<input type="text" className="form-control" placeholder="Subject" name="subject" />
</div>
<div className="col-md-6 col-xs-12">
{/* Subject Input */}
<textarea type="text" className="form-control" placeholder="Subject" name="description" />
<div className="text-center center">
<button className="btn btn-outline-dark contact-button p-button mt-3" type="submit">
Send!
</button>
</div>
</div>
</div>
</form>
</div >
</div >
)
}
export default Contact
Your code helped me debug my EmailJS submission so it's only right if I try my best to help you.
I'm able to successfully display my validation error messages by doing the following:
const {
register,
handleSubmit,
formState: { errors },
} = useForm<IContactForm>();
.
.
.
<form>
<input {...register("firstName", { required: "ENTER YOUR FIRST NAME" })}/>
{errors.firstName && errors.firstName.message}
</form>
Only difference I see is that you don't have 'formState: {errors}' for your useForm hook.

React function Component Validation

I am a beginner in react. I was working on the react function component with forms using hooks. Can anyone please tell how can I apply validation on email text when it is invalid or empty, and disable the continue button if the form is not valid.
import React, { useState } from "react";
const ForgotPassowrd = () => {
const [emailId, setemailId] = useState("");
const forgotPasswordClick = (event) => {};
return (
<div>
<div className="NewPassword-form form_wrapper">
<div className="form-body">
<form action="#">
<div>
<div className="form-group">
<label htmlFor="password">Email-Id</label>
<div className="input-group">
<input type="text" className="form-control" value={emailId} onChange={(event)=>
setemailId(event.target.value)}/>
</div>
</div>
<button type="button" onClick={forgotPasswordClick} className="btn btn-lg
btn-block">Continue</button>
</div>
</form>
</div>
</div>
</div>
);
};
export default ForgotPassowrd;
**Try it.This may be helpfull for you! If you can any queries comment below.**
const LoginV2 = ({}) => {
// state
const [loginForm, setLoginForm] = useState({
email: undefined,
password: undefined,
emailValid: false,
passwordValid: false,
});
const [error, setError] = useState({ email: undefined, password: undefined });
// state update
const handleLoginForm = (e) => {
checkValidity(e.target.name, e.target.value);
setLoginForm({ ...loginForm, [e.target.name]: e.target.value });
};
// validation function
const checkValidity = (inputName, inputValue) => {
switch (inputName) {
case "email":
let pattern = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
loginForm.emailValid = pattern.test(inputValue);
break;
case "password":
loginForm.passwordValid = inputValue.length >= 6;
break;
default:
break;
}
};
// form submit
const onSubmitLoginForm = () => {
console.log(loginForm);
if (!loginForm.emailValid) {
setError(prevError => {
return {
...prevError,
email: "Invalid Email Address"
}
});
}
if (!loginForm.passwordValid) {
setError(prevError => {
return {
...prevError,
password: "Password must be at least six characters long"
}
});
}
return (
<div class="row">
<div class="form">
<div class="col span-1-of-2">
<div class="username">
<p class="login-para text-align-center">LOG IN VIA EMAIL</p>
<form method="post" action="#" class="login-form">
{error.email && (
<div class="alert alert-danger">
<p>
{" "}
<strong> {alertText} </strong> {error.email}
</p>
</div>
)}
{error.password && (
<div class="alert alert-danger">
<p>
{" "}
<strong> {alertText} </strong> {error.password}
</p>
</div>
)}
<div class="info-box">
{icon && <i class="fas fa-user-alt login-icon"></i>}
<input
type="text"
name="email"
placeholder="Your Email"
onChangeText={(e) => handleLoginForm(e)}
inputValue={loginForm.email}
/>
</div>
<div class="info-box">
{icon && <i class="fas fa-user-alt login-icon"></i>}
<input
type="password"
name="password"
placeholder="Your Password"
onChangeText={(e) => handleLoginForm(e)}
inputValue={loginForm.password}
/>
</div>
<div class="buttons">
<input type="checkbox" />
<label class="remember" for="#">
Remember me
</label>
<div class="form-btn-disabled" onClick={onSubmitLoginForm}
>
LOGIN NOW
</div>
</div>
</form>
</div>
</div>
</div>
</div>
);
};
export default LoginV2;
Try below. I have added inline comments for better understanding. Comment your queries if you have any.
// Regex to check valid email
const validEmail = /^[\w-\.]+#([\w-]+\.)+[\w-]{2,4}$/g
import React, { useState } from "react";
const ForgotPassowrd = () => {
const [emailId, setemailId] = useState("");
//State to disable/enable continue button
const [disableBtn, setDisableBtn] = useState(false);
const forgotPasswordClick = (event) => {};
const handleSubmit = e => {
e.preventDefault();
// Do whatever you want to do after you click submit button
}
const handleChange = e => {
setemailId(event.target.value);
setDisableBtn(validEmail.test(e.target.value));
}
return (
<div>
<div className="NewPassword-form form_wrapper">
<div className="form-body">
{/* Remove action and use onSubmit handler*/}
<form onSubmit={handleSubmit}>
<div>
<div className="form-group">
<label htmlFor="password">Email-Id</label>
<div className="input-group">
{/* Introduced name attribute to help you with handleSubmit handler*/}
<input name="email" type="text" className="form-control" value={emailId} onChange={(event)=>
setemailId(event.target.value)}/>
</div>
</div>
<button onClick={forgotPasswordClick} className="btn btn-lg
btn-block" disabled={disableBtn}>Continue</button>
</div>
</form>
</div>
</div>
</div>
);
};
export default ForgotPassowrd;

React state hooks and useEffect unexpected behavior for state updates

So I have a project I did before in Vue and now am doing in React(w/ hooks) in order to learn it. I'm having a few problems and concerns that I'm not going about it the right way(certain I'm not).
One of the biggest problems I'm having is where the state is updated via onchange and onblur. Many times the state values would be one "tick" behind. I found that with old class components you could use a callback within setState.
I'm trying to make instant form validation feedback show/hide as the user updates the fields.
With hooks, it is supposed to be done with useEffect. I have it "working" right now but it seems it's rendering more times than it should. I can tell by the fact it runs the checkValues() twice to show the current state values .
An example of the nature of my misunderstanding is if I don't put setinValid(validateForm()); within the onchange AND the useEffect.. it won't update the state for inValid which disables/enables the submit button. This seems redundant to me and I'm not sure why it "works" as is.
Any help/insight on how to properly do what I'm attempting would be greatly appreciated.
https://codesandbox.io/s/user-listing-in-react-9ip4t?fontsize=14&module=%2Fsrc%2Fcomponents%2FUser%2FUserAdd.js
import React from "react";
import { Link } from "react-router-dom";
// import { saveUserToLocalStorage } from "../../utils/StorageHelper";
// import { User } from "../../utils/UserClass";
const UserAdd = props => {
const [userName, setuserName] = React.useState("");
const [userAge, setuserAge] = React.useState("");
const [userEmail, setuserEmail] = React.useState("");
const [inValid, setinValid] = React.useState(true);
const [errors, setErrors] = React.useState({
name: [],
age: [],
email: []
});
React.useEffect(() => {
checkValues();
setinValid(validateForm());
}, [userName, userAge, userEmail, inValid]);
const validateForm = () => {
if (isNaN(userAge)) {
return true;
}
if (!userName || !userAge || !userEmail) {
return true;
}
if (!validateEmail(userEmail)) {
return true;
}
return false;
};
function checkIndividualErrors() {
if (userName.length === 0) {
setErrors({ ...errors, name: ["User name is required"] });
} else {
setErrors({ ...errors, name: [] });
}
}
const checkValues = () => {
console.log(
"username:",
userName,
"age:",
userAge,
"useremail: ",
userEmail,
"invalid:",
inValid
);
};
const validateEmail = mail => {
if (/^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(mail)) {
return true;
}
return false;
};
return (
<div>
<h2 class="line-container">
<span>Add a new User</span>
</h2>
<hr />
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Name</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input
class="input"
type="text"
name="name"
placeholder="Name"
value={userName}
onChange={e => {
setuserName(e.target.value);
setinValid(validateForm());
checkIndividualErrors();
}}
onBlur={checkIndividualErrors}
/>
<span class="error">{errors.name}</span>
</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Age</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input
class="input"
type="text"
name="age"
placeholder="Age"
value={userAge}
onChange={e => {
setuserAge(e.target.value);
setinValid(validateForm());
// checkIndividualErrors not fully implemented yet
}}
/>
<span class="error" />
</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Email</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input
class="input"
type="email"
name="email"
placeholder="Email"
value={userEmail}
onChange={e => {
setuserEmail(e.target.value);
setinValid(validateForm());
// checkIndividualErrors not fully implemented yet
}}
/>
<span class="error" />
</p>
</div>
</div>
</div>
<p class="" style={{ margin: "0 auto" }}>
<button
disabled={inValid}
class="button is-primary"
style={{ marginRight: "10px" }}
>
Create
</button>
<Link to="/" class="button">
Cancel
</Link>
<Link to="/" class="goBack">
<span style={{ fontSize: "20px" }}>←</span>
</Link>
</p>
</div>
);
};
export default UserAdd;

Resources