Different Patterns in Communicating Between Web Components

Four (4) Patterns in Which Web Components can Communicate With Each Other

Building modern web applications requires developers to think about functionality and reusability. Ideally, the best practice for engineering web components is to remain self-contained and loosely coupled with the rest. However, following such implementations generally create “isolated” components, which rely on the consumer to provide the context for its usage.

For example, a Button component might rely on its consumer to define its behavior for a click, as shown below.

<Button onClick={() => {alert('clicked');}}>
Click me
</Button>

As you can see, these components must communicate with others to provide their desired functionality. Hence, this article will provide an in-depth walkthrough of implementation patterns developers can use to communicate between web components.

Web Component Communication Patterns

1. Parent-to-Child Communication

In component-based development, numerous components work together to create a single function. In such situations, you’d need to ensure these components can communicate.

Most times, you’d have a single parent component and place several components — child components that require data from the parent to work. For example, consider the diagram shown below.

Figure — Parent-to-Child Communication

The figure depicted above highlights two components — BookList and Book. The Book component would be implemented as an “isolated” component where it needs a context provided by the BookList to construct its output. For example, the Book component might include the following:

  1. A title
  2. An outline
  3. An author
  4. A published date.

These parameters need to be communicated to the Book component from the BookList. Hence, one pattern to implement this form of communication is using component properties.

The Book component will receive a list of properties from BookList that helps construct a fully functional Book component. An implementation of this using React is shown below.

import React from "react";
import Book from "./Book";

const BookList = (props) => {
return (
<div>
{props.books.map((book) => {
return (
<Book
 key={book.id}

// pass in the props to help communicate with the book component

title={book.title}

author={book.author}

pages={book.pages}

outline={book.outline}
/>
);
})}
</div>
);
};

The snippet shown above utilizes the principle of component properties to provide information about the Book component to help deliver its concrete implementation.

2. Event-Based Communication

Secondly, you may want your child components to communicate with your parent component. For example, your Book component would have an action, onDelete(), responsible for executing a delete operation. However, the implementation of the delete action could vary depending on the context.

For instance, you can directly delete it at a specific location or display a confirmation dialog in another place. Hence, these functionalities need to be provided within their context. Therefore, this information must have a way of being communicated to the child component. In such cases, you will need to implement child-to-parent communication, as shown below.

Figure — Child-to-Parent Communication

The figure above illustrates the Book component talking to the BookList component and informing it regarding a delete action. Such child-to-parent communication can be implemented with a pattern known as event-based communication.

In a nutshell, event-based communication is when a child component emits an event understood by the parent component, executing an action for that particular event. So, for example, the Book component could emit an event called – onDelete that the parent component will listen to. And when an onDelete event is received by the parent, it will execute an action (delete the book).

Such event-based communication can be implemented across all front-end frameworks. The example shown below highlights an event-driven architecture in React.

// implementation of Book - Child

const Book = (props) => {
// will receive an onDelete function as a prop to handle delete event
return (
<div><button onClick={() => props.onDelete(props.id)}>Delete</button></div>
);
};

// implementation of BookList - Parent

const BookList = (props) => {
const handleOnDelete = (id) => {
// TODO: delete the book with the given id
};
return (
<div>
{props.books.map((book) => {
return <Book

key={book.id}

// handle the delete event in the parent

onDelete={handleOnDelete}

/>;
})}
</div>
);
};

The snippet above highlights the implementation of the following:

  1. Book component: A child component that accepts an event handler (the implementation provided by the parent component to handle all deleted events emitted by the child component). The provided implementation is invoked when the button is clicked.
  2. BookList component: Each iterated Book receives an event handler – handleOnDelete to manage the delete event emitted by the Book component.

3. Sibling-Based Communication

You may often want components within the same level to communicate with each other. For example, consider the component tree shown below.

Figure — Sibling Communication

The figure above depicts two components within the same level — Header and Footer communicating with each other to exchange data.

For example, you might need this sort of implementation when your header component needs to update a list of quick links that need to be accessible in the footer when the route changes.

For example, if the user clicks “Home” in the Header, you might want your Footer to display quick actions such as Login and Sign Up.

Its implementation differs based on the framework. However, some standard techniques for adopting sibling-based communication are to use either:

  1. Global state management system: Redux or NGRX
  2. Context — React specific (React Context API)
  3. The observer pattern — Observables, Effects, Redux.

You could:

  1. Define a global store (service) that holds the events for route change & footer data.
  2. Expose a method to handle a route change event.
  3. Maintain a subscription in the Footer component to react to changes in the footer data.

By following the three steps discussed above, you ensure that your components communicate within the same level.

Note: Ensure you clear any subscriptions when you unmount a component from the DOM to avoid memory leaks.

4. Event Bubbling

Event bubbling is a DOM concept that has been around for quite a while. It, too, is a way that child components can use to communicate with their parents.

Its fundamental working is that a top-level component, the parent component captures events that originate from its child components. Its implementation is shown below.

import React from "react";

const EventBubbling = () => {
const [count, setCount] = React.useState(0);

const handleClick = () => {
setCount(count + 1);
};
return (
<div onClick={handleClick}><p>Clicks: {count}</p><Child/></div>
);
};

The snippet above implements event bubbling through a single onClick handler in the div. This onClick handler will catch all the onClick events emitted across all the child components within the div.

Concluding Thoughts

It’s essential to ensure that web components are built to be reusable while exposing means of communication for them to provide their desired functionality.

This is exactly the approach Bit enables. By adopting a composable, modularity-first design for your components, and independently storing, testing, and documenting atomic units of your codebase instead of entire apps at once, your app scales better, and is infinitely more maintainable. Learn more from Bit’s documentation.

Learn more about extracting and reusing components here:

Extracting and Reusing Pre-existing Components using bit add

The four patterns presented in this article give developers an insight into how web components can improve communication between each other and act as a foundation for effective component development.

I hope that you have found this article helpful.

Thank you for reading.

Build Apps with reusable components, just like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo

Learn more:


Different Patterns in Communicating Between Web Components was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Lakindu Hewawasam

Four (4) Patterns in Which Web Components can Communicate With Each Other

Building modern web applications requires developers to think about functionality and reusability. Ideally, the best practice for engineering web components is to remain self-contained and loosely coupled with the rest. However, following such implementations generally create “isolated” components, which rely on the consumer to provide the context for its usage.

For example, a Button component might rely on its consumer to define its behavior for a click, as shown below.

<Button onClick={() => {alert('clicked');}}>
Click me
</Button>

As you can see, these components must communicate with others to provide their desired functionality. Hence, this article will provide an in-depth walkthrough of implementation patterns developers can use to communicate between web components.

Web Component Communication Patterns

1. Parent-to-Child Communication

In component-based development, numerous components work together to create a single function. In such situations, you’d need to ensure these components can communicate.

Most times, you’d have a single parent component and place several components — child components that require data from the parent to work. For example, consider the diagram shown below.

Figure — Parent-to-Child Communication

The figure depicted above highlights two components — BookList and Book. The Book component would be implemented as an "isolated" component where it needs a context provided by the BookList to construct its output. For example, the Book component might include the following:

  1. A title
  2. An outline
  3. An author
  4. A published date.

These parameters need to be communicated to the Book component from the BookList. Hence, one pattern to implement this form of communication is using component properties.

The Book component will receive a list of properties from BookList that helps construct a fully functional Book component. An implementation of this using React is shown below.

import React from "react";
import Book from "./Book";

const BookList = (props) => {
return (
<div>
{props.books.map((book) => {
return (
<Book
 key={book.id}

// pass in the props to help communicate with the book component

title={book.title}

author={book.author}

pages={book.pages}

outline={book.outline}
/>
);
})}
</div>
);
};

The snippet shown above utilizes the principle of component properties to provide information about the Book component to help deliver its concrete implementation.

2. Event-Based Communication

Secondly, you may want your child components to communicate with your parent component. For example, your Book component would have an action, onDelete(), responsible for executing a delete operation. However, the implementation of the delete action could vary depending on the context.

For instance, you can directly delete it at a specific location or display a confirmation dialog in another place. Hence, these functionalities need to be provided within their context. Therefore, this information must have a way of being communicated to the child component. In such cases, you will need to implement child-to-parent communication, as shown below.

Figure — Child-to-Parent Communication

The figure above illustrates the Book component talking to the BookList component and informing it regarding a delete action. Such child-to-parent communication can be implemented with a pattern known as event-based communication.

In a nutshell, event-based communication is when a child component emits an event understood by the parent component, executing an action for that particular event. So, for example, the Book component could emit an event called - onDelete that the parent component will listen to. And when an onDelete event is received by the parent, it will execute an action (delete the book).

Such event-based communication can be implemented across all front-end frameworks. The example shown below highlights an event-driven architecture in React.

// implementation of Book - Child

const Book = (props) => {
// will receive an onDelete function as a prop to handle delete event
return (
<div><button onClick={() => props.onDelete(props.id)}>Delete</button></div>
);
};

// implementation of BookList - Parent

const BookList = (props) => {
const handleOnDelete = (id) => {
// TODO: delete the book with the given id
};
return (
<div>
{props.books.map((book) => {
return <Book

key={book.id}

// handle the delete event in the parent

onDelete={handleOnDelete}

/>;
})}
</div>
);
};

The snippet above highlights the implementation of the following:

  1. Book component: A child component that accepts an event handler (the implementation provided by the parent component to handle all deleted events emitted by the child component). The provided implementation is invoked when the button is clicked.
  2. BookList component: Each iterated Book receives an event handler - handleOnDelete to manage the delete event emitted by the Book component.

3. Sibling-Based Communication

You may often want components within the same level to communicate with each other. For example, consider the component tree shown below.

Figure — Sibling Communication

The figure above depicts two components within the same level — Header and Footer communicating with each other to exchange data.

For example, you might need this sort of implementation when your header component needs to update a list of quick links that need to be accessible in the footer when the route changes.

For example, if the user clicks “Home” in the Header, you might want your Footer to display quick actions such as Login and Sign Up.

Its implementation differs based on the framework. However, some standard techniques for adopting sibling-based communication are to use either:

  1. Global state management system: Redux or NGRX
  2. Context — React specific (React Context API)
  3. The observer pattern — Observables, Effects, Redux.

You could:

  1. Define a global store (service) that holds the events for route change & footer data.
  2. Expose a method to handle a route change event.
  3. Maintain a subscription in the Footer component to react to changes in the footer data.

By following the three steps discussed above, you ensure that your components communicate within the same level.

Note: Ensure you clear any subscriptions when you unmount a component from the DOM to avoid memory leaks.

4. Event Bubbling

Event bubbling is a DOM concept that has been around for quite a while. It, too, is a way that child components can use to communicate with their parents.

Its fundamental working is that a top-level component, the parent component captures events that originate from its child components. Its implementation is shown below.

import React from "react";

const EventBubbling = () => {
const [count, setCount] = React.useState(0);

const handleClick = () => {
setCount(count + 1);
};
return (
<div onClick={handleClick}><p>Clicks: {count}</p><Child/></div>
);
};

The snippet above implements event bubbling through a single onClick handler in the div. This onClick handler will catch all the onClick events emitted across all the child components within the div.

Concluding Thoughts

It’s essential to ensure that web components are built to be reusable while exposing means of communication for them to provide their desired functionality.

This is exactly the approach Bit enables. By adopting a composable, modularity-first design for your components, and independently storing, testing, and documenting atomic units of your codebase instead of entire apps at once, your app scales better, and is infinitely more maintainable. Learn more from Bit’s documentation.

Learn more about extracting and reusing components here:

Extracting and Reusing Pre-existing Components using bit add

The four patterns presented in this article give developers an insight into how web components can improve communication between each other and act as a foundation for effective component development.

I hope that you have found this article helpful.

Thank you for reading.

Build Apps with reusable components, just like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo

Learn more:


Different Patterns in Communicating Between Web Components was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Lakindu Hewawasam


Print Share Comment Cite Upload Translate Updates
APA

Lakindu Hewawasam | Sciencx (2023-03-15T07:06:45+00:00) Different Patterns in Communicating Between Web Components. Retrieved from https://www.scien.cx/2023/03/15/different-patterns-in-communicating-between-web-components/

MLA
" » Different Patterns in Communicating Between Web Components." Lakindu Hewawasam | Sciencx - Wednesday March 15, 2023, https://www.scien.cx/2023/03/15/different-patterns-in-communicating-between-web-components/
HARVARD
Lakindu Hewawasam | Sciencx Wednesday March 15, 2023 » Different Patterns in Communicating Between Web Components., viewed ,<https://www.scien.cx/2023/03/15/different-patterns-in-communicating-between-web-components/>
VANCOUVER
Lakindu Hewawasam | Sciencx - » Different Patterns in Communicating Between Web Components. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2023/03/15/different-patterns-in-communicating-between-web-components/
CHICAGO
" » Different Patterns in Communicating Between Web Components." Lakindu Hewawasam | Sciencx - Accessed . https://www.scien.cx/2023/03/15/different-patterns-in-communicating-between-web-components/
IEEE
" » Different Patterns in Communicating Between Web Components." Lakindu Hewawasam | Sciencx [Online]. Available: https://www.scien.cx/2023/03/15/different-patterns-in-communicating-between-web-components/. [Accessed: ]
rf:citation
» Different Patterns in Communicating Between Web Components | Lakindu Hewawasam | Sciencx | https://www.scien.cx/2023/03/15/different-patterns-in-communicating-between-web-components/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.