nice-modal-react
nice-modal-react copied to clipboard
Unnecessary re-render when showing multiple modals..
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
- Declare modal constants
export const ModalConstant = {
modalA: "Modal_A",
modalB: "Modal_B",
modalC: "Modal_C",
};
- in
index.tsx
, call register function
NiceModal.register(ModalConstant.modalA, ModalA);
NiceModal.register(ModalConstant.modalB, ModalB);
NiceModal.register(ModalConstant.modalC, ModalC);
- 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>
);
}
- muti
modal.tsx
- Only the title is different
- In
ModalA.tsx
, click will showModalB
- In
ModalB.tsx
, click will showModalC
...
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
- Call
showModalA()
inApp.tsx
, it opens the Modal, without re-rendering the App(desired); - Call
showModalB()
inModalA.tsx
, it opens the Modal B, causes a re-render to the Modal A(not desired). - Call
showModalC()
inModalB.tsx
, it opens the Modal C, causes a re-render to the Modal A and Modal B(not desired). - 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?