使用 React-Hook-Form 和 YupResolver 时遇到此错误:尝试导入错误:“set”未从“react-hook-form”导出(导入为“o”)

Posted

技术标签:

【中文标题】使用 React-Hook-Form 和 YupResolver 时遇到此错误:尝试导入错误:“set”未从“react-hook-form”导出(导入为“o”)【英文标题】:Faced this error while using React-Hook-Form and YupResolver: Attempted import error: 'set' is not exported from 'react-hook-form' (imported as 'o') 【发布时间】:2021-07-13 09:13:42 【问题描述】:

我正在使用 Capacitor、Ionic、React 开发应用程序,最近在第一次使用 React Hook Form 和 YupResolver 时遇到了以下错误:

当我尝试运行该项目时,我收到此错误:

Failed to compile
./node_modules/@hookform/resolvers/dist/resolvers.module.js
Attempted import error: 'set' is not exported from 'react-hook-form' (imported as 'o').

我想创建和验证用于更改密码的表单,将新密码提交给外部 API /change-password。表格如下:

Actual Password: ...
New Password: ...
Confirm new Password: ...

Submit

组件:

import 
  IonContent,
  IonPage,
  IonItem,
  IonLabel,
  IonButton,
  IonInput,
  IonRow,
  IonAlert,
  IonGrid,
  IonCol,
 from "@ionic/react";
import React,  useState  from "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(
    password: yup
      .string()
      .min(8, "Password must be at least 8 characters")
      .required("Password is required"),
    newPassword: yup
      .string()
      .min(8, "Password must be at least 8 characters")
      .required("New Password is required"),
    confirmPassword: yup
      .string()
      .oneOf([yup.ref("newPassword"), null], "Passwords must match")
      .required("Confirm Password is required"),
  );

const ChangePassword: React.FC = () => 

//get the actual password from React Contenxt
  const 
    password,
    setPassword,
    alertMessage,
    setAlertMessage,
   = React.useContext(AuthContext);

  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState(""); 

  // functions to build form returned by useForm() hook
  const  register, handleSubmit, errors  = useForm(
    resolver: yupResolver(validationSchema),
  );

  const onSubmit = () => 
    const data = 
      oldPassword: password,
      newPassword: newPassword,
      sourceId: 1,
    ;

    axios
      .post("change-password", data)
      .then((response) => 
        return response.data;
      );
  ;

  return (
    <React.Fragment>
      <IonPage className="ion-page" id="main-content">
        <IonContent className="ion-padding">
          <IonGrid>  
            <h3>Change Password</h3>

            <form onSubmit=handleSubmit(onSubmit)>
              <IonItem>
                <IonLabel position="floating">Actual Password</IonLabel>
                <IonInput
                  name="password"
                  type="password"
                  value=password
                  ref=register
                  className=`form-control $
                    errors.password ? "is-invalid" : ""
                  `
                  onIonChange=(e) => setPassword(e.detail.value!)
                ></IonInput>
                <div className="invalid-feedback">
                  errors.password?.message
                </div>
              </IonItem>

              <IonItem>
                <IonLabel position="floating">New Password</IonLabel>
                <IonInput
                  name="newPassword"
                  type="password"
                  value=newPassword
                  ref=register
                  className=`form-control $
                    errors.newPassword ? "is-invalid" : ""
                  `
                  onIonChange=(e) => setNewPassword(e.detail.value!)
                ></IonInput>
                <div className="invalid-feedback">
                  errors.newPassword?.message
                </div>
              </IonItem>

              <IonItem>
                <IonLabel position="floating">
                  Cofirm New Password
                </IonLabel>
                <IonInput
                  name="confirmPassword"
                  type="password"
                  value=confirmPassword
                  ref=register
                  className=`form-control $
                    errors.confirmPassword ? "is-invalid" : ""
                  `
                  onIonChange=(e) => setConfirmPassword(e.detail.value!)
                ></IonInput>
                <div className="invalid-feedback">
                  errors.confirmPassword?.message
                </div>
              </IonItem>

              <IonButton type="submit">
                Submit
              </IonButton>
            </form>
          </IonGrid>
        </IonContent>
      </IonPage>
    </React.Fragment>
  );
;

export default ChangePassword;
@hookform/resolvers@2.4.0
yup@0.32.9
react-hook-form@6.15.6

任何帮助将不胜感激。谢谢!

【问题讨论】:

当您查看 react-hook-form/resolvers 存储库中的 the peerDependencies 时,您需要使用 react-hook-form ^7.0.0 这不是真的,工作代码沙箱示例没有运行版本 7 @AaronSaunders 沙箱中的代码也没有使用与 OP 代码相同的版本。我不是说你不能让它在旧版本上工作,我只是说如果你要使用@hookform/resolvers ^2.4.0,那么你需要使用 react-hook-form ^ 7.0.0 @Adam,我也是这么想的,我发现没有其他办法继续前进,所以我从 6.15.6 升级到了 7.1.1 react-hook-form.com/migrate-v6-to-v7。谢谢:) 【参考方案1】:

react-hook-form 改变了做事的方式。此外,您不需要自己跟踪值,您可以从 react-hook-form 获取它们。

此代码已经过测试并且可以工作 - 请参阅此处的链接 - https://codesandbox.io/s/react-hook-form-fieldsarray-yup-validation-min-length-forked-rccmg?file=/src/index.js:0-1934

import React from "react";
import ReactDOM from "react-dom";
import  useForm, useFieldArray  from "react-hook-form";
import  object, ref, string  from "yup";
import  yupResolver  from "@hookform/resolvers";
// import "./styles.css";
import "@ionic/react/css/core.css";

import 
  IonContent,
  IonPage,
  IonItem,
  IonLabel,
  IonButton,
  IonInput
 from "@ionic/react";

const validationSchema = object().shape(
  password: string()
    .min(8, "Password must be at least 6 characters")
    .required("Password is required"),
  newPassword: string()
    .oneOf([ref("password"), null], "Passwords must match")
    .required("New Password is required"),
  confirmPassword: string()
    .oneOf([ref("newPassword"), null], "Passwords must match")
    .required("Confirm Password is required")
);

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

  return (
    <IonPage>
      <IonContent>
        <form onSubmit=handleSubmit(console.log)>
          <IonItem>
            <IonLabel>PASSWORD</IonLabel>
            <IonInput name="password" type="text" ref=register></IonInput>
          </IonItem>

          <IonItem>
            <IonLabel>NEW PASSWORD</IonLabel>
            <IonInput name="newPassword" type="text" ref=register></IonInput>
          </IonItem>

          <IonItem>
            <IonLabel>CONFIRM PASSWORD</IonLabel>
            <IonInput
              name="confirmPassword"
              type="text"
              ref=register
            ></IonInput>
          </IonItem>

          <pre>Errors: JSON.stringify(errors, null, 2)</pre>
          <pre>Values: JSON.stringify(getValues(), null, 2)</pre>
          <input type="submit" />
        </form>
      </IonContent>
    </IonPage>
  );


const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

【讨论】:

非常感谢您的回答。我根据您的代码调整了我的代码,但仍然出现错误:尝试导入错误:'set' 不是从'react-hook-form' 导出的(导入为'o')。我认为这可能是与反应挂钩表单版本有关的问题。我将 RHF 从版本 6.x.x 升级到 7.1.1,现在我没有收到此错误。我还有很多需要修复的代码,但至少我没有收到错误。 肯定还有其他错误,因为如果您查看正在运行的代码框示例,您会看到它正在运行而没有升级到版本 7。我专门使用您使用的 RHF 版本进行了测试,我不使用 abs不希望其他阅读本文的人相信修复是您必须升级才能使其正常工作。不过我很高兴你能继续前进 是的,你是对的,我不想说升级 RHF 是解决这个错误的方法,但是由于我使用的是最新版本的解析器,我认为我可以对 RHF 做同样的事情.这就是我升级 RHF 并根据您的代码和 react hook v7 文档调整代码的原因。谢谢你:)【参考方案2】:

我没有找到专门针对此错误的解决方案。所以我决定继续实施并将 RHF 从 6.x.x 升级到最新版本 7.1.1,因为我也在使用最新版本的解析器。 https://react-hook-form.com/migrate-v6-to-v7/ 我还根据 RHF 版本 7 文档调整了实现: https://react-hook-form.com/api/useform

现在它可以正常工作了。

【讨论】:

【参考方案3】:

我在使用 react-hook-form v6.16.5 和 @hookform/resolvers v2.5.2 时遇到了这个问题

我将@hookform/resolvers 降级到v1.3.7,现在可以使用了。

【讨论】:

是的,你是对的。这似乎是 react-hook-form 和解析器版本的问题。就我而言,我使用的是 "react-hook-form": "^7.1.1" 和 "@hookform/resolvers": "^2.4.0" 并且效果很好。【参考方案4】:

我的错误是我将导入实现为

import yupResolver from "@hookform/resolvers"; 而不是

import yupResolver from "@hookform/resolvers/yup";

把这个留在这里,因为它可能对某人有帮助。

【讨论】:

【参考方案5】:

我正在使用 "react-hook-form": "^7.25.1" 版本,我正在导入为

import yupResolver from "@hookform/resolvers"; 取代

您可以如下所示导入(它对我有用)

从 '@hookform/resolvers/yup' 导入 yupResolver ;

【讨论】:

以上是关于使用 React-Hook-Form 和 YupResolver 时遇到此错误:尝试导入错误:“set”未从“react-hook-form”导出(导入为“o”)的主要内容,如果未能解决你的问题,请参考以下文章

react-hook-form:使用 onBlur 模式时验证不起作用

可以将 reactstrap 与 react-hook-form 和 react-input-mask 一起使用吗?

使用 react-select 和 react-hook-form 返回正确的值

React JS 多个提交按钮 react-hook-form

如何使用 React-Hook-Form 设置焦点

如何将 MUI Select 与 react-hook-form 一起使用?