Skip to content

Connected state issue with StrictMode #140

Closed

Description

@present-g

Describe the bug
When using useListener (and likely useEmitter) from @hyper-fetch/react inside an app wrapped in React.StrictMode, the connected value returned by the hook stays false forever, even though the WebSocket connection is actually established and messages keep arriving correctly. Connection callbacks registered directly on the Socket instance (socket.onConnected(...)) fire as expected — only the connected state exposed by the hook never updates.

Removing React.StrictMode (no other code changes) makes connected update correctly and immediately once the socket opens.

To Reproduce
Steps to reproduce the behavior:

  1. Wrap the app root in <React.StrictMode>.
  2. In a component, use:
    const { connected } = useListener(someListener);
    
    console.log({ connected });
  3. Point someListener's socket at a real, reachable WebSocket server.
  4. Load the page and watch the console / rendered UI:
    • The server accepts the connection and starts sending messages.
    • socket.onConnected(() => console.log("connected")), registered directly on the Socket instance, logs as expected.
    • connected from useListener never becomes true — it stays false on every subsequent render, even while new messages keep updating other state (e.g. cached data from onEvent).
  5. Remove <React.StrictMode> and repeat step 2–4 with no other changes — connected now correctly becomes true right after the socket opens.

Expected behavior
connected returned by useListener/useEmitter should reflect the real WebSocket connection state regardless of whether the app runs inside React.StrictMode. Since StrictMode is a standard, recommended development wrapper, hooks are expected to keep working correctly under it.

Screenshots
N/A — text/console reproduction. Example console output with StrictMode enabled:

{connected: false}
{connected: false}
[WS] Connected ✓
{connected: false}
{connected: false}
...
{connected: false}   <- never changes, despite data updating normally

Same app without StrictMode:

{connected: false}
[WS] Connected ✓
{connected: true}
{connected: true}
...

Desktop (please complete the following information):

  • OS: macOS 24.6.0 (Darwin)
  • Browser: Chrome / Chromium (also reproduced headless via Playwright)
  • Version: React 19.2.8, react-dom 19.2.8, @hyper-fetch/react 9.0.0, @hyper-fetch/sockets 9.0.0, Vite 8.3.0 (dev mode)

Smartphone (please complete the following information):
N/A — issue is not platform/device-specific.

Additional context

  • The underlying connection is genuinely healthy the whole time — data keeps flowing through onEvent, so this isn't a networking or server-side problem.
  • The bug only reproduces with React.StrictMode enabled; toggling it off (with everything else identical) reliably fixes connected, which points at how the hook tracks connection state across React's development-only double-invoked effects, rather than at the WebSocket/adapter layer itself.
  • This makes connected unreliable for any UI that shows live connection status (e.g. "reconnecting…" indicators, disabling actions while offline) in apps developed with StrictMode on, which is the default in most React templates (including Vite's).

Activity

  1. github-actions commented on Oct 4, 2026

    @github-actions

    🎉 This issue has been resolved in version 9.0.1 🎉

    The release is available on:

    Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions