I'm trying to set up a hard coded authentication in react when a user logs in through a form. With the code I have right now, it always returns the "else" statement, even if it meets the requirements for the "if".
I'm trying to pass in both the handleSubmit function and the authenticate function in the onClick for the submit button. The other issue I'm running into is that when I pass in both functions, it doesn't reset state on the username and password fields on the form.
import React, { useState } from "react";
import "./Login.css";
function Login() {
const [name, setName] = useState("");
const [uname, setUname] = useState("");
const [pword, setPword] = useState("");
const Employee = {
id: 12345,
password: "abcde",
};
function handleInput(e) {
setName(e.target.value);
}
function handleSubmit(e) {
e.preventDefault();
setUname("");
setPword("");
}
function authenticate() {
if (uname === Employee.id && pword === Employee.password) {
console.log("Success! Logged in.");
} else {
console.log("Invalid Employee ID and/or password");
}
}
return (
<div className="login-card">
Hello {name}
<div className="username" onChange={handleInput}>
<input
type="input"
className="username-input"
placeholder="Employee ID"
onChange={(e) => setUname(e.target.value)}
value={uname}
autoComplete="off"
/>
</div>
<div className="password">
<input
className="password-input"
type="password"
placeholder="Password"
onChange={(e) => setPword(e.target.value)}
value={pword}
autoComplete="off"
/>
</div>
<button
className="submit-btn"
type="submit"
onClick={(handleSubmit, authenticate)}
>
Login
</button>
</div>
);
}
export default Login;
EDIT: A combination of all three answers worked. Had to wrap the div in a form, call the authenticate function inside of handleSubmit, and use "==" instead of "===" on checking for the Employee.id:
import React, { useState } from "react";
import "./Login.css";
function Login() {
const [name, setName] = useState("");
const [uname, setUname] = useState("");
const [pword, setPword] = useState("");
const Employee = {
id: 12345,
password: "abcde",
};
function handleInput(e) {
setName(e.target.value);
}
function authenticate() {
if (uname == Employee.id && pword === Employee.password) {
console.log("Success! Logged in.");
} else {
console.log("Invalid Employee ID and/or password");
}
}
function handleSubmit(e) {
authenticate();
e.preventDefault();
setUname("");
setPword("");
}
return (
<div className="login-card">
Hello {name}
<form onSubmit={handleSubmit}>
<div className="username" onChange={handleInput}>
<input
type="input"
className="username-input"
placeholder="Employee ID"
onChange={(e) => setUname(e.target.value)}
value={uname}
autoComplete="off"
/>
</div>
<div className="password">
<input
className="password-input"
type="password"
placeholder="Password"
onChange={(e) => setPword(e.target.value)}
value={pword}
autoComplete="off"
/>
</div>
<button className="submit-btn" type="submit" onClick={handleSubmit}>
Login
</button>
</form>
</div>
);
}
export default Login;
import React, { useState } from "react";
function Login() {
const [name, setName] = useState("");
const [uname, setUname] = useState("");
const [pword, setPword] = useState("");
const Employee = {
id: "12345", //string
password: "abcde"
};
function handleInput(e) {
setName(e.target.value);
}
function handleSubmit(e) {
e.preventDefault();
setUname("");
setPword("");
}
function authenticate(e) {
if (uname === Employee.id && pword === Employee.password) {
console.log("Success! Logged in.");
} else {
console.log("Invalid Employee ID and/or password");
}
handleSubmit(e);
}
console.log(uname, pword);
return (
<div className="login-card">
Hello {name}
<div className="username" onChange={handleInput}>
<input
type="input"
className="username-input"
placeholder="Employee ID"
onChange={(e) => setUname(e.target.value)}
value={uname}
autoComplete="off"
/>
</div>
<div className="password">
<input
className="password-input"
type="password"
placeholder="Password"
onChange={(e) => setPword(e.target.value)}
value={pword}
autoComplete="off"
/>
</div>
<button className="submit-btn" type="submit" onClick={authenticate}>
Login
</button>
</div>
);
}
export default Login;
You are trying to compare id which is number but e.target.value always return string.So === does strict checking with value as well as its type and it fails since "12345" === 12345 will be false.
you need to place those divs inside a form tag
then you can assign "onSubmit" to the form
and also you can do all in one function you don't need two
try this and tell me if its works:
function handleSubmit = (e) => {
e.preventDefault();
if(uname === Employee.id && pword === employee.password){
console.log("logged in")
setname(uname);
setUname("")
setPword("")
} else if(!uname && !pword){
console.log("please fill the fields")
}
else {
console.log("invalid login");
setUname("")
setPword("")
}
}
<div className="login-card">
Hello {name}
<form onSubmit={handleSubmit}>
<div className="username">
<input
type="input"
className="username-input"
placeholder="Employee ID"
onChange={(e) => setUname(e.target.value)}
value={uname}
autoComplete="off"
/>
</div>
<div className="password">
<input
className="password-input"
type="password"
placeholder="Password"
onChange={(e) => setPword(e.target.value)}
value={pword}
/>
</div>
<button type="submit">submit</button>
</form>
</div>
</div>
Related
In my react js application i have the next input:
<input required type="text" id="fname" name="fname" value=""/>
In the case above if the form will be submitted the without input value the will appear a message: Please fill in this field, because it is required. Instead of this text i want to add a custom html element with a different content and style.
I want to check after the form is submitted that this input is required and there is no value. So if there is that scenario then to show a custom element bellow like: <div>No data here</div>
I need to achieve this without using the form tag just to create a custom input component in React js and to do something like:
export default function Input() {
const ref = React.useRef();
return (
<div className="App">
<input ref={ref} required type="text" id="fname" name="fname" value=""/>
{ref.current.isError ? <div>Message</div> : null}
</div>
);
}
Is this possible to check?
You can use onInvalid method on input e.g:
function Input() {
const [invalid, setInvalid] = useState<boolean>(false);
const onSubmit = (data: any) => {
setInvalid(false);
console.log(data)
}
return (
<div style={{ margin: '60px'}}>
<form onSubmit={onSubmit}>
<input
id="fname"
name="fname"
required
type="text"
onInvalid={(e) => {
e.preventDefault();
// if you have ref you can obtain reason why this input is invalid
// console.log(ref.current?.validity.valueMissing);
// or just use e.target.validity
setInvalid(true);
}}
/>
<button type="submit">submit</button>
</form>
{invalid && "invalid"}
</div>
);
}
useState is used here to cause re-render component
Edit: if you don't want to have form inside Input component then just move state to parent component e.g:
function Input(props: { invalid: boolean; setInvalid: () => void }) {
const { invalid, setInvalid } = props;
return (
<div style={{ margin: '60px'}}>
<input
id="fname"
name="fname"
required
type="text"
onInvalid={(e) => {
e.preventDefault();
setInvalid();
}}
/>
{invalid && "invalid"}
</div>
);
}
function App() {
const [invalid, setInvalid] = useState<Record<string, boolean>>({});
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
setInvalid({});
console.log(event);
}
return (
<div className="App">
<form onSubmit={handleSubmit}>
<Input invalid={invalid.fname} setInvalid={() => setInvalid(state => ({...state, fname: true}))}/>
<button type="submit">submit</button>
</form>
</div>
);
}
Edit2: If you want make it valid again you can use onChange:
function Input() {
const [invalid, setInvalid] = React.useState(false);
const updateInvalid = (e) => setInvalid(!e.nativeEvent.target.validity.valid);
return (
<div>
<input
id="fname"
name="fname"
required
type="text"
onChange={updateInvalid}
onInvalid={(e) => {
e.preventDefault();
updateInvalid(e);
}}
/>
<div>{invalid && "Invalid"}</div>
</div>
);
}
Sandbox
All you need is to check if the input is empty or not and based on result we are making a decision for printing message.
All we need is useState hook, onSubmit form validation.
index.js
import React from "react";
import ReactDOM from "react-dom";
import MyInput from "./MyInput.js";
class App extends React.Component {
render() {
return (
<div>
// validate attribute to defind which validation we need
<MyInput validate="email" />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("container"));
MyInput.js
import React, { useState } from "react";
const MyInput = ({ validate }) => {
const [userInput, setUserInput] = useState("");
const [isError, setIsError] = useState(false);
const [errorMessage, setErrorMessage] = useState("");
const handleInput = (e) => {
setUserInput(e.target.value);
setIsError(false);
};
function validateEmail(email) {
var re = /\S+#\S+\.\S+/;
return re.test(email);
}
//you can defind more states such as for password or as per your requirement.
const validateField = (fieldType) => {
switch (fieldType) {
case "email":
if (validateEmail(userInput)) {
setIsError(false);
} else {
setErrorMessage("Need proper email..");
setIsError(true);
}
break;
default:
setIsError(false);
}
};
const handleSubmit = (e) => {
e.preventDefault();
validateField(validate);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" value={userInput} onChange={handleInput} />
{isError ? <p>{errorMessage}</p> : ""}
<input type="submit" />
</form>
);
};
export default MyInput;
Here is working example.
<iframe src="https://codesandbox.io/embed/react-playground-forked-ozgle5?fontsize=14&hidenavigation=1&theme=dark&view=preview" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" title="React PlayGround (forked)" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe>
I have a form with a button to submit it, and I also use the same button to route to another page.
the button work in routing and when I remove the Navlink tag it submits the form. but it does not submit it when the Navlink tags are there and does not show the validation error msgs as well it just route the page.
any help on how to get the two actions to work?
here is my code
import react, { Component, useState, useEffect } from 'react';
import { NavLink } from 'react-router-dom';
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faEyeSlash, faEye } from "#fortawesome/free-solid-svg-icons";
import './sign.css';
const Sign = () => {
//state to be sent to backend
const intialValues = { firstname: "", lastname: "", mobile: "", email: "", password: "", cpassword: "" };
const [formValues, setFormValues] = useState(intialValues);
const [formErrors, setFormErrors] = useState({});
const [isSubmit, setIsSubmit] = useState(false);
const handleChange = (e) => {
console.log(e.target.value);
const { name, value } = e.target;
setFormValues({ ...formValues, [name]: value });
}
const handleSubmit = (err) => {
err.preventDefault();
setFormErrors(validate(formValues));
setIsSubmit(true);
}
useEffect(() => {
if (Object.keys(formErrors).length === 0 && isSubmit) {
console.log(formValues);
}
}, [formErrors])
const validate = (values) => {
const errors = {};
if (!values.firstname) {
errors.firstname = 'firstname is required!';
}
if (!values.lastname) {
errors.lastname = 'lastname is required!';
}
return errors;
}
return (
<div className='signup'>
<form onSubmit={handleSubmit} >
<div className="container">
<h1>Sign Up</h1>
<div className="name">
<div>
<input
type="text"
placeholder="First name"
name="firstname"
id='firstName'
value={formValues.firstname}
onChange={handleChange}
/>
</div>
<div>
<input
type="text"
placeholder="Last name"
name="lastname"
value={formValues.lastname}
onChange={handleChange}
/>
</div>
</div>
<p className='errorMsg'>{formErrors.firstname}</p>
<p className='errorMsg'>{formErrors.lastname}</p>
<br />
<div className="clearfix">
<NavLink to='/profileclient'>
<button type="submit" className="signupbtn">Sign Up</button>
</NavLink>
</div>
</div>
</form>
</div>
)
}
export default Sign;
then I tried to use useNavigate so I modified these lines, and it does navigate to the other page but in the console, it gives me a warning "Form submission canceled because the form is not connected", it does not log the state objects.
const navigate = useNavigate();
<div className="clearfix">
<button type="submit" className="signupbtn" onClick={() => { navigate('/profileclient') }}>Sign Up</button>
</div>
I discovered the solution.
the main problem was that I tried to trigger functions at the same time by clicking on a button, while the submission needs time first before the navigation could happen, this is why it did not submit the form but only navigated. in order to solve the ambiguous behavior, I have put the navigation function call in if statement to make sure the submission is done or not before the navigation is executed. I have also changed the place where I call the navigate function, rather than calling it on the button onClick attribute, I placed it in the useEffect where I check if there are no errors you can submit the form and after submitting it you can navigate to another page.
this is the part of my code that made it work well.
if (isSubmit) {
return (navigate('/profileclient'));
}
and here is my full code
import react, { Component, useState, useEffect } from 'react';
import { NavLink, useNavigate } from 'react-router-dom';
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faEyeSlash, faEye } from "#fortawesome/free-solid-svg-icons";
import './sign.css';
const SignC = () => {
const navigate = useNavigate();
//state to be sent to backend
const intialValues = { firstname: "", lastname: "", mobile: "", email: "", password: "", cpassword: "" };
const [formValues, setFormValues] = useState(intialValues);
const [formErrors, setFormErrors] = useState({});
const [isSubmit, setIsSubmit] = useState(false);
const [passwordShown, setPasswordShowen] = useState(false);
const [cPasswordShown, setCPasswordShowen] = useState(false);
const [eyeShowen, setEyeShowen] = useState(false);
const [cEyeShowen, setCEyeShowen] = useState(false);
const handleChange = (e) => {
console.log(e.target.value);
const { name, value } = e.target;
setFormValues({ ...formValues, [name]: value });
}
const handleSubmit = (err) => {
err.preventDefault();
setFormErrors(validate(formValues));
setIsSubmit(true);
}
useEffect(() => {
if (Object.keys(formErrors).length === 0 && isSubmit) {
console.log(formValues);
if (isSubmit) {
return (navigate('/profileclient'));
}
}
}, [formErrors])
const validate = (values) => {
const errors = {};
const regex = /^[^\s#]+#[^\s#]+\.[^\s#]{2,}$/i;
if (!values.firstname) {
errors.firstname = 'firstname is required!';
}
if (!values.lastname) {
errors.lastname = 'lastname is required!';
}
if (!values.mobile) {
errors.mobile = 'mobile is required!';
}
if (!values.email) {
errors.email = 'email is required!';
} else if (!regex.test(values.email)) {
errors.email = 'this is not a valid email format!'
}
if (!values.password) {
errors.password = 'password is required!';
} else if (values.password.length < 4) {
errors.password = 'password must be more than 4 characters';
} else if (values.password.length > 10) {
errors.password = 'password must not exceeds 10 characters';
}
if (!values.cpassword) {
errors.cpassword = 'password confirmation is required!';
} else if (values.cpassword != values.password) {
errors.cpassword = 'confirmation password does not match!';
}
return errors;
}
const togglePassword = () => {
setPasswordShowen(!passwordShown);
toggleEye();
}
const toggleCPassword = () => {
setCPasswordShowen(!cPasswordShown);
toggleCEye();
}
const toggleEye = () => {
setEyeShowen(!eyeShowen);
}
const toggleCEye = () => {
setCEyeShowen(!cEyeShowen);
}
return (
<div className='signup'>
<form onSubmit={handleSubmit} >
<div className="container">
<h1>Sign Up</h1>
<div className="name">
<div>
<input
type="text"
placeholder="First name"
name="firstname"
id='firstName'
value={formValues.firstname}
onChange={handleChange}
/>
</div>
<div>
<input
type="text"
placeholder="Last name"
name="lastname"
value={formValues.lastname}
onChange={handleChange}
/>
</div>
</div>
<p className='errorMsg'>{formErrors.firstname}</p>
<p className='errorMsg'>{formErrors.lastname}</p>
<br />
<div>
<input
type="text"
placeholder="Business mobile number"
name="mobile"
value={formValues.mobile}
onChange={handleChange}
/>
<p className='errorMsg'>{formErrors.mobile}</p>
<br />
<input
type="text"
placeholder="Email Adress"
name="email"
value={formValues.email}
onChange={handleChange}
/>
<p className='errorMsg'>{formErrors.email}</p>
<br />
<div className="password">
<input
type={passwordShown ? 'text' : 'password'}
placeholder="Password"
name="password"
id='password'
value={formValues.password}
onChange={handleChange}
/>
<FontAwesomeIcon
icon={eyeShowen ? faEye : faEyeSlash}
id='togglePassword'
onClick={togglePassword}
/>
<p className='errorMsg'>{formErrors.password}</p>
<br />
<input
type={cPasswordShown ? 'text' : 'password'}
placeholder="Confirm Password"
name="cpassword"
id='Cpassword'
value={formValues.cpassword}
onChange={handleChange}
/>
<FontAwesomeIcon
icon={cEyeShowen ? faEye : faEyeSlash}
id='toggleCPassword'
onClick={toggleCPassword}
/>
<p className='errorMsg'>{formErrors.cpassword}</p>
</div>
</div>
<br />
<div className="checkbox">
<label>
<input type="checkbox" className="check" />i’ve read and agree with <a href="url" >Terms of service</a>
</label>
</div>
<div className="clearfix">
<button type="submit" className="signupbtn">Sign Up</button>
</div>
</div>
</form >
</div >
)
}
export default SignC;
I am trying to make a button which submit the form and then navigate
to another page.
The important distinction here is the then. When you wrap a link around a button both elements are clicked.
<NavLink to='/profileclient'>
<button type="submit" className="signupbtn">Sign Up</button>
</NavLink>
The link tries to navigate at the same time the form is processing its onSubmit handler.
If you want to conditionally navigate at the after submitting the form then you need to move the navigation logic there. Use the useHistory or useNavigate (depending on react-router-dom version, v5 the former, v6 the latter). There's also no need to store an isSubmit state, you can simply check the validation result in the submit handler and conditionally set the form errors or navigate to the next page.
Example:
const Sign = () => {
const navigate = useNavigate();
...
const handleSubmit = (event) => {
event.preventDefault();
const errors = validate(formValues);
if (Object.values(errors).length) {
setFormErrors(errors);
} else {
navigate("/profileclient");
}
};
const validate = (values) => {
const errors = {};
...
return errors;
};
return (
<div className="signup">
<form onSubmit={handleSubmit}>
<div className="container">
<h1>Sign Up</h1>
...
<div className="clearfix">
<button type="submit" className="signupbtn">
Sign Up
</button>
</div>
</div>
</form>
</div>
);
};
I'm trying to make a table that receives a new user data that is got in a form.
Heres is my code:
import React,{useState} from 'react'
export default function FormAdd({callbackSubmit,...props}) {
const [user,setUser] = useState({});
const handleChangeInput = (name,value) => {
setUser((last) => {
[name]:value,
}
);
}
return (
<form
onSubmit={
(e)=>{
e.preventDefault();
callbackSubmit(user)
}
}
className="formadd-container"
>
<input onChange={(e)=>{handleChangeInput(e.target.name,e.target.value)}} name={"firstname"} placeholder="Fist Name" type="text" className="formadd-container__input"/>
<input onChange={(e)=>{handleChangeInput(e.target.name,e.target.value)}} name={"age"} placeholder="Age" type="text" className="formadd-container__input"/>
<input onChange={(e)=>{handleChangeInput(e.target.name,e.target.value)}} name={"gender"} placeholder="Gender" type="text" className="formadd-container__input"/>
<input onChange={(e)=>{handleChangeInput(e.target.name,e.target.value)}} name={"phone"} placeholder="Phone" type="text" className="formadd-container__input"/>
<input value="Add" type="submit" className="formadd-container__button"/>
</form>
)
}
I get an error >expected ";" inside handleChangeInput function, when I try to set the values for the user object.
Any ideas?
You miss the return in the setState callback.
Replace this :
const handleChangeInput = (name,value) => {
setUser((last) => {
[name]:value,
}
);
}
By:
const handleChangeInput = (name,value) => {
setUser((last) => ({
[name]:value,
})
);
}
I am writing a full stack web application to register a user. I have state variables to reflect the back-end errors, which are then used in the jsx code. I re-render the component whenever the alerts change (which are app-level state managed by redux whose content are generated by the backend). The problem I am facing is that, when the first time I don't enter the required info and hit submit, I display the errors successfully below the corresponding wrongly entered field for 1 second before dispatching a clear alert action, and although alerts state are updated according to redux devtool, the error message would still be there after 1 s in the component. I think the problem is that I need to reset the local state variable that corresponds to the field that was cleared, but I am not sure how to implement that. The errors are captured in errorsData state variable below. Here is my component
import React, { useState, useEffect } from 'react';
import { setAlert } from '../../actions/alert';
import { connect } from 'react-redux';
import { registerUser } from '../../actions/auth';
const Register = ({ setAlert, alerts, registerUser }) => {
const [formData, setFormData] = useState({
name: '',
email: '',
password: '',
password2: '',
});
const [errorsData, setErrorsData] = useState({
nameErr: '',
emailErr: '',
passwordErr: '',
});
const { name, email, password, password2 } = formData;
const { nameErr, emailErr, passwordErr } = errorsData;
const handleOnChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const handleOnSubmit = async (e) => {
e.preventDefault();
if (password !== password2) {
console.log('Passwords do not match');
} else {
registerUser({ name, email, password });
}
};
useEffect(() => {
alerts.forEach((alert) => {
if (alert.errField === 'name') {
setErrorsData({ ...errorsData, nameErr: alert.msg });
}
if (alert.errField === 'email') {
setErrorsData({ ...errorsData, emailErr: alert.msg });
}
if (alert.errField === 'password') {
setErrorsData({ ...errorsData, passwordErr: alert.msg });
}
});
}, [alerts]);
return (
<form className='form' onSubmit={handleOnSubmit}>
<div className='input-field'>
<label htmlFor='name'>Name</label>
<input
type='text'
name='name'
value={name}
id='name'
placeholder='Enter your name'
onChange={handleOnChange}
/>
<small className='error error--name'>{nameErr}</small>
</div>
<div className='input-field'>
<label htmlFor='email'>Email</label>
<input
type='email'
name='email'
value={email}
id='email'
placeholder='Enter a valid email'
onChange={handleOnChange}
/>
<small className='error error--email'>{emailErr}</small>
</div>
<div className='input-field'>
<label htmlFor='password'>Passwrod</label>
<input
type='password'
name='password'
value={password}
id='password'
placeholder='Enter password'
onChange={handleOnChange}
/>
<small className='error error--password'>{passwordErr}</small>
</div>
<div className='input-field'>
<label htmlFor='password2'>Confirm password</label>
<input
type='password'
name='password2'
value={password2}
id='password2'
placeholder='Confirm password'
onChange={handleOnChange}
/>
</div>
<input className='submit' type='submit' value='Submit' />
</form>
);
};
const mapStateToProps = (state) => ({
alerts: state.alert,
});
export default connect(mapStateToProps, { setAlert, registerUser })(Register);
Your component is setup incorrectly because you are trying to use connect with functional components when you must be using useDispatch and useTypedSelector for redux with functional components. Instead you should do something like this.
import React, { useState, useEffect } from "react";
/* Hooks */
**import { useDispatch, useSelector } from "react-redux";**
/* Actions */
import { registerUser } from "../../actions/auth";
import { setAlert } from "../../actions/alert";
const Register = () => {
// Hooks
**const dispatch = useDispatch();**
// Store
**const alerts = useSelector(state => state.alert);**
// Local state
const [formData, setFormData] = useState({
name: "",
email: "",
password: "",
password2: "",
});
const [errorsData, setErrorsData] = useState({
nameErr: "",
emailErr: "",
passwordErr: "",
});
const { name, email, password, password2 } = formData;
const { nameErr, emailErr, passwordErr } = errorsData;
// Event handlers
const handleOnChange = e => setFormData({ ...formData, [e.target.name]: e.target.value });
const handleOnSubmit = async e => {
e.preventDefault();
if (password !== password2) console.log("Passwords do not match");
else dispatch(registerUser({ name, email, password }));
};
// Effects
useEffect(() => {
alerts.forEach(alert => {
switch(alert.errField) {
case "name":
setErrorsData({ ...errorsData, nameErr: alert.msg });
break;
case "email":
setErrorsData({ ...errorsData, emailErr: alert.msg });
break;
case "password":
setErrorsData({ ...errorsData, passwordErr: alert.msg });
break;
default:
break;
};
});
}, [alerts, errorsData]);
// Rendering
return (
<form className="form" onSubmit={handleOnSubmit}>
<div className="input-field">
<label htmlFor="name">Name</label>
<input
type="text"
name="name"
value={name}
id="name"
placeholder="Enter your name"
onChange={handleOnChange}
/>
<small className="error error--name">{nameErr}</small>
</div>
<div className="input-field">
<label htmlFor="email">Email</label>
<input
type="email"
name="email"
value={email}
id="email"
placeholder="Enter a valid email"
onChange={handleOnChange}
/>
<small className="error error--email">{emailErr}</small>
</div>
<div className="input-field">
<label htmlFor="password">Passwrod</label>
<input
type="password"
name="password"
value={password}
id="password"
placeholder="Enter password"
onChange={handleOnChange}
/>
<small className="error error--password">{passwordErr}</small>
</div>
<div className="input-field">
<label htmlFor="password2">Confirm password</label>
<input
type="password"
name="password2"
value={password2}
id="password2"
placeholder="Confirm password"
onChange={handleOnChange}
/>
</div>
<input className="submit" type="submit" value="Submit" />
</form>
);
};
**export default Register;**
Major changes are highlighted.
I want to check the validation of Re-password in React, I wrote this code for that but when you set(for Example) passsword:"1234" and Re-password:"1234" it doesn't apply as true but when you enter the fifth character for Re-password it becomes True .
Do you know what is issue?
import React , { Component } from 'react';
export default class RegistrationForm extends Component {
constructor(props) {
super(props);
this.state = {
name: '',
email:'',
password :'',
password_re:'',
password_has_error:false
};
}
checkPassword() {
if(!this.state.password || this.state.password != this.state.password_re) {
this.setState({password_has_error:true});
}
else {
this.setState({password_has_error:false});
}
}
handleChange(event) {
this.setState({[event.target.name] : event.target.value });
if (event.target.name == 'password' || event.target.name == 'password_re')
this.checkPassword();
}
handleSubmit(event) {
event.preventDefault();
// TODO: will submit the form here
}
render(){
return (
<form onSubmit={(event)=>this.handleSubmit(event)}>
<div>
<label>Name</label>
<input
type="text"
name="name"
value={this.state.name}
onChange={(event)=>this.handleChange(event)}
/>
</div>
<div>
<label>Email address</label>
<input
name="email"
type="email"
value={this.state.email}
onChange={(event)=>this.handleChange(event)}
/>
</div>
<div>
<label>Password</label>
<input
type="password"
name="password"
value={this.state.password}
onChange={(event)=>this.handleChange(event)}
/>
</div>
<div>
<label>Re-enter password</label>
<input
type="password"
name="password_re"
value={this.state.password_re}
onChange={(event)=>this.handleChange(event)}
/>
</div>
<button type="submit">Submit</button>
</form>
)
}
}
Edit:This is my React component
This is because, setState is async, it will not update the state value immediately.
Write it like this, by using setState callback method:
handleChange(event) {
const { name, value } = e.target
this.setState({
[name] : value
}, () => {
if (name == 'password' || name == 'password_re')
this.checkPassword();
}
}
);
}
Check this for more details about setState async behaviour.