updated-redux-signalr
TypeScript icon, indicating that this package has built-in type declarations

2.5.1 • Public • Published

Forked from redux-signalr redux middleware for SignalR (ASP.NET Core)

Updated @microsoft/signalr dependency to v7.0.2

Installation

npm install updated-redux-signalr

or

yarn add updated-redux-signalr

Usage

NOTE: Apart of SignalR invoke method, redux-signalr gives you an access to Redux state and dispatch in actions, so you don't need to use redux-thunk and redux-signalr simultaneously as the latter already does the same job.

First, configuration

Build a connection object

const connection = new HubConnectionBuilder()
  .configureLogging(LogLevel.Debug)
  .withUrl('https://0.0.0.0:5001/testHub', {
    skipNegotiation: true,
    transport: HttpTransportType.WebSockets,
  })
  .build();

Register callbacks

In the callbacks you have an access to redux dispatch and getState and signalr invoke methods.

const callbacks = withCallbacks()
  .add('ReceiveMessage', (msg: string) => (dispatch) => {
    dispatch(setText(msg));
  })
  .add('ReceiveRandomNumber', (num: number) => (dispatch, getState, invoke) => {
    const { example } = getState();
    dispatch(setRandomNumber(num));
    invoke('SendMessage', txt + example.text)
  })

Create middleware with the callbcaks and connection object

export const signal = signalMiddleware({
  callbacks,
  connection,
});

Second, apply the configured middleware

import { signal } from './helpers/withSignalR';

export default function configureStore(preloadedState?: RootState) {
  return createStore(
    rootReducer,
    preloadedState,
    applyMiddleware(signal)
  );
}

Third, write action functions as you would do with thunk, but now it has the third parameter - invoke (from signalR) to call server methods

export const sendMessage = (txt: string): Action => (dispatch, getState, invoke) => {
  invoke('SendMessage', txt)
};

Fourth (only for TS), add custom types

import { rootReducer } from './rootReducer';
import { AnyAction } from 'redux';
import { SignalAction, SignalDispatch } from 'redux-signalr';

export type RootState = ReturnType<typeof rootReducer>;

export type Action<ReturnValue = void> = SignalAction<
  ReturnValue,
  RootState,
  AnyAction
>;

export type Dispatch<Action extends AnyAction = AnyAction> = SignalDispatch<
  RootState,
  Action
>;

Use those Dispatch and RootState types in callbacks, this way you will have correct typings for dispatch and getState methods in your callbacks

const callbacks = withCallbacks<Dispatch, RootState>()
  .add('CallbackName', () => (dispatch, getState, invoke) => { }

Additional features

Don't start a connection immediately

Create signalMiddleware with shouldConnectionStartImmediately set to false.

const signal = signalMiddleware({
  callbacks,
  connection,
  shouldConnectionStartImmediately: false
});

Then, import the 'connection' in the place you want and start it if it's not already. Here is an example with a simple Button container:

import { connection } from "../redux/helpers/createSignalMiddleware";

const StartConnectionButton: FunctionComponent = () => {
  const handleClick = useCallback(() => {
    if (connection.state !== HubConnectionState.Connected) {
      connection
        .start()
        .then(() => console.log("Connection started"))
        .catch((err) => console.error(err.toString()));
    }
  }, []);

  return <Button onClick={handleClick}>Start Connection</Button>;
};

export default StartConnectionButton;

Package Sidebar

Install

npm i updated-redux-signalr

Weekly Downloads

16

Version

2.5.1

License

MIT

Unpacked Size

9.44 kB

Total Files

11

Last publish

Collaborators

  • okuruchidan