Reputation: 3265
I'm trying to build a Password validator. My issue is that the boolean valid
is always false even when the regex is tested to be correct. I am actually using typescript in my app, but I've made a demo here just in JSX:
The App.js file looks like this:
import React, { useState } from "react";
import "./styles.css";
const App = () => {
const [inputValue, setInputValue] = useState('');
const [valid, setValid] = useState(false);
const isValidPasswordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$@!%&*?])[A-Za-z\d#$@!%&*?]{12,}$/;
//const isValidPasswordRegex = /^\d+$/;
const validatePassword = (value) => {
if (!isValidPasswordRegex.test(value)) {
setValid(!valid);
} else {
setValid(valid);
}
return valid;
};
function onChange(e) {
setInputValue(e.target.value);
setValid(validatePassword(e.target.value));
}
return(
<div>
<div>Fill the password input and click elsewhere to blur the field</div>
<input
className={`${valid ? 'success' : 'error'}`}
onChange={onChange}
onBlur={onBlur}
value={inputValue}
/>
<div>{valid.toString()}</div>
</div>
);
}
export default App;
I've looked ay many similar questions on SO that seem to be using a very similar logic, but I assume that the app is re-rendering and valid
is being set to false on each render. I thought useState was the correct implementation and binding this to an onChange event would test the input value each time it is changed. I was concerned my regex was not correct so I also tested a simpler condition (which is commented out here) but that is not the issue.
Upvotes: 1
Views: 4229
Reputation: 7033
There are two problems with your code.
1.) validatePassword
uses the useState
's setter, but as a value to set it is using the valid
state (e.g. setValid(!valid)
). As useState
's setter works asynchronously, this will not use the "latest" state. Just use true
or false
directly, no reason to use valid
. That way you're also safe if valid
is changed somewhere else in the code.
2.) In your onChange
, you're calling validatePassword
, which therefore is always setting the value of valid
to false
(or void
, your example at StackOverflow differs from your example of the CodeSandbox), because you're calling validatePassword
in your setValid
.
Just call validatePassword(...)
instead of setValid(validatePassword(...))
, as validatePassword
is already calling setValid
:
function onChange(e) {
setInputValue(e.target.value);
setValid(validatePassword(e.target.value));
}
should be
function onChange(e) {
setInputValue(e.target.value);
validatePassword(e.target.value);
}
Another option would be to return true
or false
from validatePassword
and don't call setValid
inside there, but outside with the return value of validatePassword
.
Working CodeSandbox: https://codesandbox.io/s/patient-worker-7fs84
I don't understand your regex, so I replaced it with a simple "every character is a letter" for demonstration purposes.
Upvotes: 1