Ionic 如何正确更新基于离子React的React钩子形式中的isDirty值

zed5wv10  于 2023-01-28  发布在  Ionic
关注(0)|答案(1)|浏览(148)

我有一个关于Ionic react的应用程序,有两个呈现组件,其中一个绘制另一个,第二个modal,有两个钩子,一个负责打开和关闭modal,第二个用于表单处理逻辑,我需要在输入字段时检查表单是否脏,我需要立即更新值isDirty,因为我想将其更改后的值从useModalForm通过Management和MyModal传递到useModalHandler挂钩,作为“closeModal”函数的参数,以便当用户开始在字段中输入值时,isDirty更改为true,并且如果我没有保存就关闭表单,应该调用myAlert来警告数据丢失。但实际上,isDirty在用户输入字段时并不更改值,问题可能是什么?

管理部分

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 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;

使用ModalForm挂接

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;

未保存的更改警报组件

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;
u59ebvdq

u59ebvdq1#

使用useForm时,可以指定模式:

mode: onChange | onBlur | onSubmit | onTouched | all

你可以使用onChange或者onTouched模式来实现你想要的东西。在你的useForm声明中,它看起来像这样:

const {
    handleSubmit, 
    register,
    onSubmit,
    reset,
    formState: { errors, isDirty },
  } = useModalForm({ mode: 'onTouched' });

相关问题