Skip to content

Unnecessary re-render when showing multiple modals.. #162

@sandlz

Description

@sandlz

Business description

In my App, there are a lot of modals that need to be displayed, so in some business scenarios, there may be 5 or more modals displayed cascading.

As follows:
Modal-A
-- Modal-B
------ Modal-C
---------- Modal-D

Code description

Example link

  1. Declare modal constants
export const ModalConstant = {
  modalA: "Modal_A",
  modalB: "Modal_B",
  modalC: "Modal_C",
};
  1. in index.tsx, call register function
NiceModal.register(ModalConstant.modalA, ModalA);
NiceModal.register(ModalConstant.modalB, ModalB);
NiceModal.register(ModalConstant.modalC, ModalC);
  1. in App.tsx
export default function App() {
  console.log("App render");

  const showModalA = () => {
    NiceModal.show(ModalConstant.modalA, {});
  };

  return (
    <div className="App">
      <h1>Muti Modal Re-render demo</h1>
      <Button variant="secondary" onClick={showModalA}>
        Show Modal [A]
      </Button>
    </div>
  );
}
  1. muti modal.tsx
  • Only the title is different
  • In ModalA.tsx, click will show ModalB
  • In ModalB.tsx, click will show ModalC ...
import BootstrapModal from "react-bootstrap/Modal";
import NiceModal, { useModal, bootstrapDialog } from "@ebay/nice-modal-react";
import { ModalConstant } from "../constant";
import Button from "react-bootstrap/Button";

const ModalA = NiceModal.create(() => {
  const modal = useModal();

  console.log("Modal [A] render", `id: ${modal.id}, visible: ${modal.visible}`);
  const showModalB = () => {
    NiceModal.show(ModalConstant.modalB, {});
  };

  return (
    <BootstrapModal {...bootstrapDialog(modal)}>
      <BootstrapModal.Header closeButton>
        <BootstrapModal.Title>Modal A</BootstrapModal.Title>
      </BootstrapModal.Header>

      <BootstrapModal.Body>
        <p>This is modal A.</p>
        <Button variant="secondary" onClick={showModalB}>
          Show Modal [B]
        </Button>
      </BootstrapModal.Body>

      <BootstrapModal.Footer>
        <Button variant="secondary" onClick={modal.hide}>
          Close
        </Button>
        <Button variant="primary" onClick={modal.hide}>
          Save changes
        </Button>
      </BootstrapModal.Footer>
    </BootstrapModal>
  );
});

export default ModalA;

Step

  1. Call showModalA() in App.tsx, it opens the Modal, without re-rendering the App(desired);
  2. Call showModalB() in ModalA.tsx, it opens the Modal B, causes a re-render to the Modal A(not desired).
  3. Call showModalC() in ModalB.tsx, it opens the Modal C, causes a re-render to the Modal A and Modal B(not desired).
  4. Console logs
Modal [A] render id: Modal_A, visible: false
2Modal [A] render id: Modal_A, visible: true
Modal [B] render id: Modal_B, visible: false
Modal [A] render id: Modal_A, visible: true
Modal [B] render id: Modal_B, visible: true
Modal [A] render id: Modal_A, visible: true
Modal [B] render id: Modal_B, visible: true
Modal [C] render id: Modal_C, visible: false
Modal [A] render id: Modal_A, visible: true
Modal [B] render id: Modal_B, visible: true
Modal [C] render id: Modal_C, visible: true

Questions

As you can see, opening the next Modal causes the previous modals re-render.

How can I get around this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions