I am trying to build a simple React web app that utilizes Bootstrap. Specifically, I was trying to use its tooltips component. I initialize every tooltip on a page using a custom hook with some tweaks to the code found in the Bootstrap Docs like so:
function useInitializeTooltips({ trigger = "hover focus" } = {}) {
useEffect(() => {
document.querySelectorAll(`[data-bs-toggle="tooltip"]`)
.forEach(
(tooltipTriggerElement) => new Tooltip(tooltipTriggerElement, { trigger })
);
}
export default useInitializeTooltips;
However, later on I realized using the code as is causes "ghost" tooltips to persist on re-renders (e.g. when some state has changed) and even on page redirects (using react-router v5). These can only be removed on page reloads. That's why I perform some cleanup on unmount and now the code looks like so:
useEffect(() => {
const initializedTooltipList = [
...document.querySelectorAll(`[data-bs-toggle="tooltip"]`)
].map(
(tooltipTriggerElement) => new Tooltip(tooltipTriggerElement, { trigger })
);
// Dispose all initialized tooltips on component unmount
return () => initializedTooltipList.forEach((tooltip) => tooltip.dispose());
});
Now the bugged tooltips are gone but this creates a new problem. I get the following error when a tooltip is still showing and a re-render happens:
tooltip.js:371 Uncaught TypeError: Cannot read properties of null (reading 'template')
at Tooltip.getTipElement (tooltip.js:371)
at Tooltip._cleanTipClass (tooltip.js:705)
at complete (tooltip.js:323)
at execute (index.js:251)
at HTMLDivElement.handler (index.js:273)
at triggerTransitionEnd (index.js:100)
at index.js:279
Actual error stacktrace screenshot
This has been bugging me for a while now so I've looked around but found nothing on my particular circumstance. I did find this one and also this that says to provide a 'manual' trigger option on init. However, from what I understand, in my app I am not manually triggering it myself, but manually disposing. Either way, I want to avoid manually triggering it if possible. I would also like to avoid using the react-bootstrap component library if I can.
What's more, most articles I've found are using JQuery which I know next to nothing about. I've also tried digging into the bootstrap code itself but the only clue I found seems to be pointing to the fact that this._config
, which I assume is the internal config it uses for init, somehow becomes null
at some point in the component lifecycle. I wonder if I'm doing this the right way.
Link for a codesandbox with details on how to reproduce the error here.
I am still quite new to web development and have been developing for just a little over 3 months, so if there is some points that need clarification or my understanding was fundamentally wrong, please feel free to point it out!