#reactjs #regex #react-hooks
#reactjs #регулярное выражение #реагирует-перехваты
Вопрос:
Я пытаюсь создать средство проверки паролей. Моя проблема в том, что логическое valid
значение всегда равно false, даже если регулярное выражение проверяется на правильность. На самом деле я использую typescript в своем приложении, но я сделал демонстрацию здесь только в JSX:
App.js файл выглядит следующим образом:
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)(?=.*[#$@!%amp;*?])[A-Za-zd#$@!%amp;*?]{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;
Я просмотрел много похожих вопросов на SO, которые, похоже, используют очень похожую логику, но я предполагаю, что приложение повторно визуализируется и valid
устанавливается в false при каждом рендеринге. Я думал, что useState является правильной реализацией, и привязка этого к событию onChange будет проверять входное значение при каждом его изменении. Я был обеспокоен тем, что мое регулярное выражение было неправильным, поэтому я также протестировал более простое условие (которое прокомментировано здесь), но это не проблема.
Ответ №1:
В вашем коде есть две проблемы.
1.) validatePassword
использует useState
установщик, но в качестве значения для установки он использует valid
состояние (например setValid(!valid)
). Поскольку useState
установщик работает асинхронно, при этом не будет использоваться «последнее» состояние. Просто используйте true
или false
напрямую, нет причин использовать valid
. Таким образом, вы также в безопасности, если valid
это изменено где-то еще в коде.
2.) В вашем onChange
, вы вызываете validatePassword
, который, следовательно, всегда устанавливает значение valid
to false
(или void
, ваш пример в StackOverflow отличается от вашего примера CodeSandbox), потому что вы вызываете validatePassword
в своем setValid
.
Просто вызовите validatePassword(...)
вместо setValid(validatePassword(...))
, как validatePassword
уже вызывается setValid
:
function onChange(e) {
setInputValue(e.target.value);
setValid(validatePassword(e.target.value));
}
должно быть
function onChange(e) {
setInputValue(e.target.value);
validatePassword(e.target.value);
}
Другим вариантом было бы вернуть true
или false
из validatePassword
и вызывать не setValid
внутри, а снаружи с возвращаемым значением validatePassword
.
Рабочий CodeSandbox: https://codesandbox.io/s/patient-worker-7fs84
Я не понимаю вашего регулярного выражения, поэтому я заменил его простым «каждый символ — это буква» в демонстрационных целях.
Комментарии:
1. Спасибо. Я понял, что
onChange
событие должно быть,validatePassword(e.target.value);
но возврат valid приводил меня в замешательство. Я не вхожу в другой мир ада регулярных выражений. Спасибо2. Теперь вводим! Извините