React Closures and third party editors

August 13, 2025

The issue:

In our app, we have a comment form which allows users to attach files to their comments. Users are permitted to upload a comment that is just an attachment without text content if they like. The text content in these comment is composed using a Tiptap editor instance.

I hit a bug where clicking the submit button worked perfectly (whether or not the form had text), but pressing enter did nothing when there were only attachments (enter worked fine if text was present). Elsewhere in the form we implemented a special handler for the enter key to allow an "@" mentions dropdown to capture that enter press if a user wants to mention another user without immediately submitting the comment.

The bug:

In React, when you create a function inside a component, that function "remembers" the values that existed when it was created. This is called a closure.

My form had:

  • A submit button that checked the current state before submitting
  • An enter key handler function that was created once and never updated

The button worked because it checked fresh state every time

The keypress failed because it remembered old, empty state

The useRef() fix

When I logged the values, I saw:

  • Current attachments in component: 2 files ✅
  • Attachments seen by Enter key: 0 files ❌

The Enter key was stuck in the past, always seeing the initial empty state.

React has a hook called useRef() that acts like a "always current" box. With this I could pipe my attachments into the handler without worrying about stale data in the closure:

Why This Happens

Think of it like taking a photo vs. looking through a window:

  • Closure = Taking a photo of state when the component mounts (captures that moment forever)
  • useRef() = Looking through a window at present data/state (always shows what's happening now)

Third-party libraries (like my text editor) often create these "photo moments" that get stuck in time.

The Result

Now both the button AND Enter key work perfectly! 🎉

Key takeaway When React state seems "stuck" in callbacks or external libraries, useRef is your friend for getting fresh values.