Using React Suspense to Freeze DOM Updates (But It Hides Everything)
I was trying to stop a component from updating while it exits. I just wanted to freeze it. I wanted to let the animation run. That’s all I wanted.
I tried some hacky solutions like: saving state first, rendering from some snapshot, experimenting with timers. And it felt messy.
There were states everywhere, messed up with andom flags and things leaking out between renders. I didn’t like it.
So I went looking for a way to pause rendering. I couldn’t find one. At least nothing obvious.
I tried the usual things: delayed state updates, stored values in refs, rendered from cached props. It kind of worked. But not really. Something always slipped through. A re-render here and a tiny change there.
And I kept thinking React must have a switch for this.
Like, some hidden “pause DOM” thing.
The Solution That I Felt Weird About At First
Suspense pauses commits, right?
That’s what happens when something suspends. React keeps doing its thing internally, but it doesn’t push changes to the DOM. UI just sits there. Frozen. (Well, mostly.)
But it also hides the subtree. display: none !important.
So yeah. It’s not so great for exit animations.
But then I wondered, if it freezes updates and only hides stuff with a style, could I just undo that? I was not sure about it. To me it felt like I needed to look into React internals deeper. I wasn’t sure why I even tried it.
What Actually Worked
I was surprised to learn that Suspense already does most of what I wanted. It stops DOM commits for that subtree. Visible UI stays exactly how it was.
Well. Not exactly. It freezes it and hides it.
So I wrapped Suspense and kept a close eye on the child DOM nodes. Then I cleared the display: none in an insertion effect while it’s suspended.
So I tried useInsertionEffect. This hook runs right after insertion just before layout and before paint. Basically the earliest React hook that lets you access the DOM.
React still thinks the subtree is hidden and I just remove the style. And the tree stays visible.
Now the element stays visible while the exit animation runs. It doesn’t move. It literally just stays there.
Weirdly satisfying.
Suspension comes from a component calling React.use() on an unresolved promise (which feels slightly ridiculous, honestly). But it works.
I tested it out in React 18 and 19.2. To me it seems fine but probably fragile and definitely a hack.
Also it depends on how Suspense handles styles right now. That could change in future. I don’t really know if this is stable or just luck.
How I Think About Suspense Now
I always thought Suspense was loading UI.
But it’s also kind of a DOM pause switch. If you’re willing to fight the hiding part.
So yeah. I reach for it differently now.