【问题标题】:React validate input with regex and useState hook使用正则表达式和 useState 钩子响应验证输入
【发布时间】:2020-11-24 08:34:03
【问题描述】:

我正在尝试构建密码验证器。我的问题是布尔值valid 总是错误的,即使正则表达式被测试为正确。我实际上在我的应用程序中使用了打字稿,但我只是在 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)(?=.*[#$@!%&*?])[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;

我在 SO 上查看了许多类似的问题,这些问题似乎使用了非常相似的逻辑,但我假设应用程序正在重新渲染,并且 valid 在每次渲染时都设置为 false。我认为 useState 是正确的实现,并且将其绑定到 onChange 事件会在每次更改时测试输入值。我担心我的正则表达式不正确,所以我还测试了一个更简单的条件(此处已注释掉),但这不是问题。

【问题讨论】:

    标签: reactjs regex react-hooks


    【解决方案1】:

    您的代码有两个问题。

    1.) validatePassword 使用useState 的设置器,但作为设置它的值使用valid 状态(例如setValid(!valid))。由于useState 的设置器是异步工作的,因此不会使用“最新”状态。直接用true或者false就行了,没理由用valid。这样,如果在代码中的其他位置更改了 valid,您也是安全的。

    2.) 在您的onChange 中,您调用的是validatePassword,因此始终将valid 的值设置为false(或void,您在StackOverflow 的示例与您的示例不同CodeSandbox),因为您在 setValid 中调用了 validatePassword

    只需调用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);
      }
    

    另一种选择是从validatePassword 返回truefalse,不要在内部调用setValid,而是在外部调用validatePassword


    工作代码沙盒:https://codesandbox.io/s/patient-worker-7fs84

    我不懂你的正则表达式,所以我用一个简单的“每个字符都是一个字母”来代替它以进行演示。

    【讨论】:

    • 谢谢。我发现onChange 事件应该是validatePassword(e.target.value);,但返回有效值让我绕了弯路。我没有进入正则表达式地狱的不同世界。谢谢
    • 现在进入!对不起
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2016-02-26
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多