You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.
While working on the React Context API, @c4rl0sbr4v0 discovered that with the current implementation, the unmount callbacks (mainly returns of useEffect) won't run when an interactive block is removed from the DOM because a parent interactive block stops showing children. This is normal because they are independent React apps, but can lead to memory leaks and inconsistencies.
I've taken a look at Astro, and it doesn't support this. I couldn't find any reference to this problem in their repository either. I haven't looked into other island-based frameworks.
I've been playing around with this, and the callback of useLayoutEffect runs before the DOM nodes are removed, so maybe we could use that to unmount the children interactive blocks before they are destroyed.
constChildren=({ value, providedContext })=>{constref=useRef(null);useLayoutEffect(()=>()=>{ref.current.querySelectorAll("gutenberg-interactive-block").map((node)=>{// These interactive blocks are about to be destroyed. We can send them a// signal so they can switch to `null` internally and force React to run// their unmount callbacks.constsetIsMounted=isMountedMap.get(node);setIsMounted(false);});},[]);return(<gutenberg-inner-blocksref={ref}suppressHydrationWarning={true}dangerouslySetInnerHTML={{__html: value}}/>);};
The other part is to switch to null if a node receives that signal. We can use a similar approach to the one we used in the React Context.
constInteractiveBlock=()=>{const[isMounted,setIsMounted]=useState(true);useEffect(()=>{// Expose the setIsMounted so it can be accessed by the parent.isMountedMap.set(this,setIsMounted);})returnisMounted ? <Comp.../> : null;
};hydrate(InteractiveBlock,this);
I'm not 100% confident that React will successfully run all the callbacks with this approach, but I don't consider this a priority, especially considering that even Astro doesn't have a solution for this. It'd be great to keep an eye on it, though.
EDIT: Client-side navigations could be another source of external unmounting. There could be more. Maybe the API should be part of the HTML nodes? Something like Bento Component APIs:
Bento:
constaccordion=document.querySelector("#myAccordion");awaitcustomElements.whenDefined("bento-accordion");constapi=awaitaccordion.getApi();// set up button actionsdocument.querySelector("#button1").onclick=()=>{api.toggle();};document.querySelector("#button2").onclick=()=>{api.toggle("section1");};
EDIT 2: I'm not super familiar with the Mutation Observer, but if it can be used to execute code right before a <gutenberg-interactive-block> is about to be removed, it could be a more robust solution.
The text was updated successfully, but these errors were encountered:
While working on the React Context API, @c4rl0sbr4v0 discovered that with the current implementation, the unmount callbacks (mainly returns of
useEffect
) won't run when an interactive block is removed from the DOM because a parent interactive block stops showingchildren
. This is normal because they are independent React apps, but can lead to memory leaks and inconsistencies.I've taken a look at Astro, and it doesn't support this. I couldn't find any reference to this problem in their repository either. I haven't looked into other island-based frameworks.
I've been playing around with this, and the callback of
useLayoutEffect
runs before the DOM nodes are removed, so maybe we could use that to unmount the children interactive blocks before they are destroyed.The other part is to switch to
null
if a node receives that signal. We can use a similar approach to the one we used in the React Context.I'm not 100% confident that React will successfully run all the callbacks with this approach, but I don't consider this a priority, especially considering that even Astro doesn't have a solution for this. It'd be great to keep an eye on it, though.
EDIT: Client-side navigations could be another source of external unmounting. There could be more. Maybe the API should be part of the HTML nodes? Something like Bento Component APIs:
Bento:
Interactive Blocks:
It could be nice 🙂
EDIT 2: I'm not super familiar with the Mutation Observer, but if it can be used to execute code right before a
<gutenberg-interactive-block>
is about to be removed, it could be a more robust solution.The text was updated successfully, but these errors were encountered: