【问题标题】:Why setCustomValidity() not working in React app?为什么 setCustomValidity() 在 React 应用程序中不起作用?
【发布时间】:2017-12-19 11:15:34
【问题描述】:

为什么setCustomValidity() 在 React 中不起作用?我错过了什么吗?使用 vanillia HTML 和 JS 可以正常工作。或者还有其他方法可以轻松制作类似于setCustomValidity 的东西?

反应代码:

class Form extends React.Component {
  formVal(e) {
    e.target.setCustomValidity("Test_1");
  }
  formVal2() {
    let inpt = document.getElementById("input");
    inpt.target.setCustomValidity("TEST_2");
  }
  render() {
    return (
      <div>
        <form>
          <input
            id="input"
            type="datetime-local"
            onBlur={this.formVal}
          />
        </form>
        <button onClick={this.formVal2}>Click </button>
      </div>
    );
  }
}

CodePen - React

没有反应:

<form>
  <input type="email" id="mail" name="mail">
  <button onclick="test()">Submit</button>
</form>

// JS

var input = document.getElementById("mail");
function test() {
 input.setCustomValidity("test")
}

CodePen - no React

【问题讨论】:

  • 检查函数formVal2,不需要.target
  • @Mikalai 你是对的,但仍然无法正常工作。 React 不推荐通过document.getElementById() 获取元素。

标签: javascript html reactjs


【解决方案1】:

setCustomValidity 不会立即触发验证,您必须有一个表单提交事件来触发它或调用checkValidity。我已经更新了你的 CodePen 以展示你如何在 React 中实现这一点,它也包含在下面。

class Form extends React.Component {
  
  onChange(e) {
    let date = new Date(Date.parse(e.target.value));
    
    if (date > new Date()) {
      e.target.setCustomValidity("Please select a date in the past."); 
    } else {
      e.target.setCustomValidity("");
    }
  }
    
  render() {
    return (
      <div>
        <form>
          <input
            id="input"
            type="datetime-local"
            onChange={this.onChange}
          />
          <button type="submit">Submit</button>
        </form>
      </div>
    );
  }
}

ReactDOM.render(<Form />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

【讨论】:

  • 请注意,在 Mac、Chrome 上,如果在提交表单时字段不在视口中,则错误消息将不可见!如果该字段在视口上可见,那么只有我们可以看到正确的消息,否则,该 resp 字段将被聚焦,但错误消息将不存在!
【解决方案2】:

你好,这是你需要做的。

import * as React from "react";

export default function Form () {
  const nameInput = React.useRef<HTMLInputElement>(null);
  const [nameVal,setNameVal] = React.useState("");

  const onSubmitHandler = (e: React.FormEvent<HTMLFormElement>) => {
   // handle yow submition
  }

  const onNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (!nameInput.current) return;

    setNameVal(e.currentTarget.value);
    const {validity} = nameInput.current;

    if (nameInput.current.validity.badInput) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

    if (nameInput.current.validity.customError) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

    if (validity.patternMismatch) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

    if (validity.rangeOverflow) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

    if (nameInput.current.validity.rangeUnderflow) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

    if (validity.stepMismatch) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

    if (validity.tooLong) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

    if (validity.tooShort) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

    if (validity.typeMismatch) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

    if (validity.valid) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

    if (validity.valueMissing) {
      nameInput.current.setCustomValidity("Set the message to show");
    }

  
  }

  return (
    <form onSubmit={onSubmitHandler}>
     <label htmlFor="id-name">Name</label>
     <input 
        ref={nameInput}
        type="text"
        required
        min={5}
        max={15}
        value={nameVal}
        onChange={onNameChange}
      />
      <button type="submit">submit</button>
    </form>
  )
  
}

我的意思是您不必添加所有这些,只需添加您关心的那些

【讨论】:

    【解决方案3】:

    简答:

    <input required onInvalid={(e)=>{e.target.setCustomValidity('Your custom validation message here')}} />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      相关资源
      最近更新 更多