@WorksDens
JustDen

Как правильно обновить значения isDirty в React Hook Form на основе приложения Ionic React?

У меня есть приложение на Ionic react, есть две презентационных компоненты, один отрисовывает другой, второй модал. Есть два хука, один отвечает за открытие и закрытие модала, второй за логику обработки формы, мне нужно проверить, не загрязнена ли форма при вводе поля, мне нужно, чтобы значение isDirty обновлялось немедленно, потому что я хочу передать его измененное значение из useModalForm через MyModal в хук useModalHandler в качестве аргумента функции closeModal, так что, когда пользователь начинает вводить значение в поле, isDirty менялось на true, и если закрыть форму без сохранения, по условию должен вызываться myAlert, который предупреждает о потере данных.
Но на практике isDirty не меняет значение в момент ввода, в чем может быть проблема?

import React from "react";
import {
  IonModal,
  IonHeader,
  IonToolbar,
  IonButton,
  IonIcon,
  IonContent,
  IonItem,
  IonLabel,
  IonInput,
  IonCard,
  IonCardContent,
} from "@ionic/react";
import UnsavedChangesAlert from "../Alert/MyAlert";

interface MyModalProps {
  isOpen: boolean;
  closeModal: (isDirty: boolean) => void;
  errors: any;
  isDirty: boolean;
  register: any;
  handleSubmit: any;
  onSubmit: (event: any) => void;
  reset: any;
  showAlert: boolean;
  handleCancel: () => void;
  handleConfirm: () => void;
};

const MyModal: React.FC<MyModalProps> = ({
  isOpen,
  closeModal,
  register,
  onSubmit,
  handleSubmit,
  errors,
  isDirty,
  showAlert,
  handleCancel,
  handleConfirm,
}) => {

  return (
    <IonModal isOpen={isOpen}>
      <IonHeader>
        <IonToolbar>
          <IonButton slot="start" onClick={() => closeModal(isDirty)}>
            <IonIcon slot="icon-only" name="arrow-back-outline"></IonIcon>
          </IonButton>
          <IonButton slot="end" type="submit" form="myForm">
            <IonLabel>Save</IonLabel>
          </IonButton>
        </IonToolbar>
      </IonHeader>
      <IonContent>
        <IonCard>
          <IonCardContent>
            <form onSubmit={handleSubmit(onSubmit)} id="myForm">
              <IonItem>
                <IonLabel position="floating">Product Name</IonLabel>
                <IonInput
                  type="text"
                  {...register("name", { required: true })}
                ></IonInput>
              </IonItem>
              {errors.name && <span>This field is required</span>}
              <IonItem>
                <IonLabel position="floating">Amount</IonLabel>
                <IonInput
                  type="number"
                  {...register("amount")}
                ></IonInput>
              </IonItem>
            </form>
          </IonCardContent>
        </IonCard>
        {isDirty && showAlert && (
          <UnsavedChangesAlert
            isOpen={showAlert}
            onCancel={handleCancel}
            onConfirm={handleConfirm}
          />
        )}
      </IonContent>
    </IonModal>
  );
};

export default MyModal;


import React from "react";
import {
  IonPage,
  IonHeader,
  IonToolbar,
  IonTitle,
  IonContent,
  IonButton,
  IonIcon,
  IonLabel,
} from "@ionic/react";
import { add } from "ionicons/icons";
import MyModal from "./Modal/MyModal";
import useModalForm from "../../../Hooks/useModalForm";
import useModalHandler from "../../../Hooks/useModalHandler";

const Management: React.FC<any> = () => {
  
  const {
    handleSubmit, 
    register,
    onSubmit,
    reset,
    formState: { errors, isDirty },
  } = useModalForm();

  const {
    isOpen,
    showAlert,
    openModal,
    closeModal,
    handleCancel,
    handleConfirm,
  } = useModalHandler();

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Management</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent>
        <IonButton expand="block" onClick={openModal}>
          <IonIcon icon={add} />
          <IonLabel>Add Product</IonLabel>
        </IonButton>
        <MyModal
          isOpen={isOpen}
          closeModal={closeModal}
          register={register}
          handleSubmit={handleSubmit}
          onSubmit={onSubmit}
          errors={errors}
          isDirty={isDirty}
          reset={reset}
          showAlert={showAlert}
          handleCancel={handleCancel}
          handleConfirm={handleConfirm}
        />
      </IonContent>
    </IonPage>
  );
};
export default Management;


import { IonAlert } from "@ionic/react";

const UnsavedChangesAlert: React.FC<{
  isOpen: boolean;
  onCancel: () => void;
  onConfirm: () => void;
}> = ({ isOpen, onCancel, onConfirm }) => {
  
  return (
    <IonAlert
      isOpen={isOpen}
      header={"Unsaved Changes"}
      message={"Are you sure you want to discard unsaved changes?"}
      buttons={[
        {
          text: "Cancel",
          role: "cancel",
          cssClass: "secondary",
          handler: onCancel,
        },
        {
          text: "Unsave Changes",
          handler: onConfirm,
        },
      ]}
    />
  );
};

export default UnsavedChangesAlert;


import { useForm } from "react-hook-form";

  const useModalForm = () => {
    const {
      register,
      handleSubmit,
      formState: {
        errors,
        isDirty
      },
      reset
    } = useForm({
      defaultValues: {
        name: '',
        amount: '',
  }});

  console.log(isDirty);


    const onSubmit = (data: any) => {
      console.log(JSON.stringify(data, null, 2));
      reset();
    };

    return {
      register,
      handleSubmit,
      onSubmit,
      reset,
      formState: {
        errors,
        isDirty,
      }
    };
  };

  export default useModalForm;


import { useState } from "react";

const useModalHandler = () => {

  const [isOpen, setIsOpen] = useState(false);
  const [showAlert, setShowAlert] = useState(false);

  const openModal = () => {
    setIsOpen(true);
    setShowAlert(false);
  };

  const closeModal = (isDirty: boolean) => {
    if (isDirty) {
      setShowAlert(true);
    } else {
      setIsOpen(false);
    }
  };

  const handleCancel = () => {
    setIsOpen(false);
    setShowAlert(false);
  };

  const handleConfirm = () => {
    setIsOpen(false);
    setShowAlert(false);
  };

  return {
    isOpen,
    showAlert,
    openModal,
    closeModal,
    handleCancel,
    handleConfirm,
  };
};

export default useModalHandler;
  • Вопрос задан
  • 145 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы