Please refer my code below I wrote for just learning purpose :
import { useState } from "react";
function LoginForm() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
let isInputTouched = false;
const [isValidForm, setIsValidForm] = useState(false);
function formSubmitHandler(event) {
event.preventDefault();
isInputTouched = true;
if (username.length < 10 || password.length < 10) {
setIsValidForm(false);
console.log((!isValidForm && isInputTouched));
setUsername("");
setPassword("");
return;
}
}
function usernameHandler(event) {
const inputValue = event.target.value;
setUsername(inputValue);
isInputTouched = true;
}
function passwordHandler(event) {
const inputValue = event.target.value;
setPassword(inputValue);
isInputTouched = true;
}
return (
<div className="container w-50 border shadow p-5">
<form onSubmit={formSubmitHandler}>
<div class="mb-3">
<label for="exampleInputEmail1" class="form-label">Email address</label>
<input onChange={usernameHandler} type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" value={username} />
<div id="emailHelp" class="form-text">We'll never share your email with anyone else.</div>
</div>
<div class="mb-3">
<label for="exampleInputPassword1" class="form-label">Password</label>
<input onChange={passwordHandler} type="password" class="form-control" id="exampleInputPassword1" value={password} />
</div>
{(!isValidForm && isInputTouched) && < p className="text text-center text-danger">please enter valid email and password</p>}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div >
);
}
export default LoginForm;
My current understanding is that if any of the attributes managed by useState are updated, the jsx will be re evaluated. If that is the case, when I hit a submit button without entering any input jsx reevaluation should happen because I am calling setIsValidForm() in that. Now since I am updating isInputTouched manually (isInputTouched = true;
) in the line before so this value should be considered anywhere its value is asked for but it wont trigger the reevaluation of jsx, but that should happen when I call setIsValidForm(false);
. And post that my error warning should pop up : {(!isValidForm && isInputTouched) && < p className="text text-center text-danger">please enter valid email and password
Please help me understand where am I going wrong.
Thanks
CodePudding user response:
Reason
This is happening because, the value of isInputTouched
is not persisted across rerenders
. Every time the component rerenders, the value of isInputTouched
is reset to false
.
Code
Here is an example to show, how the isInputTouched
is erased on every rerender.
Note: Check the Browser's console for clarity.
Steps:
- Click on
setRand
button then see console (no extra logs as no rerender, but you are expecting randVar change) - Click on
ToggleValid
button. There the value ofrandVar
will be shown (in logs) before the state updation. - After the state updation, a new
table
will appear inbrowser's logs
due torerender
on state change. You will notice that,setRand
is reset tofalse
. Here is the gist
https://codesandbox.io/s/modest-bardeen-j6efc?file=/src/index.js
Solution
You can use useState
for isInputTouched
as well.