I am new to React and as I am building a registration page I encountered an performance issue with my password validation function. Below is my code:
State Defined
const [errordiv, changeViewDiv] = useState(0);
const [passwordValid, setPasswordValid] = useState(false)
Pass Check Function
changeViewDiv(1)
// console.log(errordiv)
const letterReg = /[a-z]/;
const capitalReg = /[A-Z]/;
const specialReg = /[!\@\#\$\%\^\&\(\)\_\+\-\.\,\;\:\\/]/;
const numberReg = /[0-9]/;
// let flag = 1;
const input = e.target.value;
const errorDiv = document.getElementById('message');
// errorDiv.style.display = "block";
Array.from(errorDiv.childNodes).slice(1, 6).forEach((item) => {
item.children[0].style.display = "inline-block";
item.children[1].style.display = "none"
});
// array.forEach((item) => {
// item.children[0].style.display = "inline-block";
// item.children[1].style.display = "none";
// })
if (letterReg.test(input)) {
document.getElementById("letter").children[0].style.display = "none"
document.getElementById("letter").children[1].style.display = "inline-block"
// flag = 0
setPasswordValid(true)
}
if (capitalReg.test(input)) {
document.getElementById("capital").children[0].style.display = "none"
document.getElementById("capital").children[1].style.display = "inline-block"
// flag = 0
setPasswordValid(true)
}
if (numberReg.test(input)) {
document.getElementById("number").children[0].style.display = "none"
document.getElementById("number").children[1].style.display = "inline-block"
// flag = 0
setPasswordValid(true)
}
if (input.length >= 8 && input.length < 16) {
document.getElementById("length").children[0].style.display = "none"
document.getElementById("length").children[1].style.display = "inline-block"
// flag = 0
setPasswordValid(true)
}
if (specialReg.test(input)) {
document.getElementById("special").children[0].style.display = "none"
document.getElementById("special").children[1].style.display = "inline-block"
// flag = 0
setPasswordValid(true)
}
// return flag
Password Input Field
<RStyle.Detailsform style={{ borderBottom: "initial" }} type={passInputType} id="password" name="password" minLength="8" required onInput={passCheck} onChange={inputChange} />
Error Message To Display
{errordiv == 1 ? <RStyle.ErrorMessage id="message">
<h4 style={{ marginBottom: "10px", fontSize: "1em" }}>Passwords must contain:</h4>
<p id="letter" className="invalid"><VscError className='errorIcon' style={errorIcon} /><VscCheck className='validIcon' style={validIcon} /> A <b>lowercase</b> letter</p>
<p id="capital" className="invalid"><VscError className='errorIcon' style={errorIcon} /><VscCheck className='validIcon' style={validIcon} /> A <b>capital (uppercase)</b> letter</p>
<p id="number" className="invalid"><VscError className='errorIcon' style={errorIcon} /><VscCheck className='validIcon' style={validIcon} /> A <b>number</b></p>
<p id="special" className="invalid"><VscError className='errorIcon' style={errorIcon} /><VscCheck className='validIcon' style={validIcon} /> A <b>special character</b></p>
<p id="length" className="invalid"><VscError className='errorIcon' style={errorIcon} /><VscCheck className='validIcon' style={validIcon} /> Length : <b>8-15</b> characters</p>
</RStyle.ErrorMessage> : null}
My conditions are working properly just when I press on any key for the first time the state doesn't change immediately and pressing the key again it starts working. How can I fix this issue?
I have attached the screenshot of the error console
Those error messages are rendered conditionally which will make you validate stuff and try to access the DOM in search of elements that will only be synchronously be renderer after the check function. Your access to e.g.: document.getElementById("number").children[1].style.display
is undefined.
Edit (Proposal for errors):
const [errors, setErrors] = useState([]);
<div className="errors">
{errors.map(error => <p>{error}</p>)}
</div>
Instead of setting display you just push errors to array using setState:
setErrors(previousState => [...previousState].push(error))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.