如何解决“termsOfUse 必须是布尔类型,但最终值为:“on”。使用 Ionic、React、Yup 和解析器

Posted

技术标签:

【中文标题】如何解决“termsOfUse 必须是布尔类型,但最终值为:“on”。使用 Ionic、React、Yup 和解析器【英文标题】:How to solve "termsOfUse must be a boolean type, but the final value was: "on"." using Ionic, React, Yup and Resolvers 【发布时间】:2021-07-15 14:17:18 【问题描述】:

我想创建一个注册表单,其中所有字段都是必需的。我正在使用 React Hook Form 和 Yup 进行表单验证。 所有字段都是必需的,包括两个复选框。 当我提交表单时,复选框出现此错误:

termsOfUse 必须是 boolean 类型,但最终值为:"on"

我认为这意味着我正在尝试将字符串值“on”保存到 yup 字段中,这需要一个布尔值。这是因为复选框传递的是 target.value 而不是 target.checked: ...register("privacyPolicy")

我仍然不知道如何传递 'checked' 而不是 'value' 并通常在 RHF 中使用复选框输入。 任何帮助将非常感激。谢谢你:)

组件:

import React from "react";
import  useHistory  from "react-router-dom";
import  useState  from "react";
import 
  IonPage,
  IonHeader,
  IonToolbar,
  IonTitle,
  IonContent,
  IonButton,
  IonInput,
  IonLabel,
  IonItem,
  IonLoading,
  IonToast,
  IonSelectOption,
  IonSelect,
  IonRadio,
  IonCheckbox,
  IonGrid,
  IonRow,
  IonCol,
  IonAlert,
 from "@ionic/react";
import  useForm  from "react-hook-form";
import  yupResolver  from "@hookform/resolvers/yup";
import * as yup from "yup";
import axios from "axios";

// form validation rules
const validationSchema = yup.object().shape(
  email: yup
    .string()
    .email("E-mail is invalid!")
    .min(7, "E-Mail must have 7 characters")
    .required("E-Mail is required"),
  password: yup
    .string()
    .min(8, "Password should have at least 8 characters!")
    .required("Password is required"),
  termsOfUse: yup
    .boolean()
    .oneOf([true], "You should accept terms of use"),
  privacyPolicy: yup
    .boolean()
    .oneOf([true], "You should accept privacy policy"),
);

const CreateAccountPage: React.FC = () => 
 
  const [checkedTermsOfUse, setCheckedTermsOfUse] = useState(false);
  const [checkedPrivacyPolicy, setCheckedPrivacyPolicy] = useState(false);

  const history = useHistory();

  const 
    register,
    handleSubmit,
    formState:  errors ,
    getValues,
   = useForm(
    mode: "onChange",
    resolver: yupResolver(validationSchema),
  );

  const doCreateAccount = () => 
    const data = 
      eMail: getValues("email"),
      password: getValues("password"),
    ;

    axios
      .post("xx/register", data)
      .then((response) => 
        return response.data;
      )
  ;

  return (
    <IonPage>
      <IonHeader>
      </IonHeader>
      <IonContent className="ion-padding">
           
          <form
            className="ion-padding"
            onSubmit=handleSubmit(doCreateAccount)
          >
          
            <IonItem>
              <IonLabel position="floating">E-Mail *</IonLabel>
              <IonInput type="email" ...register("email") />
            </IonItem>
            errors.email && <p>errors.email.message</p>
            
            <IonItem>
              <IonLabel position="floating">
                Password *
              </IonLabel>
              <IonInput type="password" ...register("password") />
            </IonItem>
            

            <div>
              <IonCheckbox
                checked=checkedTermsOfUse
                ...register("termsOfUse")
              ></IonCheckbox>" "
              <a
                href="https://wss-rest.api.woehlke.de/type/agreement-version-content/1"
                target="_blank"
              >
                I accept terms of use
              </a>
            </div>
            errors.termsOfUse && <p>errors.termsOfUse.message</p>

            <div>
              <IonCheckbox
                ...register("privacyPolicy")
                checked=checkedPrivacyPolicy
              ></IonCheckbox>" "
              <a
                href="https://wss-rest.api.woehlke.de/type/agreement-version-content/3"
                target="_blank"
              >
                I accept privacy policy
              </a>
            </div>
            errors.privacyPolicy && <p>errors.privacyPolicy.message</p>

            <IonButton type="submit">Submit</IonButton>
            <IonButton onClick=() => history.goBack() color="danger">
              CANCEL
            </IonButton>
          </form>
      </IonContent>
    </IonPage>
  );
;

export default CreateAccountPage;
"@hookform/resolvers": "^2.4.0",
"react-hook-form": "^7.1.1",
"yup": "^0.32.9"

【问题讨论】:

【参考方案1】:

对于原生复选框,register 调用就足够了:

<input
  type="checkbox"
  ...register("nativeCheckbox")
/>

但是当您使用带有&lt;IonCheckbox /&gt; 的外部受控组件时,您需要使用Controller 组件:

<Controller
  control=control
  name="checkbox"
  render=( field:  value, onChange  ) => (
    <IonCheckbox
      checked=value
      onIonChange=( detail:  checked  ) => onChange(checked)
    />
  )
/>

查看文档中的section 了解更多信息。

【讨论】:

他们一直在改变它的工作方式,老实说越来越令人沮丧,我即将停止使用 react-hook-form... 只是更新到下一个版本会破坏代码?? @AaronSaunders 在 v6 中使用 Controller 组件的方式不一样吗?在 v7 中唯一改变的是 render 的参数结构,因为 valueonChange 属性现在嵌套在 field 属性中。 我相信在一次迭代中......在版本 6 中它刚刚工作,你不需要在某些时候使用控制器,而且这种新格式的 ...register('name') 如果您升级,则完全破坏旧代码 对于像&lt;IonInput /&gt; 这样的简单离子组件,仍然可以使用registeronly。 codesandbox.io/s/… 是的,使用新格式迁移到 v7 有点麻烦。但是现在对 TypeScript 的支持也变得更好了,这使得一些重大更改(例如 register)成为必要。 @knoefel,谢谢。它工作正常。 :)

以上是关于如何解决“termsOfUse 必须是布尔类型,但最终值为:“on”。使用 Ionic、React、Yup 和解析器的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 Ajax 跨域请求不到的问题

如何解决包冲突问题

如何解决包冲突问题

如何解决ajax跨域问题

MySQL 的 10048问题,如何解决?

如何解决smartgit的冲突问题