Реагируйте на проверку входных данных с помощью регулярного выражения и useState hook

#reactjs #regex #react-hooks

#reactjs #регулярное выражение #реагирует-перехваты

Вопрос:

Я пытаюсь создать средство проверки паролей. Моя проблема в том, что логическое valid значение всегда равно false, даже если регулярное выражение проверяется на правильность. На самом деле я использую typescript в своем приложении, но я сделал демонстрацию здесь только в JSX:

https://codesandbox.io

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. Теперь вводим! Извините