Form validation React function component with useState |
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
</body>
</html>
src/App.js
import { useState, useEffect } from "react";
import {
Stack,
Input,
InputGroup,
InputRightElement,
Button,
Alert,
AlertIcon
} from "@chakra-ui/react";
export default function App() {
const [userInfo, setUserInfo] = useState({
email: "",
password: "",
formErrors: { email: "", password: "" },
emailValid: false,
passwordValid: false,
formValid: false,
fieldNameEmail: "email",
fieldNamePassword: "password"
});
const [show, setShow] = useState(false);
const handleClick = () => setShow(!show);
const handleChange = (e) => {
const value = e.target.value;
setUserInfo({
...userInfo,
[e.target.name]: value
});
};
const validateField = (fieldName, value) => {
let fieldValidationErrors = userInfo.formErrors;
let emailValid = userInfo.emailValid;
let passwordValid = userInfo.passwordValid;
switch (fieldName) {
case "email":
emailValid = /^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i.test(value);
fieldValidationErrors.email = emailValid ? "" : " is invalid";
break;
case "password":
passwordValid = value.length >= 6;
fieldValidationErrors.password = passwordValid ? "" : " is too short";
break;
default:
break;
}
setUserInfo({
...userInfo,
formErrors: fieldValidationErrors,
emailValid: emailValid,
passwordValid: passwordValid,
formValid: userInfo.emailValid && userInfo.passwordValid
});
};
useEffect(() => {
validateField(userInfo.fieldNameEmail, userInfo.email);
}, [userInfo.email, userInfo.emailValid]);
useEffect(() => {
validateField(userInfo.fieldNamePassword, userInfo.password);
}, [userInfo.password, userInfo.passwordValid]);
return (
<Stack spacing={3} py={20} px={20}>
{userInfo.emailValid && (
<Alert status="success">
<AlertIcon />
Your email {userInfo.email} is valid.Hurry!
</Alert>
)}
{userInfo.passwordValid && (
<Alert status="success">
<AlertIcon />
Your password {userInfo.password} is valid.Hurry!
</Alert>
)}
<Input
value={userInfo.email}
placeholder="Email"
name="email"
type="email"
width={380}
height="48px"
isInvalid={!userInfo.emailValid}
errorBorderColor="red.300"
onChange={(event) => handleChange(event)}
/>
<InputGroup width={380} height="48px">
<Input
value={userInfo.password}
pr="4.5rem"
type={show ? "text" : "password"}
placeholder="Password"
width={380}
isInvalid={!userInfo.passwordValid}
errorBorderColor="red.300"
name="password"
height="48px"
onChange={(event) => handleChange(event)}
/>
<InputRightElement width="4.5rem" pt={2}>
<Button h="2.35rem" size="sm" onClick={handleClick}>
{show ? "Hide" : "Show"}
</Button>
</InputRightElement>
</InputGroup>
<Button
size="md"
height="48px"
width="200px"
border="2px"
borderColor="green.500"
disabled={!userInfo.formValid}
>
Login
</Button>
</Stack>
);
}
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { ChakraProvider } from "@chakra-ui/react";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<ChakraProvider>
<App />
</ChakraProvider>
</StrictMode>,
rootElement
);