Right now, I have a react portal rendering a 'pinnable' side drawer modal that will display based on a redux state. The contents of the modal will have information based on where that modal was pinned from, in this case my notifications.
The problem I'm running into at the moment is that since the modal will be pinnable in multiple places, I'm not exactly sure of the logic on how to handle the modal contents if the modal is already pinned.
I've tried/considered the following:
- Just have one portal render its children dynamically. Unfortunately the location of where the portal will be rendered does not contain the contents and logic of the modal, so I believe this can't be done.
- Compare
props.children
and if they're not identical, render the newer portal and deconstruct the other. I'm hesitant to use this approach since I believe there's a better solution out there. - Render the portals based on Ids and deconstruct/reconstruct where needed if one exists. I'm leaning towards this approach, but again I'd like to see if there's a better one.
Portal location:
export default function PaperContainer() {
return <div id="pinned-container"></div>;
}
Portal:
export default function PinnedContainer(props) {
const pinned = useSelector(state => state.ui.isDrawerPinned);
return (
pinned &&
createPortal(
<div>
<div>{props.children}</div>
</div>
,
document.getElementById('pinned-container')
)
);
}
Where the portals are called (simplified for brevity):
export default function PortalCallLocationOne() {
const dispatch = useDispatch();
const pinContainer = () => {
dispatch(toggleDrawer());
};
return (
<>
<Button startIcon={<Icon>push_pin</Icon>} onClick={() => pinContainer}>
Pin Notification
</Button>
<PinnedContainer>
//Notification
</PinnedContainer>
</>
);
}
export default function PortalCallLocationTwo() {
const dispatch = useDispatch();
const pinContainer = () => {
dispatch(toggleDrawer());
};
return (
<>
<Button startIcon={<Icon>push_pin</Icon>} onClick={() => pinContainer}>
Pin List
</Button>
<PinnedContainer>
// List
</PinnedContainer>
);
</>
}