React + RxJS - Communicating Between Components with Observable & Subject
Built with React 16.8.1 and RxJS 6.4.0
Other versions available:
- React: React Hooks + RxJS
- Vue: Vue.js + RxJS
- Angular: Angular 14, 10, 9, 8, 7, 6, 2/5
- ASP.NET Core: Blazor WebAssembly
This is a quick tutorial to show how you can communicate between components in React with RxJS. The tutorial example uses Webpack 4 for compiling + bundling the React components and is styled with bootstrap 4.
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 like React and Vue.
When using RxJS with React, 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 used by React 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 components that are subscribers (a.k.a. observers) of that observable.
React + RxJS Component Communication Tutorial Example
Here's a simple example showing communication between a React home page component and a root app component via a message service using RxJS observables.
The tutorial code is available on GitHub at https://github.com/cornflourblue/react-rxjs-communicating-between-components
(See on StackBlitz at https://stackblitz.com/edit/react-rxjs-communicating-between-components)
Running the React + RxJS Component Communication Example Locally
- Install NodeJS and NPM from https://nodejs.org/en/download/.
- Download or clone the tutorial project code from https://github.com/cornflourblue/react-rxjs-communicating-between-components
- Install all required npm packages by running
npm install
from the command line in the project root folder (where the package.json is located). - Start the application by running
npm start
from the command line in the project root folder.
React + RxJS Message Service
With the message service you can subscribe to new messages in any component with the getMessage()
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(),
getMessage: () => subject.asObservable()
};
React + RxJS App Component that Receives Messages
The React 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 from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { messageService } from '@/_services';
import { HomePage } from '@/HomePage';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
messages: []
};
}
componentDidMount() {
// subscribe to home component messages
this.subscription = messageService.getMessage().subscribe(message => {
if (message) {
// add message to local state if not empty
this.setState({ messages: [...this.state.messages, message] });
} else {
// clear messages when empty message received
this.setState({ messages: [] });
}
});
}
componentWillUnmount() {
// unsubscribe to ensure no memory leaks
this.subscription.unsubscribe();
}
render() {
const { messages } = this.state;
return (
<Router>
<div>
<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={HomePage} />
</div>
</div>
</div>
</div>
</div>
</Router>
);
}
}
export { App };
React + RxJS Home Component that Sends Messages
The React home component uses the message service to send messages to the app component.
import React from 'react';
import { messageService } from '@/_services';
class HomePage extends React.Component {
sendMessage() {
// send message to subscribers via observable subject
messageService.sendMessage('Message from Home Page Component to App Component!');
}
clearMessages() {
// clear messages
messageService.clearMessages();
}
render() {
return (
<div>
<h2>React + RxJS Component Communication</h2>
<button onClick={this.sendMessage} className="btn btn-primary">Send Message</button>
<button onClick={this.clearMessages} className="btn btn-secondary">Clear Messages</button>
</div>
);
}
}
export { HomePage };
Need Some React Help?
Search fiverr for freelance React developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!