Published:

React Hooks + RxJS - Communicating Between Components with Observable & Subject

Built with React 16.13.1 and RxJS 6.5.5

Other versions available:

This is a quick tutorial to show how you can communicate between components with React Hooks and RxJS. The below example contains a Home component that sends messages to an App component via a message service using RxJS. The app component displays messages it receives as bootstrap alerts at the top of the screen.

While RxJS is typically thought of as being used with Angular projects, it's a completely separate library that can be used with other JavaScript frameworks including React and Vue.

When using RxJS with React Hooks, the way to communicate between components is to use an Observable and a Subject (which is a type of observable), I won't go too much into the details about how observables work here since it's a big subject, but in a nutshell there are two methods that we're interested in: Observable.subscribe() and Subject.next().

Observable.subscribe()

The observable subscribe method is called by React Hooks components to subscribe to messages that are sent to an observable.

Subject.next()

The subject next method is used to send messages to an observable which are then sent to all React Hooks components that are subscribers (a.k.a. observers) of that observable.


React Hooks + RxJS Component Communication Example

This is a simple example showing communication between a React Hooks Home component and a root App component via a message service using RxJS observables.

(See on StackBlitz at https://stackblitz.com/edit/react-hooks-rxjs-communicating-between-components)


RxJS Message Service

With the message service you can subscribe to new messages in any component with the onMessage() method, send messages from any component with the sendMessage(message) method, and clear messages from any component with the clearMessages() method.

Note: The clearMessages() method actually just sends an empty message by calling subject.next() without any arguments, the logic to clear the messages when an empty message is received is in the app component below.

import { Subject } from 'rxjs';

const subject = new Subject();

export const messageService = {
    sendMessage: message => subject.next({ text: message }),
    clearMessages: () => subject.next(),
    onMessage: () => subject.asObservable()
};


React Hooks App Component that Receives Messages

The App component uses the message service to subscribe to new messages and push them into the messages array which is displayed as a list of alert divs in the render method. If an empty message is received then the messages array is cleared which automatically removes the messages from the UI.

import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';

import { messageService } from '../_services';
import { Home } from '../home';

function App() {
    const [messages, setMessages] = useState([]);

    useEffect(() => {
        // subscribe to home component messages
        const subscription = messageService.onMessage().subscribe(message => {
            if (message) {
                // add message to local state if not empty
                setMessages(messages => [...messages, message]);
            } else {
                // clear messages when empty message received
                setMessages([]);
            }
        });

        // return unsubscribe method to execute when component unmounts
        return subscription.unsubscribe;
    }, []);

    return (
        <Router>
            <div className="jumbotron">
                <div className="container text-center">
                    <div className="row">
                        <div className="col-sm-8 offset-sm-2">
                            {messages.map((message, index) =>
                                <div key={index} className="alert alert-success">{message.text}</div>
                            )}
                            <Route exact path="/" component={Home} />
                        </div>
                    </div>
                </div>
            </div>
        </Router>
    );
}

export { App };


React Hooks Home Component that Sends Messages

The Home component uses the message service to send messages to the app component.

import React from 'react';

import { messageService } from '../_services';

function Home() {
    function sendMessage() {
        // send message to subscribers via observable subject
        messageService.sendMessage('Message from Home Page Component to App Component!');
    }

    function clearMessages() {
        // clear messages
        messageService.clearMessages();
    }

    return (
        <div>
            <h2>React Hooks + RxJS Component Communication</h2>
            <button onClick={sendMessage} className="btn btn-primary mr-2">Send Message</button>
            <button onClick={clearMessages} className="btn btn-secondary">Clear Messages</button>                
        </div>
    );
}

export { Home };

 

Subscribe or Follow Me For Updates

Subscribe to my YouTube channel or follow me on Twitter or GitHub to be notified when I post new content.

 


Supported by