Communicate Between Components with Observable Subject in ReactJS

    Aug 17, 2021       by Pankaj Kumar
communicate-between-components-with-observables-and-subject.jpg

While working on web or mobile components, It is one of the common requirements to share data between multiple components. There are few common ways by which data is shared between multiple components in ReactJS application.

  1. Using props
  2. Using Redux
  3. Using Context API

There is one more way by which data can be shared easily between multiple components in the Reactjs application, Which is using rxjs library.

It is assumed that Rxjs is mainly used with Angular projects, But it is not true. Rxjs is totally separate library that can be used with other JavaScript libraries/Frameworks also like ReactJS and Vue.

 

Observable.subscribe()

This method is used by React components to subscribe to messages that are sent to an observable.

 

Subject.next()

This 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.

 

Communicate Between Components with Observable & Subject Example

In the example, We will try to send the data from a child component to parent component and data can be shared with any type of component like parent to child, child to parent or deeply nested components, etc.

Here we will use a message service by which we can subscribe to new messages in any component with the getMessage() method, send messages from any component with the sendMessage(message) method, and also if needed we can clear/delete the data from the variable using clearMessages() method.

 

Message Service

Let's see the code inside the file message.service.ts file. It actually does the real work for data communication. We will import Subject from rxjs library and then create methods to set/get/delete the value from the Subject. 

 

 
import { Subject } from 'rxjs';
 
const subject = new Subject();
 
export const messageService = {
    sendMessage: message => subject.next({ text: message }),
    clearMessages: () => subject.next(),
    getMessage: () => subject.asObservable()
};
 

 

Home Component that Sends the data

In this component, we will mainly set the value of Message which can subscribe to any of the components wherever we need the specific data. 

 

 
import React from 'react';
 
import { messageService } from './_services/message.service';
 
export class Home extends React.Component {
    sendMessage() {
        // send message to subscribers via observable subject
        messageService.sendMessage('Message from Home Component to App Component!');
    }
 
    clearMessages() {
        messageService.clearMessages();
    }
 
    render() {
        return (
            <div>
                <button onClick={this.sendMessage} className="btn btn-primary">Click to Send</button><br/>
                <button style={{marginTop:'10px'}} onClick={this.clearMessages} className="btn btn-secondary">Clear Value</button>                
            </div>
        );
    }
}
 

 

App Component that Receives the data

This component uses the message service to subscribes to the data from the Subject, Push them to the variable and then render it in the JSX part. Let's see the code below

 
import React from 'react';
import { BrowserRouter as RouterRoute } from 'react-router-dom';
 
import { messageService } from './_services/message.service';
import { Home } from './Home';
 
export default 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.messagesmessage] });
            } 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 style={{marginTop:'100px'}}>
                    <div className="text-center">
 
                        <div className="col-sm-8 offset-sm-2">
                            {messages.map((messageindex=>
                                <div key={index} className="alert alert-success">{message.text}</div>
                            )}
                            <Route exact path="/" component={Home} />
                            <h2 style={{textAlign:'center'}}>Component Communication Using Observable Subject</h2>
 
                        </div>
                    </div>
                </div>
            </Router>
        );
    }
}
 

 

Important Note!

While using Subject, When you subscribe to an observable or event in JavaScript, you should always need to unsubscribe at a certain point to release memory in the system. Otherwise, you will have a memory leak.

 

Conclusion

With the help of Observable, Data can be shared with the components with any relation. And I believe it is one of the quickest ways to share the data between Components.

I hope this article helped you to understand How to communicate between Components with Observable & Subject. You can also find other demos/articles here to start working on enterprise-level applications.

Let me know your thoughts over email pankaj.itdeveloper@gmail.com. I would love to hear them and If you like this article, share it with your friends.

Thanks!


WHAT'S NEW

Find other similar Articles here: