Unnecessary re-render when showing multiple modals..
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.3k
- Forks
- 127
- PR merge metrics
- No merged PRs in 30d
Description
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?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the App.tsx, index.tsx, and cascading modal component examples described in the issue, then reproduce the behavior using the linked CodeSandbox. Use the console logs to compare renders while opening Modal A, B, and C. Done means opening a nested modal no longer re-renders the already visible parent modals.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100