'Faced this error while using React-Hook-Form and YupResolver: Attempted import error: 'set' is not exported from 'react-hook-form' (imported as 'o')

I'm developing an app using Capacitor, Ionic, React and recently I faced the following error, while using React Hook Form and YupResolver for the first time:

When I try to run the project, I get this error:

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').

I want to create and validate a form for changing Password, submitting the new Password to an external API /change-password. The form will be like below:

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

Submit

The component:

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/[email protected]
[email protected]
[email protected]

Any help would be really appreciated. Thanks!



Solution 1:[1]

I ran into this issue when using react-hook-form v6.16.5 and @hookform/resolvers v2.5.2

I downgraded @hookform/resolvers to v1.3.7 and it works now.

Solution 2:[2]

My error was that I had implemented the import as

import { yupResolver } from "@hookform/resolvers"; instead of

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

Leaving this here as it may help someone.

Solution 3:[3]

The way things are done have changed with react-hook-form. Also you don't need to track the values yourself, you can get them from react-hook-form.

This code is tested and works - See link here - 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);

Solution 4:[4]

I am using "react-hook-form": "^7.25.1" version and i was importing as

import { yupResolver } from "@hookform/resolvers"; Instaed of

you can import as shown below (it's working for me)

import { yupResolver } from '@hookform/resolvers/yup';

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 anthony
Solution 2 M. Arnold
Solution 3 Aaron Saunders
Solution 4 Bahubali Ak