← Back to list

How to Use SignalR in a React App (Step by Step)

Real-time apps are everywhere: chat apps, live maps, dashboards, stock tickers, and collaborative tools.  If you’re building one in React…

Shehzad Ahmed · 2025-08-23 01:01 · 0 claps · 3.2 min read
#react #signalr #socketio #realtime #chat
Open on Medium ↗
Wiki topics: 🌐 · Web Development 🔒 · Cybersecurity 🎬 · Film & Television 📊 · Economic Policy

How to Use SignalR in a React App (Step by Step)

Real-time apps are everywhere: chat apps, live maps, dashboards, stock tickers, and collaborative tools. If you’re building one in React, SignalR is a great way to get reliable, scalable, real-time communication between client and server.

In this guide, I’ll walk you through setting up SignalR with React from scratch. We’ll build a clean context provider, a custom hook called useListen, and then use it inside a component.

By the end, you’ll have a production-ready pattern for subscribing to server events in your React app.

🚀 What is SignalR?

SignalR is Microsoft’s real-time communication library. It abstracts away WebSockets, Server-Sent Events, and Long Polling into one unified API. On the frontend, you use @microsoft/signalr, and on the backend (ASP.NET Core or anything with hubs), you can push messages to clients.

📦 Step 1: Install the SignalR client

npm i @microsoft/signalr
# or
yarn add @microsoft/signalr

🏗️ Step 2: Create a SignalR Provider and Hook

We’ll build a React context provider that manages the hub connection and a hook called useListen to subscribe to events.

Create src/config/sockets/SignalRContext.js:

import React, { createContext, useContext, useEffect, useRef, useState } from 'react';
import * as signalR from '@microsoft/signalr';

export const SignalRContext = createContext(null);
export const SignalRProvider = ({ children, serverUrl, accessToken, getAccessToken }) => {
  const [hub, setHub] = useState(null);
  useEffect(() => {
    if (!serverUrl) {
      setHub(null);
      return;
    }
    const connection = new signalR.HubConnectionBuilder()
      .withUrl(serverUrl, {
        accessTokenFactory: getAccessToken
          ? () => getAccessToken()
          : () => accessToken || '',
        transport: signalR.HttpTransportType.WebSockets,
      })
      .withAutomaticReconnect([0, 2000, 10000, 30000]) // retry delays
      .configureLogging(signalR.LogLevel.Information)
      .build();
    setHub(connection);
    connection.start().catch((err) => {
      console.warn('SignalR initial start failed:', err);
    });
    return () => {
      connection.stop().catch(() => {});
    };
  }, [serverUrl, accessToken, getAccessToken]);
  return <SignalRContext.Provider value={hub}>{children}</SignalRContext.Provider>;
};
/**
 * useListen(eventName, callback)
 * - Subscribes to hub events
 * - Cleans up on unmount
 * - Keeps callback fresh (avoids stale closures)
 */
export const useListen = (eventName, callback) => {
  const hub = useContext(SignalRContext);
  const cbRef = useRef(callback);
  useEffect(() => {
    cbRef.current = callback;
  }, [callback]);
  useEffect(() => {
    if (!hub || !eventName) return;
    const handler = (...args) => cbRef.current?.(...args);
    hub.on(eventName, handler);
    return () => {
      try {
        hub.off(eventName, handler);
      } catch {
        // ignore cleanup errors
      }
    };
  }, [hub, eventName]);
};

Why this setup?

  • Automatic reconnect → if your connection drops, it retries with backoff.
  • Cleanup on unmount → avoids duplicate event handlers.
  • Fresh callback ref → your latest callback logic always runs without re-registering handlers on every render.

🔌 Step 3: Wrap Your App

In App.jsx, use the SignalRProvider to wrap your app.

Example with Redux:

import React from 'react';
import { useSelector } from 'react-redux';
import AppRouter from './config/routes';
import { SignalRProvider } from './config/sockets/SignalRContext';

const App = () => {
  const conn = useSelector((s) => s.user?.user?.signalRConnectionInfo);
  return (
    <SignalRProvider
      serverUrl={conn?.url}
      accessToken={conn?.accessToken}
    >
      <AppRouter />
    </SignalRProvider>
  );
};
export default App;

Now, all components inside AppRouter can listen to SignalR events.

🎧 Step 4: Listen to Events in Components

Let’s say your server sends live location updates under the event name LiveLocationUpdate.

// LiveMap.jsx
import React, { useCallback } from 'react';
import { useListen } from '@/config/sockets/SignalRContext';
import { SOCKET_SERVER } from '@/config/constants';

export default function LiveMap() {
  const onLocationUpdate = useCallback((payload) => {
    console.log('📍 New location:', payload);
    // update map markers or component state
  }, []);
  useListen(SOCKET_SERVER.LiveLocationUpdate, onLocationUpdate);
  return <div>🗺️ Map UI goes here</div>;
}

When the server pushes a LiveLocationUpdate, your callback runs immediately.

📤 Step 5: (Optional) Sending Data Back

If you want to invoke hub methods from React:

export const useInvoke = (methodName) => {
  const hub = useContext(SignalRContext);
  return async (...args) => {
    if (!hub) return null;
    try {
      return await hub.invoke(methodName, ...args);
    } catch (err) {
      console.warn(`Error invoking ${methodName}:`, err);
      return null;
    }
  };
};

Usage:

const sendMessage = useInvoke('SendMessage');
sendMessage('Hello world!');

🛠️ Troubleshooting

  • CORS issues? → Allow your frontend origin in the server’s CORS policy.
  • No updates on reconnect? → Handlers registered with .on() persist across reconnects automatically.
  • Duplicate events? → Ensure you’re not mounting the same component multiple times.

✅ Final Thoughts

With this setup:

  • SignalRProvider manages the lifecycle of the hub connection.
  • useListen gives you a clean way to subscribe to server events.
  • useInvoke lets you call hub methods from React.

This approach scales well across pages and components — whether you’re building chat apps, dashboards, or live tracking systems.

✍️ That’s it! You now have a production-ready pattern for SignalR in React.

Find me on your favorite platform

  • Github — Follow me on GitHub for further useful code snippets and open source repos.
  • LinkedIn Profile — Connect with me on LinkedIn for further discussions and updates.
  • Twitter (X) — Connect with me on Twitter (X) for useless tech tweets.
  • Instagram — Connect with me on Twitter (X) for useless tech tweets.

메타데이터
post_id
645bd73aad2a
slug
how-to-use-signalr-in-a-react-app-step-by-step-645bd73aad2a
url
https://medium.com/@shaxadd/how-to-use-signalr-in-a-react-app-step-by-step-645bd73aad2a
canonical_url
https://medium.com/@shaxadd/how-to-use-signalr-in-a-react-app-step-by-step-645bd73aad2a
author_url
https://medium.com/@shaxadd
status
ok
fetched_at
2026-06-15 22:55:51