Reactjs 如何解决;termsOfUse必须是布尔类型,但最终值为:“1”;在“上”&引用;使用离子、反应、Yup和分解器

Reactjs 如何解决;termsOfUse必须是布尔类型,但最终值为:“1”;在“上”&引用;使用离子、反应、Yup和分解器,reactjs,typescript,ionic-framework,yup,react-hook-form,Reactjs,Typescript,Ionic Framework,Yup,React Hook Form,我想创建一个注册表,其中所有字段都是必需的。我使用React-Hook表单和Yup进行表单验证。 所有字段都是必填字段,包括两个复选框。 提交表单时,复选框出现以下错误: 术语用法必须是布尔型类型,但最终值为:“on” 我认为这意味着我试图将字符串值“on”保存到yup字段中,这需要一个布尔值。这是因为复选框正在传递target.value而不是target.checked:{…register(“privacyPolicy”)} 我仍然不知道如何传递“checked”而不是“value”,并且

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

术语用法必须是
布尔型
类型,但最终值为:
“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;
<Controller
  control={control}
  name="checkbox"
  render={({ field: { value, onChange } }) => (
    <IonCheckbox
      checked={value}
      onIonChange={({ detail: { checked } }) => onChange(checked)}
    />
  )}
/>

对于本机复选框,
寄存器
调用就足够了:


但是,当您使用带有
的外部受控组件时,您需要使用
控制器
组件:

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;
<Controller
  control={control}
  name="checkbox"
  render={({ field: { value, onChange } }) => (
    <IonCheckbox
      checked={value}
      onIonChange={({ detail: { checked } }) => onChange(checked)}
    />
  )}
/>
(
一旦更改(已选中)}
/>
)}
/>


查看文档中的更多信息。

他们一直在改变它的工作方式,这确实令人沮丧,我即将停止使用react hook表单。。。仅仅更新到下一个版本就会破坏代码???@AaronSaunders在v6中使用
Controller
组件时,这不是同样的工作方式吗?v7中唯一改变的是
render
参数的结构,因为
value
onChange
属性现在嵌套在
字段中。。。在第6版中,它刚刚起作用,您在某一点上不需要使用控制器,{…register('name')}的新格式完全打破了旧代码,如果您升级为像
这样的简单离子组件,仍然可以只使用
register
。是的,用新格式迁移到v7有点麻烦。但是现在对TypeScript的支持也好多了,这使得像
register
这样一些突破性的更改成为必要。@knoefel,谢谢你。它工作正常。:)