Java编程网

分享 Java Web 开发相关知识

如何声明参数并将其传递给离子+反应模态

这些天,我在玩Ionic React,因此尝试了不同的组件。我几乎在所有应用程序中都没有例外地使用过模式之一。尽管它的专用文档非常简洁,但我想进一步说明一下,因为我喜欢在它们自己的单独组件中声明它们。这就是为什么我要写这篇新的博客文章。

入门

要向应用程序中添加模式,请按照文档中显示的步骤进行操作(告诉您,此文档有据可查)。我们使用组件,IonModal并且为了触发它的打开和关闭,我们还使用状态(借助于useState钩子)来修改其property isOpen

import React, {useState} from 'react';
import {IonModal, IonButton, IonContent} from '@ionic/react';

export const Tab1: React.FC = () => {

  const [showModal, setShowModal] = useState(false);

  return (
    <IonContent>
      <IonModal isOpen={showModal}>
        <p>This is the modal content.</p>
        <IonButton onClick={() => setShowModal(false)}>
            Close Modal
        </IonButton>
      </IonModal>
      <IonButton onClick={() => setShowModal(true)}>
            Show Modal
      </IonButton>
    </IonContent>
  );

};

export default Tab1;

请注意,我已经使用*tab入门工具包来开发本文,这就是上面页面名称为Tab1。* 的原因。

创建一个组件

模式很快就会变得和页面一样复杂,这就是为什么我习惯在自己的组件中声明它们。然后,让我们尝试在一个单独的新文件(例如)中创建一个新文件MyModal.tsx

import React from 'react';
import {IonHeader, IonContent, IonToolbar, IonTitle} from '@ionic/react';

class MyModal extends React.Component {

  render() {
    return <>
      <IonHeader>
        <IonToolbar color="primary">
          <IonTitle>My Modal</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent className="ion-padding">
        <p>This is the modal content.</p>
      </IonContent>
    </>
  };

}

export default MyModal;

创建它之后,我们可以在页面中使用它来替换模式的先前内容。

import React, { useState } from 'react';
import { IonModal, IonButton, IonContent} from '@ionic/react';

import MyModal from './MyModal';

export const Tab1: React.FC = () => {

  const [showModal, setShowModal] = useState(false);

  return (
    <IonContent>
      <IonModal isOpen={showModal}>
        <MyModal></MyModal>
        <IonButton onClick={() => setShowModal(false)}>
            Close Modal
        </IonButton>
      </IonModal>
      <IonButton onClick={() => setShowModal(true)}>
            Show Modal
      </IonButton>
    </IonContent>
  );

};

export default Tab1;

关闭模态

超级,我们迈出了第一步,现在我们在单独的组件中声明了一个模式。但是,在上面的示例中,关闭模态的操作(IonButton将显示状态设置为的按钮false)仍然呈现在组件外部,这在设计上有点不幸,因为我认为在模式本身的标题中呈现这样的动作。

为了将此按钮移到模式中,我实际上找到了两种可能的解决方案。一种使用callback,可能是最干净的一种,另一种使用references

可能还有更多,而我很高兴听到他们的消息。因此,请给我您的评论,并在此先感谢您的分享。

打回来

在此解决方案中,我们希望将回调传递给组件以关闭模式。我们通过一个新属性对其进行了增强,该属性也用于标题中以添加相关按钮。

import React from 'react';
import {IonHeader, IonContent, IonToolbar, IonTitle, IonButtons, IonButton, IonIcon} from '@ionic/react';

type MyModalProps = {
  closeAction: Function;
}

class MyModal extends React.Component<MyModalProps> {

  render() {
    return <>
      <IonHeader>
        <IonToolbar color="primary">
          <IonTitle>My Modal</IonTitle>
          <IonButtons slot="end">
            <IonButton onClick={() => this.props.closeAction()}>
              <IonIcon name="close" slot="icon-only"></IonIcon>
            </IonButton>
          </IonButtons>
        </IonToolbar>
      </IonHeader>
      <IonContent className="ion-padding">
        <p>This is the modal content.</p>
      </IonContent>
    </>
  };

}

export default ({closeAction}: { closeAction: Function }) => (
  <MyModal closeAction={closeAction}>
  </MyModal>
)

修改组件后,我们可以在页面中创建一个新函数来将显示状态设置为false,并将其作为回调传递给组件。

import React, {useState} from 'react';
import {IonModal, IonButton, IonContent} from '@ionic/react';

import MyModal from './MyModal';

export const Tab1: React.FC = () => {

  const [showModal, setShowModal] = useState(false);

  async function closeModal() {
    await setShowModal(false);
  }

  return (
    <IonContent>
      <IonModal isOpen={showModal}>
        <MyModal closeAction={closeModal}></MyModal>
      </IonModal>
      <IonButton onClick={() => setShowModal(true)}>
        Show Modal
      </IonButton>
    </IonContent>
  );

};

export default Tab1;

参考文献

另一种可能的解决方案是使用DOM引用来消除模态。

import React, {RefObject} from 'react';
import {IonHeader, IonContent, IonToolbar, IonTitle, IonButtons, IonButton, IonIcon} from '@ionic/react';

class MyModal extends React.Component {
  headerRef: RefObject<HTMLIonHeaderElement> = React.createRef();

  async closeModal() {
    if (!this.headerRef || !this.headerRef.current) {
      return;
    }
    await (this.headerRef.current.closest('ion-modal') as 
                HTMLIonModalElement).dismiss();
  }

  render() {
    return <>
      <IonHeader ref={this.headerRef}>
        <IonToolbar color="primary">
          <IonTitle>My Modal</IonTitle>
          <IonButtons slot="end">
            <IonButton onClick={() => this.closeModal()}>
              <IonIcon name="close" slot="icon-only"></IonIcon>
            </IonButton>
          </IonButtons>
        </IonToolbar>
      </IonHeader>
      <IonContent className="ion-padding">
        <p>This is the modal content 3.</p>
      </IonContent>
    </>
  };

}

export default MyModal;

上面的方法的效果是 state,在我们的页面中用于显示目的的our可能最终不再与模式的有效状态同步,因为我们使用DOM关闭了它。为了克服这种情况,我们可以在关闭对话框后同步信息。

import React, {useState} from 'react';
import {IonModal, IonButton, IonContent} from '@ionic/react';

import MyModal from './MyModal';

export const Tab1: React.FC = () => {

  const [showModal, setShowModal] = useState(false);

  return (
    <IonContent>
      <IonModal isOpen={showModal}
        onDidDismiss={() => setShowModal(false)}>
        <MyModal></MyModal>
      </IonModal>
      <IonButton onClick={() => setShowModal(true)}>
        Show Modal
      </IonButton>
    </IonContent>
  );

};

export default Tab1;

但是不幸的是,这种方法有一个缺点。当我们修改状态以使其同步时,我们的组件将被“渲染”。因此,它的性能比解决方案要差一些callback,这就是为什么我找到了第一台解决方案更清洁的原因。

旁注:昨天晚上,我花了几个小时尝试不成功地shouldComponentUpdate分别包装React.Memo模态组件,以免在取消模态后修改状态后不再呈现页面。也许有可能,我也很高兴再次听到与此有关的任何提示😉

传递参数

在前面的示例中,我们已经使用了一个属性来传递回调以关闭模式。同样,我们可以使用相同的方法来定义任何其他属性。

import React from 'react';
import {IonHeader, IonContent, IonToolbar, IonTitle, IonButtons, IonButton, IonIcon} from '@ionic/react';

type MyModalProps = {
  closeAction: Function;
  text: string;
}

class MyModal extends React.Component<MyModalProps> {
  render() {
    return <>
      <IonHeader>
        <IonToolbar color="primary">
          <IonTitle>My Modal</IonTitle>
          <IonButtons slot="end">
            <IonButton onClick={() => this.props.closeAction()}>
              <IonIcon name="close" slot="icon-only"></IonIcon>
            </IonButton>
          </IonButtons>
        </IonToolbar>
      </IonHeader>
      <IonContent className="ion-padding">
        <p>{this.props.text}</p>
      </IonContent>
    </>
  };
}

export default ({closeAction, text}: { closeAction: Function, text: string }) => (
  <MyModal closeAction={closeAction} text={text}>
  </MyModal>
)

因此,将页面中的任何其他参数传递给我们的模态组件。

import React, {useState} from 'react';
import {IonModal, IonButton, IonContent} from '@ionic/react';

import MyModal from './MyModal';

export const Tab1: React.FC = () => {

  const [showModal, setShowModal] = useState(false);

  async function closeModal() {
    await setShowModal(false);
  }

  return (
    <IonContent>
      <IonModal isOpen={showModal}>
        <MyModal closeAction={closeModal}
                 text="This is the updated modal content.">
        </MyModal>
      </IonModal>
      <IonButton onClick={() => setShowModal(true)}>
        Show Modal
      </IonButton>
    </IonContent>
  );
};

export default Tab1;

超越无限🚀

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注