Tired of handling unnecessary rendering in React webpage? RxJS is the savior!

Using React for website development is very common nowadays; however, sometimes developers build projects with complicated code flow and unnecessary snippets or wrong approaches, making web applications slow over time. Today, we will talk about such a topic, which might be helpful to developers to make fluent workflows within an application without making it laggy and choppy.

But first, we need to check a few critical points about Reactjs. One of the main reasons for using react is a property called “One-way data binding”. Its component-based architecture makes use of it as a guiding principle. When one-way data binding is used, Data travels from parent to child components in a single direction. Here’s a little explanation of how it works:

Parent-Child Relationship: In a React application, components are organized hierarchically, with parent components containing child components.

Data Propagation: Data is passed down from parent to child components via props (short for properties). Parent components can set data as props when rendering child components.

Immutable Data: React promotes immutability, meaning that data should not be directly modified within child components. Instead, child components receive data as read-only props.

Reactivity: When data in a parent component changes, React re-renders that component and its child components. This ensures that the UI stays in sync with the underlying data.

Unidirectional Flow: Data flows in a unidirectional manner, meaning that changes in child components do not directly affect their parent components. To update data in a parent component, you typically pass callback functions as props, allowing child components to signal the parent when a change is required.

One-way data binding in React helps maintain a transparent and predictable data flow, which can improve code maintainability and debugging. It also contributes to React’s performance optimizations, allowing the framework to track changes and efficiently minimize unnecessary DOM updates.

Now, coming to the point of react prop drilling, also known as “prop passing” or “prop threading,” refers to the process of passing props (short for properties) through multiple layers of nested components in a React application. This occurs when data needs to be transmitted from a higher-level parent component to a lower-level child component that is not directly connected through a parent-child relationship.

Here’s how prop drilling works

1. Parent Component: You have a parent component with some data or state at the top of the component hierarchy. This component typically fetches or manages the data.

2. Intermediate Components: Between the parent and the target child component, one or more intermediate components may not need the data themselves but are responsible for passing it down. These intermediate components serve as “middlemen” for prop passing.

3. Target Child Component: Finally, you have the child component at the bottom of the hierarchy that needs the data.

export type ProductProps = {
  productDetails: any;
  allProd: any;

const Products = (props: ProductProps) => {
  let count = 0;
  const { productDetails, allProd } = props;
  const [similarProd, setSimilarProd] = useState<any[]>([]);
  const randomIntFromInterval = (min: number, max: number) => {
    return Math.floor(Math.random() * (max - min + 1) + min);
            <link rel="icon" href="../boffocake-logo.png" />
            <meta name="description" content={productDetails?.metaDesc} />
              content="width=device-width, initial-scale=1"
          <Products productDetails={productDetail

The process involves passing the data as props through each intermediate component in the hierarchy until it reaches the target child component. Here are some key considerations related to prop drilling:


Simplicity: Prop drilling is straightforward and doesn’t require additional libraries or complex state management.

Predictability: The data flow from parent to child components is easy to understand.

Minimal Abstraction: You can see exactly how data passes through the components.


Boilerplate Code: Prop drilling can produce verbose code, especially in profoundly nested component structures.

Maintainability: Changes in the component hierarchy may require updates to numerous components, which can be error-prone and time-consuming.

Not Ideal for All Scenarios: Prop drilling may become cumbersome when deeply nested components or components at various levels need the same data.

To mitigate the downsides of prop drilling, you can consider alternative approaches like

1. Context API: Use React’s Context API to create a shared state that can be accessed by any component in the tree, eliminating the need to pass props explicitly.

2. State Management Libraries: Utilise state management libraries like Redux or Mobx to centralize and manage application states, reducing the need for prop drilling.

3. Higher-Order Components (HOCs): Wrap components with HOCs to inject props or behavior without passing props through intermediate components.

In summary, while prop drilling is a fundamental part of React’s data flow, evaluating whether it’s the most efficient approach for your specific application and considering alternative solutions when necessary to maintain code readability and scalability.

Even if there are solutions for the cons of props drilling, one problem still can not be solved, and it’s the main problem for large-scale applications getting slower with time while the codebase gets bigger. That is an unnecessary rendering of parent and intermediate components while the target component is updated. So if you have 5 components between the parent and target components, all of those will render again while the parent updates data through props to the target.

Thankfully, there is a remedy for this problem that eliminates this huge issue. RxJS (Reactive Extensions for JavaScript) is a library for reactive programming in JavaScript. It’s based on the principles of the ReactiveX project, which aims to provide a consistent and composable way to work with asynchronous data streams. Here’s a brief overview of RxJS:

1. Observables: At the core of RxJS is the concept of observables, which represent sequences of values over time. Observables can emit data, errors, and completion signals.

2. Operators: RxJS provides a wide range of operators that allow you to transform, filter, combine, and manipulate observables. Operators like `map`, `filter`, `merge`, and `combineLatest` enables you to work with data streams in a declarative and composable manner.

3. Subscription: To start receiving observable data, subscribe to it. Subscriptions can also be unsubscribed to stop receiving data and release resources.

4. Error Handling: RxJS provides mechanisms for handling errors within observables, ensuring that errors in one part of your data stream don’t break the entire pipeline.

5. Hot and Cold Observables: Observables can be categorized as hot or cold. Cold observables emit data when someone subscribes, while hot observables emit data regardless of whether anyone is listening. Understanding this distinction is crucial for managing data streams effectively.

6. Schedulers: RxJS allows you to specify when and where the observable work should be executed using schedulers. This enables fine-grained control over concurrency and timing.

7. Integration: RxJS can be used in various JavaScript environments, including browser-based applications, Node.js applications, and even frameworks like Angular.

8. Async Operations: RxJS excels in handling asynchronous operations such as HTTP requests, user input, and event handling. It helps you manage complex asynchronous code in a more structured and maintainable way.

import { Subject } from "rxjs";

const subject = new Subject();
export type messageParams = {
  source: string;
  action: string;
  params: any;

export const messageService = {
  sendMessage: (sender: string, message: messageParams, target: string) =>
      sender: sender,
      message: message,
      target: target,
  onReceive: () => subject.asObservable(),
else if (m?.sender === "profile-page" && m?.target === "global") {
        if (m?.message?.action === "refresh-profile") {
        } else if (m?.message?.action === "phone-verify") {
        } else if (m?.message?.action === "logout") {

RxJS is widely used in modern web development, particularly in real-time data scenarios, complex user interfaces, and event-driven applications. It promotes a more reactive and functional approach to handling asynchronous data, making it a valuable tool for building robust and responsive applications. However, it does have a learning curve, especially for developers new to reactive programming concepts.

I hope you learned something new and enjoyed it. Let’s share more solutions and build a better community for us; till then, ciao. Happy coding!