Pusher logo ← Blog

Pusher with Redux

You might have heard about a wonderful service called Pusher. It is a service which allows you to make live updates without handling infrastructure on your own.

When I wanted to add it into my React-Redux application, I was surprised to find out that there are no libraries which help you. So I decided to write my own. I called it pusher-redux.

I think it turned out to have a very convenient API you can call anywhere from your Redux application. Let me explain how to use it below.

First, you need to configure Pusher in your app.js:

import { configurePusher } from 'pusher-redux';
...
const options = { // options are... optional
  authEndpoint: '/authenticate/me'
}
const store = configureStore(initialState);
configurePusher(store, API_KEY, options);

Then you need to subscribe to it in your component:

import { subscribe, unsubscribe } from 'pusher-redux';
import { NEW_ORDER } from '../pusher/constants';
...
export class MyPage extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.subscribe = this.subscribe.bind(this);
    this.unsubscribe = this.unsubscribe.bind(this);
  }

  componentWillMount() {
    this.subscribe();
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  // upon receiving event 'some_event' for channel 'some_channe' pusher-redux is going to dispatch action NEW_ORDER
  // you can bind multiple actions for the same event and it's gonna dispatch all of them
  subscribe() {
    subscribe('some_channel', 'some_event', NEW_ORDER);
  }

  unsubscribe() {
    unsubscribe('some_channel', 'some_event', NEW_ORDER);
  }
  ...
}

This is how you handle it in your reducer:

import { NEW_ORDER } from '../pusher/constants';
...
function orderReducer(state = initialState.orders, action) {
  case NEW_ORDER:
    return [...state, action.data.order];
  ...
}

pusher-redux dispatches actions of the following format; you can find the data you send in action.data:

return {
	type: actionType,
	channel: channelName,
	event: eventName,
	data: data,
}