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
setRandbutton then see console (no extra logs as no rerender, but you are expecting randVar change) - Click on
ToggleValidbutton. There the value ofrandVarwill be shown (in logs) before the state updation. - After the state updation, a new
tablewill appear inbrowser's logsdue torerenderon state change. You will notice that,setRandis 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.
