React state hooks and useEffect unexpected behavior for state updates - reactjs

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;

Related

How to pass data from page to another page

Hello guys i have a react project made with react, node, express, and mysql. The thing is i want to get email from login and pass to home page. How do i do that, i dont want to use useParams() because the user can input their email in the link, i want to avoid that. Is there any way to do that and if you can, can you give code example.
Login
const Login = () => {
let navigate = useNavigate();
const [emailLog, setEmailLog] = useState("");
const [passwordLog, setPasswordLog] = useState("");
const [loginStatus, setLoginStatus] = useState("");
Axios.defaults.withCredentials = true;
const login = (e) => {
e.preventDefault()
Axios.post("http://localhost:3001/login" , {
email: emailLog,
password: passwordLog
}).then((response)=> {
console.log(response)
if(response.data.message) {
alert((response.data.message))
} else{
setLoginStatus(response.data[0].email)
alert("Redirecting")
navigate("/home")
}
})
}
useEffect(() => {
Axios.get('http://localhost:3001/login').then((response)=> {
if(response.data.loggedIn == true) {
setLoginStatus(response.data.email[0].email)
}
})
})
return (
<div>
<img className="wave" src={Wave} />
<img className="wave2" src={WaveV2} />
<div className="wrapper">
<div className="img">
{/* <img src={Background}/> */}
</div>
<div className="register-content">
<div className='registerForm'>
<img src={Avatar} />
<h2 className="title">Welcome</h2>
<div className="input-div one">
<div className="i">
<i className="fas fa-user"><GrMail /></i>
</div>
<div className="div">
<input type="email" className="input" placeholder='Email' required
onChange={(e)=> {
setEmailLog(e.target.value)
}}/>
</div>
</div>
<div className="input-div pass">
<div className="i">
<i className="fas fa-lock"><AiFillLock /></i>
</div>
<div className="div">
<input type="password" className="input" placeholder='Password' required
onChange={(e)=> {
setPasswordLog(e.target.value)
}}/>
</div>
</div>
Don't have an account ?
<button type='submit' className='btn' onClick={login} data={emailLog}>Login</button>
</div>
</div>
</div>
</div>
)
}
export default Login
App.js
function App() {
const [invoice, setInvoice] = useState("");
const [date, setDate] = useState ("");
const [currency, setCurrency] = useState ("IDR");
const [ myFile, setMyFile] = useState("");
const [test, setTest] = useState("anjay#anjay.com");
Axios.defaults.withCredentials = true;
return (
<div className="App">
<BasicExample />
<div className='formInput'>
<form method='POST' encType='multipart/form-data' action='http://localhost:3001/upload'>
<div className='textUser'>
<h1>{props.data}</h1>
</div>
<input className='inputForm' defaultValue={test} type="email" disabled name='email' />
<input className='inputForm' type="number" placeholder='Invoice No' name='InvoiceNo' />
<input className='inputForm' type="date" name='Invoice_Date' />
<input className='inputForm' type="text" placeholder='Description' name='Description' />
<select className='selectBox' name='Currency' onChange={(e)=> {
setCurrency(e.target.value);
}}>
<option value="IDR">IDR</option>
<option value="USD">USD</option>
<option value="YEN">YEN</option>
</select>
<input className='inputForm' type="number" placeholder='Amount' name='Amount'/>
<input className='custom-file-upload' multiple type="file" name="DocumentFile" onChange={(e)=> {
setMyFile(e.target.value);
}} />
<button className='btnSubmit'>Submit</button>
</form>
</div>
</div>
);
}
export default App;
I think props drilling should solve it.
example
Login Component
function Login({email, setEmail}){
// you need to update state email here
}
Home or App.js
function App(){
const [email, setEmail] = useState("");
// here you should pass the props to login component,
// so you have the ability to set or asign the email state
<Login email={email} setEmail={setEmail} />
}
If you want to send data tp one page, you can use state with navigate.
navigate("/home", {state: { email: emailLog }})
you can get data from your home component like,
{props.location.state.email}

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.

React error "Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak"

I have a Login component and I receive that error: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak. I googled for the error and found some people having the same issue and I tried to solve it like them, but it didn't work for me. Why I have this error, and how do I fix it? Thanks
COMPONENT LOGIN
import React, { useState, useContext, useEffect } from "react";
import { useLocation } from "wouter";
import logic from "../../logic";
import { AuthContext } from "../../context/AuthContext";
import validate from "./validateRulesLogin";
import literals from "../../common/i18n/literals";
import "./index.css";
export default function Login(language) {
const [, setAuth] = useContext(AuthContext);
const [, pushLocation] = useLocation();
const [messageError, setMessageError] = useState("");
const [errorsValidateForm, setErrorsValidateForm] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const [data, setData] = useState({ email: "", password: "" });
const { lang } = language;
const { login_notRegister } = literals;
useEffect(() => {}, [errorsValidateForm, isSubmitting]);
let isCancelled = false;
async function handleOnSubmit(e) {
e.preventDefault();
if (!isSubmitting) {
let errorsForm = validate(data, lang);
if (Object.keys(errorsForm).length === 0 && !isCancelled) {
setIsSubmitting(true);
const { email, password } = data;
try {
await logic.loginUser(email, password, lang);
setAuth(true);
setIsSubmitting(false);
pushLocation("/");
} catch (error) {
setMessageError(error.message);
setIsSubmitting(false);
setTimeout(() => {
setMessageError("");
}, 3000);
}
}
setErrorsValidateForm(errorsForm);
}
return () => {
isCancelled = true;
};
}
const handleOnChangeData = (e) => {
e.preventDefault();
setData({
...data,
[e.target.name]: e.target.value,
});
};
return (
<>
{messageError && (
<div className="message">
<p className="messageError">{messageError}</p>
</div>
)}
<section className="hero is-fullwidth">
<div className="hero-body">
<div className="container">
<div className="columns is-centered">
<div className="column is-4">
<form id="form" onSubmit={(e) => handleOnSubmit(e)} noValidate>
<div className="field">
<p className="control has-icons-left">
<input
className="input"
name="email"
type="email"
placeholder="Email"
onChange={handleOnChangeData}
required
/>
<span className="icon is-small is-left">
<i className="fas fa-envelope"></i>
</span>
</p>
{errorsValidateForm.email && (
<p className="help is-danger">
{errorsValidateForm.email}
</p>
)}
</div>
<div className="field">
<p className="control has-icons-left">
<input
className="input"
name="password"
type="password"
placeholder="Password"
onChange={handleOnChangeData}
required
/>
<span className="icon is-small is-left">
<i className="fas fa-lock"></i>
</span>
</p>
{errorsValidateForm.password && (
<p className="help is-danger">
{errorsValidateForm.password}
</p>
)}
</div>
<div className="field">
<p className="control">
<button type="submit" className="button is-success">
Login
</button>
</p>
</div>
<div>
{login_notRegister[lang]}
</div>
</form>
</div>
</div>
</div>
</div>
</section>
</>
);
}

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;

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;
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

Resources