react-bootstrap 表单中的自定义验证不起作用

Custom validation in react-bootstrap forms not working

我正在尝试将自定义验证逻辑添加到我的 react-bootstrap 表单中,但 isInvalid 似乎没有得到遵守。一旦在表单上设置了 validated={true},它总是验证 non-empty 个字符串,而不管 isValidisInvalid。显示无效消息,但该字段显示为绿色。看这里:

这是有问题的代码:

 <Form noValidate validated={formValidated} id="bidForm">
    <Form.Group className="mb-3" controlId="formBasicBidding">
       <Form.Label>Bid Amount</Form.Label>
       <InputGroup hasValidation className="mb-3">
           <InputGroup.Text id="inputGroupPrepend">$</InputGroup.Text>
           <Form.Control
              required
              value={bidAmount}
              isInvalid={!(parseInt(bidAmount) > 0) && formValidated}
              onChange={e => setBidAmount(e.target.value)}
           />
           <InputGroup.Text id="inputGroupAppend">.00</InputGroup.Text>
           <Form.Control.Feedback type="invalid">
               Please select a dollar amount {`>`} 0
           </Form.Control.Feedback>
        </InputGroup>
    </Form.Group>
    <...>
</Form>

我能够在输入中使用 pattern= 正则表达式使其工作,但我计划在正则表达式不够用的情况下进行更复杂的验证。我怎样才能让 react-bootstrap 正确地跟随 isValidisInvalid?谢谢!

文档没有做 很好的 工作来阐明这一点,但是 form-level validated 属性直接挂钩到 HTML5的本机验证库,不能与其他验证技术同时使用。因此,如果您使用 native 选项并且输入不违反任何 native 验证选项 (required, pattern, etc),则输入将被视为有效。由于您的出价输入除了 required 之外没有任何本机验证属性,因此就 React-Bootstrap 而言,“foo”是有效的。

(如果您认为“让您同时使用两者的代码设计很糟糕”,我倾向于同意您的看法。)

您会注意到,使用您当前的代码,如果您输入“foo”并提交表单,该元素实际上 具有 is-invalid class 应用于它,但它也应用了 :valid psuedo-selector 因为整个表单都经过验证,从 CSS 的角度来看似乎优先:

此处最好的解决方案是使用 本机 HTML5 验证选项(detailed here) or roll your own(有或没有像 Formik 这样的辅助库),但不能同时进行.

如果您试图在输入实际上处于“脏”状态(例如,用户填写或提交表单)之前避免验证,您可以这样做 (CodePen here) :

        <Form.Control
          required
          value={bidAmount}
          isInvalid={!(parseInt(bidAmount) > 0) && (bidAmount.length || formSubmitted)}
          onChange={(e) => setBidAmount(e.target.value)}
        />