<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mohan Sebastian </title>
    <description>The latest articles on DEV Community by Mohan Sebastian  (@mohsen_khademhoseini_c0d).</description>
    <link>https://dev.to/mohsen_khademhoseini_c0d</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1511527%2Fecdd1216-a382-49f5-980e-c1fb3152de85.jpg</url>
      <title>DEV Community: Mohan Sebastian </title>
      <link>https://dev.to/mohsen_khademhoseini_c0d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mohsen_khademhoseini_c0d"/>
    <language>en</language>
    <item>
      <title>SSR and prefetching - use cache usage in Nextjs</title>
      <dc:creator>Mohan Sebastian </dc:creator>
      <pubDate>Thu, 25 Jun 2026 21:46:38 +0000</pubDate>
      <link>https://dev.to/mohsen_khademhoseini_c0d/ssr-and-pre-fetching-use-cache-usage-in-nextjs-3098</link>
      <guid>https://dev.to/mohsen_khademhoseini_c0d/ssr-and-pre-fetching-use-cache-usage-in-nextjs-3098</guid>
      <description>&lt;p&gt;Before starting this topic, let me clarify something: I’m not going to explain what pre-fetching or SSR is, or try to teach different ways of implementing them in Next.js.&lt;/p&gt;

&lt;p&gt;I just want to share my experience with these features: why we decided to use them, what goals led us to this decision, what downsides they caused for us, and what benefits they gave us in return.&lt;/p&gt;

&lt;p&gt;This is the second part of the series I mentioned before. If you haven't read the previous article yet, you can find it &lt;a href="https://www.linkedin.com/pulse/what-we-did-takhfifan-engineering-built-new-mohsen-khadem-hoseini-qjhlf/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why SSR and Why Next.js?
&lt;/h2&gt;

&lt;p&gt;First of all, as I mentioned in the last article, we didn't choose Next.js or decide to work with SSR just because of common phrases like "we want better performance" or "we want higher Lighthouse scores".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Believe me, you can find many well-engineered CSR applications that outperform SSR applications in these areas.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our main goal was to load our pages as fast as possible. (ideally without depending on skeleton screens or waiting for client-side rendering).&lt;/p&gt;

&lt;p&gt;Also, caching was not only about improving the user experience. It helped us reduce the number of requests hitting our backend services.&lt;/p&gt;

&lt;p&gt;By reducing repeated API calls, we could lower the requests per second going to the server, which is also an important part of keeping the system stable under higher traffic.&lt;br&gt;
We wanted Google to be able to crawl our pages easily, and we had some important pages that didn't require much user interaction (client-side JavaScript events).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example, our home page and the main pages where our products and services were introduced.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;These pages acted more like entry points. They allowed users to start their journey and move into other parts of the application.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So we wanted them to be fast, and the characteristics of our product allowed us to achieve that.&lt;/p&gt;

&lt;p&gt;That was one of the reasons we chose Next.js. It provided us with many tools and built-in features that helped us solve these problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we did it
&lt;/h2&gt;

&lt;p&gt;So we started developing pages with static-generated params:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxiwpvm3ahkp0oy26xm2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxiwpvm3ahkp0oy26xm2t.png" alt=" " width="567" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and SSR components, making API calls on the server:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F485zzwxofcuvf8uxcenh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F485zzwxofcuvf8uxcenh.png" alt=" " width="620" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and then passing the data to a renderer component like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc7jld4bbpyet2rv02nml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc7jld4bbpyet2rv02nml.png" alt=" " width="712" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything is rendered on the server. The &lt;code&gt;SectionRenderer&lt;/code&gt; component itself is also a server-rendered component. This way, we could separate services properly.&lt;/p&gt;

&lt;p&gt;This component is responsible for rendering different components based on each section type, &lt;strong&gt;and each type can render either CSR or SSR components.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One good thing about SSR and pre-fetching in Next.js is that you can achieve the same goal in multiple ways. You just need to choose the right approach based on your product requirements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, the homepage we talked about could also include a section that displays private, user-based data that needs to be fetched on the client side only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We can easily define a placeholder model for this section, push it in the sections list (in what ever index), and render a skeleton inside the fully server-rendered page until the data is ready.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We did exactly this on the homepage to a component which was responsible for showing user wallet data:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy460dmaihu67r4diajvc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy460dmaihu67r4diajvc.png" alt="display skeleton when data is not ready" width="506" height="775"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw9q7jhqmys3fm1z24s32.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw9q7jhqmys3fm1z24s32.png" alt="display component after data is ready" width="506" height="775"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We could also call and fetch multiple APIs on the server. In our case, we needed to call two APIs in some pages: one to get all the sections we needed to render, and another to fetch the data for those sections.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3vjr6vsd1d0zkgb400mv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3vjr6vsd1d0zkgb400mv.png" alt=" " width="645" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and after getting all tabs, we could simply decide to render component, only if their tab is sent at the response:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fznennk0ib0efwzkbuhuo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fznennk0ib0efwzkbuhuo.png" alt=" " width="638" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So as I said, there are many different ways to render components and fetch data in Next.js. &lt;strong&gt;We just need to decide which approach fits our app best.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Downsides of using pre-fetching and caching
&lt;/h2&gt;

&lt;p&gt;Using these methods definitely has their advantages. First of all, if we use them correctly, the app becomes faster, components load instantly, and everyone is happy.&lt;/p&gt;

&lt;p&gt;But wait! not everyone, I assure you :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When we deployed the first demo pages, the QA team was the first group to “yell” at us :)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;They couldn’t easily access the API calls in the Network tab of DevTools, since most of the data was fetched on the server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It was also harder to understand which API response was responsible for a specific issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even identifying which team was responsible for a bug became more complicated &lt;strong&gt;because the API calls were happening on the server&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So for every reported issue, we first had to figure out whether it was caused by the frontend or it was backend bug.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In my opinion, one of the biggest headaches of server-side data fetching is debugging.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And you know what? We didn’t just give the QA team that headache with server-side APIs, &lt;strong&gt;we made it even worse by adding a cache layer and NextJs cache component feature&lt;/strong&gt; to cache the already pre-fetched responses at build time. :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6dkjoxdjkxsknxpnl8f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6dkjoxdjkxsknxpnl8f.png" alt=" " width="646" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With caching components and their related data at build time, you can make the application even faster, and maybe even skeleton-free :)&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But when you do this, debugging also becomes harder, especially when the backend has its own caching layer (which is usually the case). So if some data changes and you're still seeing old data, you can’t easily say “it’s a backend bug” anymore :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With this cache component implementation, we didn’t just make QA unhappy, we also dragged the backend team into the pain :)&lt;/p&gt;

&lt;p&gt;But why did we put ourselves through all this trouble, and was it really worth it?&lt;br&gt;
In our case, I should say, totally! :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We made this decision based on the product situation&lt;/strong&gt; — it wasn’t something we implemented for fun.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the app, there were a considerable number of components whose data was not expected to change frequently.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Caching this type of data results in faster load times and fewer API calls.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But we didn’t want QA or other teams to suffer from this amazing feature. &lt;strong&gt;So we came up with a workaround that allowed other teams to revalidate the cache at runtime&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We built a small utility that rendered an input inside the app, allowing QA to manually revalidate cached data. They could enter the cache tag name (which we provided in a list), and instantly see the updated content.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So in my experience: &lt;strong&gt;don’t go for caching components unless you’re sure your app actually needs it&lt;/strong&gt; — and your product manager explicitly asks for it :)&lt;/p&gt;

&lt;h2&gt;
  
  
  A Few Notes Before Diving Into Server side API call and Cache Components
&lt;/h2&gt;

&lt;p&gt;Based on my experience with this feature, using &lt;code&gt;use cache&lt;/code&gt; can sometimes make things worse, or even hurt both the user and developer experience in certain situations.&lt;/p&gt;

&lt;p&gt;So it’s better to use it with caution, and remember: don’t force it into your app. &lt;strong&gt;Your app can still feel smooth and fast without it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Some things I learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use it only when your app can actually benefit from it.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use it for sections or pages that contain static data, or data that does not change frequently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don’t decide to add caching just because you can. This kind of decision is strongly &lt;strong&gt;tied to product requirements&lt;/strong&gt; and should be made with the product team.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Also, if you decide to use caching, it’s better to have a clear cache-time policy that every page or section follows.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In simpler words: avoid hardcoding cache times everywhere. Instead, define a global cache policy and pass the proper value to your cached components.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftmafg2z01sphmv1nf3pz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftmafg2z01sphmv1nf3pz.png" alt=" " width="628" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This way, you know exactly &lt;strong&gt;how many cached components you have&lt;/strong&gt; and how long each section takes to re-validate.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t use cache components for sections that depend on user interaction or are triggered by user events. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Calling APIs on Server + Cache Components | Usage and Workarounds
&lt;/h2&gt;

&lt;p&gt;As I mentioned before, I recommend avoiding cache components for parts of the app that have user interactions. If you cache these parts, you have to deal with some annoying side effects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But why? And what if you really need caching for those parts?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let me tell you a story about a situation we faced.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On our vendor page, we had two components related to Comments and Questions. The data inside these sections looked like a good candidate for &lt;code&gt;use cache&lt;/code&gt;. They were mostly lists of user comments and questions, and we could re-validate their data from time to time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;But these sections were not just for reading. Users could like comments, write comments, and ask questions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So when we simply cached these sections, things started to get complicated.&lt;/p&gt;

&lt;p&gt;For example, &lt;strong&gt;after liking a comment, the section would update at first glance. But after revisiting the page or refreshing it, everything went back to the cached state that had been generated at build time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This issue was not only related to the like button. New comments, questions, and answers also wouldn’t appear as quickly as users expected.&lt;/p&gt;

&lt;p&gt;Another important issue was related to the nature of these sections.&lt;/p&gt;

&lt;p&gt;You might say: &lt;strong&gt;"Why not keep the cache and just re-validate it after every user interaction?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We actually tried this. But was it really solving the problem?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reading comments or questions was not a private, user-specific action. But commenting, asking questions, and liking something were strongly connected to a specific user.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine a user clicked the Like button. We updated the state and changed the button style to show that this user had liked the comment.&lt;/p&gt;

&lt;p&gt;But after refreshing the page or visiting it again, &lt;strong&gt;even if we had the latest revalidated data and the updated like count, we still couldn't know which exact comment had been liked by this specific user&lt;/strong&gt;, at least until the user identity was available.&lt;/p&gt;

&lt;p&gt;Another problem was that these Comment and Question sections were &lt;strong&gt;shared across different pages of the app&lt;/strong&gt;. Users could interact with them from multiple places, which meant every page needed to display the correct state after user actions.&lt;/p&gt;

&lt;p&gt;You might say: &lt;strong&gt;"Then just wait until the user data arrives on the client and render these sections."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But my question is: &lt;strong&gt;was it really worth adding this much complexity and handling all these side effects just for two components?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our decision was: &lt;strong&gt;hell no.&lt;/strong&gt; :)&lt;/p&gt;

&lt;p&gt;Also, after checking the real impact, we noticed that server-side fetching and caching these sections did not have a significant SEO benefit.&lt;/p&gt;

&lt;p&gt;Since these sections were mostly user-driven and interactive, we decided that forcing them into server rendering was not worth the extra complexity.&lt;/p&gt;

&lt;p&gt;So we changed the approach completely. We moved these sections to &lt;strong&gt;be fetched and rendered on the client side.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple, no unnecessary side effects, and no frontend cache problems.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So when it came to user interaction and user-driven features, in my experience, the best approach was usually not to think about server-side API calls and cache components.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg0natzrf0uqz93sfm26w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg0natzrf0uqz93sfm26w.png" alt=" " width="672" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  But what if you actually need server-side API calls or cache components?
&lt;/h2&gt;

&lt;p&gt;That’s another story.&lt;/p&gt;

&lt;p&gt;Again, on our vendor page, we had a section responsible for displaying coupons. &lt;strong&gt;Each coupon item was interactive&lt;/strong&gt;, and users could add them to their cart.&lt;/p&gt;

&lt;p&gt;For some reason (let’s just say some SEO stuff 😄), we needed to fetch this data on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calling APIs on the server and caching the result at build time could be problematic in this case for the exact reasons we talked about before.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But this time, we did both.&lt;/p&gt;

&lt;p&gt;We &lt;strong&gt;fetched the coupon list on the server&lt;/strong&gt;, &lt;strong&gt;cached it&lt;/strong&gt;, and then passed the data to the client to handle the user interactions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1gf2ed52752tc5iy3qdq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1gf2ed52752tc5iy3qdq.png" alt=" " width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But we knew how important it was to keep this list updated and display the correct coupons.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Our vendors could change anything about their coupons: update the remaining amount, close a coupon for some reason, or modify other details. Caching this kind of data without properly handling updates could become a disaster.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So what are the &lt;strong&gt;workarounds&lt;/strong&gt; for handling these situations?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One simple solution is to call the already server-fetched API again on the client side.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But where exactly should we make this client-side API call?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There are different ways&lt;/strong&gt; to do it, but obviously, you shouldn't place it at the exact same level as the server-side call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My opinion: do it at the level where the update actually affects the user experience.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, in our coupon list, we rendered an "Add" button for each coupon that was available to be added to the cart. So we triggered the client-side API call at that level.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Our client-side API calls were handled with React Query, which also provides caching for API responses. This means that no matter how many coupon items used this hook, the API request would only be made once.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So we called the related hook there and &lt;strong&gt;compared the client-fetched data with the data we received from the server&lt;/strong&gt;. If anything had changed, we could &lt;strong&gt;update the UI accordingly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1toan0ew8cn3gf7en3gc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1toan0ew8cn3gf7en3gc.png" alt=" " width="799" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then, if &lt;code&gt;isInFreshList&lt;/code&gt; was false, we could either unmount the Add button completely or simply hide it to avoid unnecessary layout recalculations&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4zam2q9426ynkcqyrgw6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4zam2q9426ynkcqyrgw6.png" alt=" " width="352" height="77"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is another workaround, this one is related to loading and using Suspense when working with server-side API calls and pre-fetching.&lt;/p&gt;

&lt;p&gt;This workaround was actually from one of our talented colleague.&lt;/p&gt;

&lt;p&gt;When working with &lt;strong&gt;server-side APIs&lt;/strong&gt;, we should always consider wrapping components that need to wait for data with &lt;code&gt;Suspense&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This way, we don’t pause the rendering of the whole page just because one or two components.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb49u2b41xv3c6cr22m3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb49u2b41xv3c6cr22m3s.png" alt=" " width="408" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The thing is, the fallback doesn’t always need to be a placeholder or a skeleton. We could actually use the pre-fetched data we already had from build time and pass that component as the fallback of the Suspense boundary.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then the main component, which is responsible for fetching the fresh data, &lt;strong&gt;could load in the background&lt;/strong&gt; and &lt;strong&gt;replace the fallback&lt;/strong&gt; once the latest data was ready.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F02392f5guka00m8t04bb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F02392f5guka00m8t04bb.png" alt=" " width="478" height="122"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can use this method, especially when you have to deal with query params on your page.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can’t pre-fetch every possible combination of params, but you can pre-fetch the main API and use its result as a placeholder until the client-side API call is completed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Of course, users might see previous data for a second, and from your perspective, &lt;strong&gt;it might look like a bug&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But in my opinion, using this workaround for sections that are not critical can actually be a very clever hack!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So in this article, I shared my experiences &lt;strong&gt;working with SSR and cache components.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the next article, I will talk about our client-side caching system, how we used React Query, how we handled serving pages from CDN, and the challenges we faced along the way.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>ssr</category>
      <category>prefetch</category>
    </item>
    <item>
      <title>Navigation State | components communication in React - final part</title>
      <dc:creator>Mohan Sebastian </dc:creator>
      <pubDate>Fri, 27 Jun 2025 11:02:27 +0000</pubDate>
      <link>https://dev.to/mohsen_khademhoseini_c0d/navigation-state-components-communication-in-react-final-part-3n8j</link>
      <guid>https://dev.to/mohsen_khademhoseini_c0d/navigation-state-components-communication-in-react-final-part-3n8j</guid>
      <description>&lt;p&gt;This is the final part of my exploration into state management and data structures.&lt;br&gt;
In the &lt;a href="https://dev.to/mohsen_khademhoseini_c0d/eventtarget-customevent-components-communication-in-react-part-three-1hg0"&gt;previous&lt;/a&gt; section, we discussed the &lt;strong&gt;CustomEvent&lt;/strong&gt; and &lt;strong&gt;EventTarget&lt;/strong&gt; APIs, and how they can be used to build a &lt;strong&gt;Pub-Sub-like&lt;/strong&gt; communication system between components.&lt;/p&gt;

&lt;p&gt;In this part, I want to introduce another native method for transferring data — one of React's built-in features within its routing system (react-router) that can greatly simplify our work. But before that, it's important to understand that React Router works closely with the &lt;strong&gt;browser's History&lt;/strong&gt; API. So whenever we use hooks like &lt;strong&gt;useNavigate&lt;/strong&gt; or &lt;strong&gt;useLocation&lt;/strong&gt;, we're actually interacting with native browser functionality under the hood.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relationship between react-router and the History stack
&lt;/h2&gt;

&lt;p&gt;Obviously react-router use &lt;code&gt;winow.history&lt;/code&gt; to manage navigation and state transitions.&lt;/p&gt;

&lt;p&gt;The History Stack is part of the browser’s navigation system and it allows pages to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push new entries (pushState)&lt;/li&gt;
&lt;li&gt;Replace the current entry (replaceState)&lt;/li&gt;
&lt;li&gt;Navigate backward and forward&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when we’re using method like navigate(“/some-url”), its internally doing:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2k6dcsfif8yqt1ek8c3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2k6dcsfif8yqt1ek8c3.png" alt="window.history" width="798" height="112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another navigation API available in the browser is &lt;strong&gt;window.location.href&lt;/strong&gt;. We can reassign this property to navigate to a different URL. However, React Router and most SPA frameworks rely on the pushState and replaceState methods instead — and here’s why:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pushState:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Doesn’t reload the page&lt;/li&gt;
&lt;li&gt;Adds a new entry to the browser’s history stack&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Allows passing state as a payload to the next page&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Ideal for SPAs&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;In contrast, window.location.href behaves like a traditional link. It performs a full page reload and is commonly used for navigating to external domains or outside the current application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now you can see how data transfer works in React Router.&lt;br&gt;
As mentioned earlier, the pushState and replaceState methods allow us to &lt;strong&gt;pass data as a payload&lt;/strong&gt; when navigating between pages in a single-page application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgafnw9d7ub86eyq3hbuw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgafnw9d7ub86eyq3hbuw.png" alt="passing payload" width="796" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don’t worry about the second argument — it’s the title property, but most browsers ignore it. It was originally intended to set the page title shown in the browser history. (modern browsers rarely support or use it.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now let's use this inside React using &lt;strong&gt;useNavigate&lt;/strong&gt; and &lt;strong&gt;useLocation&lt;/strong&gt;. Imagine we want to send some data from the Home page to another page named Article&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc32jnlofgu1u9xmvg6xf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc32jnlofgu1u9xmvg6xf.png" alt="use navigation state" width="797" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First we import useNavigate hook from &lt;strong&gt;react-router-dom&lt;/strong&gt; and then call it with a string as url and &lt;strong&gt;an object with a state prop&lt;/strong&gt; as payload.&lt;/p&gt;

&lt;p&gt;Now inside the Article page:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsnw3kwo5wd24zv1ijrl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsnw3kwo5wd24zv1ijrl.png" alt="getting the payload" width="768" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We import useLocation from react-router-dom and use the state prop to get our data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Note
&lt;/h2&gt;

&lt;p&gt;As I mentioned, the &lt;strong&gt;useNavigate&lt;/strong&gt; hook preserves data in the history stack. However, we need to remember that this state is not the same as React's internal state created with the useState hook. The navigation state, which we accessed earlier using useLocation, &lt;strong&gt;persists across page reloads&lt;/strong&gt; so remember to remove it after you’re done with it.&lt;br&gt;
We can do this using the &lt;strong&gt;useNavigate&lt;/strong&gt; hook by passing &lt;strong&gt;location.pathname&lt;/strong&gt; as the URL and an &lt;strong&gt;empty object&lt;/strong&gt; as the state payload.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7w1s6nb8ajq7xwx0o4kl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7w1s6nb8ajq7xwx0o4kl.png" alt="deleting the payload" width="426" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The navigation state is a simple and handy way to transfer state between two pages. One of its most important uses is &lt;strong&gt;tracking the user's last visited page&lt;/strong&gt; within the current session. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In our project, I used this method to navigate the user from the Orders page—along with data related to a specific order—to the Shop page, where I used that order data to create a new basket for reordering.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can try it for yourself and reorder something from the site — of course, you need to have a completed order first. :)&lt;br&gt;
&lt;a href="https://www.digikalajet.com/profile/orders" rel="noopener noreferrer"&gt;https://www.digikalajet.com/profile/orders&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Next.js does not support navigation state, so it's not possible to pass a payload directly through router.push or router.replace. Instead, you can use alternatives like query parameters or persist the data in localStorage.&lt;br&gt;
&lt;strong&gt;Next.js uses a file-based routing system and is designed with SSR. Browser-side state like a navigation payload would be lost unless passed via the URL or stored globally (like I said, in a context, Redux, or localStorage).&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mohsen Khademhosseini&lt;br&gt;
&lt;a href="https://github.com/mohsenKh75" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/mohsen-khadem-hoseini-07590b211/" rel="noopener noreferrer"&gt;linkdin&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>EventTarget - CustomEvent | components communication in React - part Three</title>
      <dc:creator>Mohan Sebastian </dc:creator>
      <pubDate>Tue, 06 May 2025 18:11:52 +0000</pubDate>
      <link>https://dev.to/mohsen_khademhoseini_c0d/eventtarget-customevent-components-communication-in-react-part-three-1hg0</link>
      <guid>https://dev.to/mohsen_khademhoseini_c0d/eventtarget-customevent-components-communication-in-react-part-three-1hg0</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/mohsen_khademhoseini_c0d/pub-sub-pattern-components-communication-in-react-1gl9"&gt;first&lt;/a&gt; and &lt;a href="https://dev.to/mohsen_khademhoseini_c0d/observer-pattern-components-communication-in-react-part-two-dh2"&gt;second&lt;/a&gt; parts, we focused on creating two different patterns for handling data flow in React.&lt;br&gt;
In this part—and the one that follows,  we’ll explore how to manage component communication using Web APIs and React’s built-in capabilities. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is EventTarget
&lt;/h2&gt;

&lt;p&gt;EventTarget is the &lt;strong&gt;foundation of the browser’s event system&lt;/strong&gt;.&lt;br&gt;
It’s a built-in interface that enables objects to handle events through methods like &lt;strong&gt;addEventListener&lt;/strong&gt;, &lt;strong&gt;removeEventListener&lt;/strong&gt;, and &lt;strong&gt;dispatchEvent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Many core Web APIs including DOM elements like &lt;code&gt;&amp;lt;button&amp;gt;,&lt;/code&gt; &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, as well as document and window inherit from &lt;strong&gt;EventTarget&lt;/strong&gt;.&lt;br&gt;
That’s exactly why we can do things like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdb29ftij7m4xrln9c566.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdb29ftij7m4xrln9c566.png" alt="addEventListener" width="427" height="102"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Event system works in the browser
&lt;/h2&gt;

&lt;p&gt;When we attach an event handler to a DOM element—like in the picture above—we’re actually &lt;strong&gt;subscribing&lt;/strong&gt; to that element through one of its event channels.&lt;br&gt;
&lt;strong&gt;In this case:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The button is the publisher (or emitter)&lt;/li&gt;
&lt;li&gt;The callback function passed to addEventListener is the subscriber (or listener)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when a user clicks the button, the button emits a 'click' event, and all registered listeners for that event type are notified and executed.&lt;/p&gt;

&lt;p&gt;So with the &lt;strong&gt;EventTarget&lt;/strong&gt; constructor, we can both publish and subscribe to &lt;strong&gt;built-in&lt;/strong&gt; or &lt;strong&gt;custom&lt;/strong&gt; events.&lt;br&gt;
But how do we create different types of events and pass custom data with them?&lt;br&gt;
&lt;strong&gt;That’s where the CustomEvent constructor comes in.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CustomEvent
&lt;/h2&gt;

&lt;p&gt;CustomEvent allows us to define our own event types beyond the built-in types (like “click”,”change”, “keydown”) and include any kind of data through the &lt;strong&gt;detail&lt;/strong&gt; property.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkeqzybt3pnkdkpv509l8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkeqzybt3pnkdkpv509l8.png" alt="create custom event" width="558" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that we able to use any DOM element as the publisher for emitting this event. like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6mdcr7bw77yjflnj838j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6mdcr7bw77yjflnj838j.png" alt="publishing custom event" width="571" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’re using the document as the publisher for our custom event.&lt;/p&gt;

&lt;p&gt;And after this any listener that subscribed to document using &lt;strong&gt;addEventListener&lt;/strong&gt;(“eventName”,....) will be notified.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbk3dejx6iw2quuf41mi8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbk3dejx6iw2quuf41mi8.png" alt="subscribing to custom event" width="571" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Good to Know: What Pattern does the Browser Event System Follow?
&lt;/h2&gt;

&lt;p&gt;The event system in the browser shares similarities with both the Observer and Pub-Sub patterns.&lt;br&gt;
When you attach a listener directly to a DOM element, that element &lt;strong&gt;acts as the subject&lt;/strong&gt;, keeping track of its observers (callback functions). In this context, &lt;strong&gt;we're clearly in the Observer area&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, when you use the EventTarget constructor to create a standalone event system not dependent on a specific DOM element—it behaves more like the &lt;strong&gt;Pub-Sub pattern&lt;/strong&gt;, where publishers and subscribers are &lt;strong&gt;loosely coupled&lt;/strong&gt; and communicate through named events.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The key difference between DOM-events and custom events lies in their level of coupling. Custom events are decoupled, meaning the publisher and subscriber don’t hold direct references to each other but DOM events are tightly coupled because listeners are directly attached to specific elements. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The more decoupled our communication becomes, the closer it aligns with the Pub-Sub pattern. The browser’s event system isn’t a strict implementation of either Pub-Sub or Observer, it draws inspiration from both.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implement Custom Event System in React with EventTarget
&lt;/h2&gt;

&lt;p&gt;This setup is very similar to the Pub-Sub pattern from the first article, but this time we use the browser’s built-in APIs instead of writing everything from scratch.&lt;/p&gt;

&lt;p&gt;First, we define an EventTypes object to list all our event names and their corresponding payloads. This ensures our pub-sub implementation remains fully type-safe:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnbtfnzz5hyb8tjedh2jd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnbtfnzz5hyb8tjedh2jd.png" alt="EventTypes" width="562" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Later, we'll use the keys of EventTypes as event names and their corresponding values as the payloads when calling the emit function.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77xaxbffv9pgf8umk3y0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77xaxbffv9pgf8umk3y0.png" alt="emit function" width="444" height="94"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we create an &lt;strong&gt;EventTarget instance&lt;/strong&gt;. As mentioned earlier, this constructor gives us access to &lt;strong&gt;event-related methods&lt;/strong&gt; like &lt;code&gt;addEventListener&lt;/code&gt; and &lt;code&gt;dispatchEvent&lt;/code&gt; &lt;strong&gt;without needing to attach them to DOM elements&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3r3ua1r5k9g6q0xa6shw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3r3ua1r5k9g6q0xa6shw.png" alt="create eventTarget" width="511" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our next step is creating the emit function which allows us to publish events:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmbyqgq7jmaopvolysk5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmbyqgq7jmaopvolysk5y.png" alt="emit function" width="701" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This method works similarly to the emit function we discussed in the &lt;a href="https://dev.to/mohsen_khademhoseini_c0d/pub-sub-pattern-components-communication-in-react-1gl9"&gt;first&lt;/a&gt; article. It accepts an &lt;strong&gt;eventName&lt;/strong&gt; and a &lt;strong&gt;payload&lt;/strong&gt; as parameters. However, this time we use the &lt;code&gt;CustomEvent&lt;/code&gt; API to create an event instance, passing the eventName and payload as arguments. This event is then dispatched using the &lt;code&gt;dispatchEvent&lt;/code&gt; method of the eventTarget instance, &lt;strong&gt;triggering the event and making it available for listeners&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Finally, we create our subscribe function, which allows us to listen to the emitted events. It takes an eventName and a callback function as parameters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2looi0eokeoik4x4g4lv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2looi0eokeoik4x4g4lv.png" alt="subscribe function" width="754" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We defined a handler that will be executed when the event is dispatched. This function receives the event as an argument, and we pass it to a CustomEvent to access the detail property, which contains the event's data.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you call subscribe, you're essentially telling your application to "listen" for a specific event (with a specific eventName) and provide a callback function that will be called when the event is triggered.&lt;br&gt;
This sets up the handler function, but nothing happens yet. The handler function doesn't execute at this point; it's just registered to listen for events.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The subscribe function returns an &lt;strong&gt;unsubscribe&lt;/strong&gt; function, which will be used later to &lt;strong&gt;remove the listener&lt;/strong&gt; and &lt;strong&gt;prevent memory leak&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you're interested, you can clone this &lt;a href="https://github.com/mohsenKh75/pub-sub-with-eventTarget" rel="noopener noreferrer"&gt;repo&lt;/a&gt; and try out the event system yourself.&lt;/p&gt;

&lt;p&gt;Mohsen KhademHosseini - Mohan&lt;br&gt;
&lt;a href="//www.linkedin.com/in/mohsen-khadem-hoseini-07590b211"&gt;Linkdin&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mohsenKh75" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>customevent</category>
      <category>evnttarget</category>
      <category>pubsub</category>
      <category>react</category>
    </item>
    <item>
      <title>Observer pattern | components communication in React - part two</title>
      <dc:creator>Mohan Sebastian </dc:creator>
      <pubDate>Sat, 26 Apr 2025 16:35:30 +0000</pubDate>
      <link>https://dev.to/mohsen_khademhoseini_c0d/observer-pattern-components-communication-in-react-part-two-dh2</link>
      <guid>https://dev.to/mohsen_khademhoseini_c0d/observer-pattern-components-communication-in-react-part-two-dh2</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/mohsen_khademhoseini_c0d/pub-sub-pattern-components-communication-in-react-1gl9"&gt;first part&lt;/a&gt; of this article, I talked about the Pub-Sub pattern — a simple and effective way to share data &lt;strong&gt;without strictly following React’s unidirectional data flow.&lt;/strong&gt;&lt;br&gt;
In this part, I’ll talk about another system called &lt;strong&gt;the Observer Pattern&lt;/strong&gt;. Like Pub-Sub, it doesn’t follow React’s top-to-bottom hierarchical data flow — but it approaches the problem in a slightly different way.  &lt;/p&gt;

&lt;p&gt;If this is how the Pub-Sub pattern manages data sharing:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gghmwe7laufz3ziv95a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gghmwe7laufz3ziv95a.png" alt="pub-sub pattern" width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Event bus / event channel is where we store the events.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The observer pattern is something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F49ojj2gdev475j4xv4iu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F49ojj2gdev475j4xv4iu.png" alt="observer pattern" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you might have noticed from the pics, there are some key differences between the two patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Pub-Sub, the publisher sends the event to an &lt;strong&gt;event channel&lt;/strong&gt;, and the subscriber listens for a specific event name.&lt;/li&gt;
&lt;li&gt;In the Observer pattern, observers (subscribers) &lt;strong&gt;register directly&lt;/strong&gt; with the subject (publisher) and get notified when its state changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;In the Pub-Sub pattern, the publisher doesn’t know anything about its subscribers, while in the Observer pattern, the subject holds direct references to its observers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  About observer Pattern
&lt;/h2&gt;

&lt;p&gt;The observer pattern is another way to work around React’s top-down data flow.&lt;br&gt;
In this pattern, we’ll talk a lot about two main concepts: &lt;strong&gt;Subject and Observers&lt;/strong&gt;. &lt;br&gt;
You can think of the &lt;strong&gt;Subject as the Publisher&lt;/strong&gt; and the &lt;strong&gt;Observer as the Subscriber&lt;/strong&gt; in the Pub-Sub pattern. (While they’re not exactly the same, this comparison might help you better understand their responsibility.)&lt;br&gt;
In this pattern, we have a main object called the &lt;strong&gt;Subject, which stores and manages a state&lt;/strong&gt;. It also keeps track of a list of other objects, called Observers, which are &lt;strong&gt;notified whenever the state changes&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This pattern is another way to work around React's unidirectional data flow. It allows you to update the state from any component and access the updated state wherever it's needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Enough talking! Let's put it into action and build our Observer utility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we’ll build:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Subject which holds and update the state &lt;/li&gt;
&lt;li&gt;Multiple Observers which can subscribe the state updates &lt;/li&gt;
&lt;li&gt;A custom hook for using this functionality in react&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating a Subject function
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmhajh9gir692qffyopo4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmhajh9gir692qffyopo4.png" alt="creating subject" width="492" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function will be responsible for storing and updating the subject’s state. It receives an initialValue, which will be our first state.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As before in the Pub-sub pattern, we use generics to make this utility flexible and type-safe. It allows us to define what type of data this subject will manage, so we get full TypeScript support when we want to set or read the state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Storing Observers and value
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpshuh1dhqasloptj6rq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpshuh1dhqasloptj6rq.png" alt="storing value and observers" width="491" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next we create a variable called value and assign the initValue to it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The reason we do this is that we want to reassign this value over time. Whenever a new state is introduced, we will update this value variable accordingly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the next line we created another variable to store our observers. As we said, we use observers to listen/subscribe to any state changes. &lt;br&gt;
We might have multiple observers in different pages or components so &lt;strong&gt;a new Set is a suitable approach&lt;/strong&gt; for &lt;strong&gt;storing&lt;/strong&gt; this type of data. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using the Set constructor ensures that a function can't be registered multiple times. It also offers faster operations for adding, removing, and checking items _O(1) _ compared to an array.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Creating a subscriber function
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxy37i0udfsa27os9g04n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxy37i0udfsa27os9g04n.png" alt="creating subscriber function" width="581" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function takes an observer as its argument, adds it to the list of observers for future updates, and immediately invokes the observer with the current value (which at first was initially set when createSubject was called). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;At the last lines, we return a callback to clean up the subscribed observer from the observers list.&lt;br&gt;
The reason for this is exactly like what we did in our Pub-sub implementation: to avoid memory leaks and prevent multiple updates caused by repeatedly mounting and unmounting components.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Updating state
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkatk8x7xiixneqgqwj3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkatk8x7xiixneqgqwj3r.png" alt="updating state" width="522" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We created a function called next. This function receives a new value, replaces the old one, and then updates each observer by calling them with the new value. This way, all observers are notified of the latest update.&lt;/p&gt;

&lt;p&gt;Both subscribe and next functions call observers, but they serve different responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;subscribe&lt;/strong&gt; is responsible for the initial setup. It registers observers when they want to start listening to the subject. It’s called once, and immediately notifies the observer with the current state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;next&lt;/strong&gt; updates the internal value with a new state and then notifies all registered observers about this change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;So in short:&lt;br&gt;
subscribe registers and notifies about the current state,&lt;br&gt;
next updates the state and notifies about the new state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Getting the Value
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpn9vy3t0sktw3be0yn0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpn9vy3t0sktw3be0yn0.png" alt="get function" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the final step, we create a simple function called get, which returns the current value. We'll use this function to access the latest value at any time, especially when we need to read it or update it with a new one.&lt;br&gt;
Finally we expose these three functions for external use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subscribing to the Observer: Creating the Custom Hook
&lt;/h2&gt;

&lt;p&gt;This custom hook lets us subscribe to a subject and automatically triggers a re-render whenever the subject’s value changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffepxa2urwojl7tfswssq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffepxa2urwojl7tfswssq.png" alt="useObserver hook" width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This hook receives the subject as an argument. It initializes a useState with the subject’s latest value, giving us access to the current state. Then, we use a useEffect hook to subscribe to the subject when the component mounts, this way we ensure the initial value is displayed and updates are tracked. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This Is Where the Magic Happens!&lt;br&gt;
As you might have noticed in the code, we passed our setState function to the subscribe method of our subject. This is a very important step — it's what makes the hook reactive and keeps the component updated.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The setState function is actually acting as our observer. Later on, you'll see how we update the state using the next function, like this:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iy266a901kfqmc448vz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iy266a901kfqmc448vz.png" alt="setting the state" width="578" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, we call next with the current value (retrieved using get) and increment it by one. Here's what happens inside the next function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Futzukb2ud7po4n8f2pm9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Futzukb2ud7po4n8f2pm9.png" alt="next function" width="481" height="99"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This function updates the internal value and then notifies all registered observers by calling them with the new value. Since our observers are actually setState functions, we’re triggering a React state update and that causes a re-render of any component using this hook.&lt;br&gt;
A similar thing happens inside the subscribe function: it receives the setState function as an argument, adds it to the observers set, and invokes it immediately with the current value to sync the initial state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At the end we expose the state (which is our latest updated value) for the external usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Part: Putting everything to use
&lt;/h2&gt;

&lt;p&gt;First, let’s create an instance using our createSubject function. This instance will hold a number and allow us to update it by one. We can create a file called store.ts and add our instances there:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vulene82cnm9amanfkg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vulene82cnm9amanfkg.png" alt="store.ts" width="465" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can use our instance in any page we want. I used it inside my Home page and call it’s next method to update its initial state by one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxvls4zwlglgghf4eflqj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxvls4zwlglgghf4eflqj.png" alt="update state" width="596" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can click this button as much as you like and still access its latest state in any component or page you need. Pretty incredible, right?&lt;br&gt;
Here’s how I subscribed to the count subject in my Counter page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5rdguu3husebqxft9ka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5rdguu3husebqxft9ka.png" alt="subscribing" width="654" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Twist For Those Who Aren't Tired Yet!
&lt;/h2&gt;

&lt;p&gt;The Observer pattern is a widely used system for managing data and communication between different parts of an app. Many methods and &lt;strong&gt;libraries have taken inspiration from this practical approach&lt;/strong&gt;.&lt;br&gt;
The &lt;strong&gt;useEffect&lt;/strong&gt; hook is a great demonstration of how this pattern has inspired core concepts in React.&lt;br&gt;
The core idea of the Observer pattern is subscribing to changes and reacting whenever something happens. &lt;strong&gt;An observer listens to a subject and gets notified whenever the subject’s state changes&lt;/strong&gt;. This concept is quite similar to how React’s useEffect hook works.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In React, the useEffect hook allows components to respond to changes in their environment, such as updates to props or state by running side effects when those changes occur.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, some web APIs like &lt;code&gt;window.addEventListener&lt;/code&gt; are inspired by the Observer pattern.&lt;/p&gt;

&lt;p&gt;If we look more deeply, we can say that state management libraries like Redux have also borrowed some ideas from this pattern.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Redux isn't a pure Observer pattern implementation, but it shares some similarities: we could count the store as the subject, components subscribe or listen to the store via selectors, and we can trigger state changes by dispatching actions. When that happens, all the subscribers get notified and can react accordingly.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Observer Pattern in React: Why It Matters and Where It Fits
&lt;/h2&gt;

&lt;p&gt;As you all know, we have tons of state management libraries for handling component communication. Among them, React’s Context API stands out as a very powerful and straightforward way to manage state and as we said, many of these tools share core ideas with the Observer pattern.&lt;/p&gt;

&lt;p&gt;That raises a very valid question — if we already have these libraries and APIs, &lt;strong&gt;why the hell would we need to implement our own observer logic to manage data flow?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I don’t want to give you a headache by over explaining this, because honestly—the answer is simple: &lt;strong&gt;we don’t need to!&lt;/strong&gt; We’ve got Context, Redux, and plenty of other libraries ready to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  But
&lt;/h2&gt;

&lt;p&gt;Choosing the Observer pattern over these tools &lt;strong&gt;isn’t about simplicity or being lightweight&lt;/strong&gt;. &lt;strong&gt;It’s about the nature of the data we’re trying to share&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If we’re working with data that needs to be accessed across the entire app, we should lift it up—put it in the top-most layer and treat it as a global state. But if we’re just trying to share some data between two pages or non-parent-child components, the Observer pattern can actually be a smart choice.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then if we’ve noticed that &lt;strong&gt;we’re creating too many observers or subscribing all over the place, it’s time to pause and rethink&lt;/strong&gt;. The Observer pattern isn’t a great fit &lt;strong&gt;when data is used widely in the app&lt;/strong&gt;. It can &lt;strong&gt;make state harder to trace and seriously hurt the developer experience&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you're interested, you can check out my &lt;a href="https://github.com/mohsenKh75/react-observer" rel="noopener noreferrer"&gt;repo&lt;/a&gt; and try using the Observer pattern yourself.&lt;br&gt;
Mohsen KhademHosseini - Mohan&lt;/p&gt;

</description>
      <category>observer</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Pub-sub pattern | components communication in React - part 1</title>
      <dc:creator>Mohan Sebastian </dc:creator>
      <pubDate>Thu, 17 Apr 2025 19:42:33 +0000</pubDate>
      <link>https://dev.to/mohsen_khademhoseini_c0d/pub-sub-pattern-components-communication-in-react-1gl9</link>
      <guid>https://dev.to/mohsen_khademhoseini_c0d/pub-sub-pattern-components-communication-in-react-1gl9</guid>
      <description>&lt;p&gt;This article aims to explain React's &lt;strong&gt;unidirectional data flow&lt;/strong&gt; and answer the question: &lt;strong&gt;are there any ways to work around it&lt;/strong&gt;?&lt;br&gt;
And based on this subject, I will take a look at different libraries and methods for sharing data and communication between components.&lt;/p&gt;

&lt;p&gt;But first, &lt;strong&gt;I'd like to explain my understanding of data flow in React.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As I said, React has a one-way data flow. This means &lt;strong&gt;the data can only move from top to bottom&lt;/strong&gt; — and by this, I mean whenever you have some data or state that you want to share between multiple components, &lt;strong&gt;&lt;a href="https://react.gg/visualized#managing-state:~:text=Here%E2%80%99s%20the%20rule%20of%20thumb%20%E2%80%93%20whenever%20you%20have%20state" rel="noopener noreferrer"&gt;you should lift that state up&lt;/a&gt;&lt;/strong&gt; to the nearest parent component and then pass it down via props.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For better understanding, we can think of React data management like a river system:&lt;br&gt;
Data starts at a main source (the parent) and flows to branches (the children).&lt;br&gt;
Child components cannot push water back to the main river.&lt;br&gt;
Only one direction is possible unless special mechanisms (like lifting state up) are used. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can say that in a React application, the main source is the Root component, which acts as the entry point for rendering the entire React component tree.&lt;br&gt;
So, if the Root component (which is usually the App.tsx file in our project) is the source of all other components, &lt;strong&gt;this is the best — and only — place to store global states&lt;/strong&gt;.&lt;br&gt;
This is where we use tools like Redux, Context, or other global providers.&lt;/p&gt;

&lt;p&gt;Then, from the Root, we can access the other components or branches of the React application system.&lt;br&gt;
And since &lt;strong&gt;routing needs to be defined at the top level of the app, the Root component is the suitable place for wrapping the React Router&lt;/strong&gt;, allowing the application to handle different pages and navigate between them.&lt;/p&gt;

&lt;p&gt;With this understanding of the React component tree, let's explore some different ways to access and store data in React.&lt;br&gt;
Rather than discussing libraries or methods like Redux or Context (which I assume you’re already familiar with), I will focus on other patterns and systems that we can create to manage data accessibility.(Let’s just say workarounds!)&lt;/p&gt;

&lt;h2&gt;
  
  
  Publish-Subscribe pattern
&lt;/h2&gt;

&lt;p&gt;This pattern is a suitable approach for communication between components / pages &lt;strong&gt;in any hierarchical location&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;create a functionality for emitting or publishing an event:&lt;/strong&gt;&lt;br&gt;
First, we need to create a variable that stores the eventName along with the value of that event. A Map constructor would be a great choice for this responsibility.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40wywstlapk34pbvzo5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40wywstlapk34pbvzo5u.png" alt="eventStores" width="568" height="39"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For enlightenment this is inside the EventTypes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4o2a5v1ym8uc83llvbkp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4o2a5v1ym8uc83llvbkp.png" alt="EventTypes.ts" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This way we have a more strict way for setting event names and values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now let's create an emit function for publishing events:&lt;/strong&gt;&lt;br&gt;
This function receives a key (which must be one of the keys defined in EventTypes) and a value (strictly typed based on the related type in EventTypes).&lt;br&gt;
&lt;strong&gt;The reason for this pattern is to prevent typos and to ensure a better DX.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By using EventTypes as a source of truth, we can't accidentally use a random string as an event name or pass an incorrect value (payload). This way we can work with events very easier across the app.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lufw1mqul8addbqkyft.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lufw1mqul8addbqkyft.png" alt="emit function" width="784" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create another functionality for listening or subscribing to an event:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At this step we create a variable to store the event that we want to listen to by calling the subscription function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxb1szoq0njkubwb1gd4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxb1szoq0njkubwb1gd4f.png" alt="subscribers" width="617" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The subscribers variable also is a Map constructor, it takes an eventName as a key and a callback as a value. This callback function is responsible for accessing the data that we emitted somewhere in the app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now it's time to create a subscription function:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfyph2xr8pwpisnn75y5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfyph2xr8pwpisnn75y5.png" alt="subscribe" width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we said,the subscribe function takes an eventName as a key and a callback, which receives the exact data stored in eventStore for that key as its parameter. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In both emit and subscribe functions, we use TypeScript generics to tell the compiler which event is being used and what type of data it should expect, ensuring everything stays typed and consistent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Let’s explain inside of the function:&lt;/strong&gt;&lt;br&gt;
In the first condition we check if the subscribers store is empty. If it is, we add the eventName as a key and initialize its value by a Set constructor. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We used Set for ensuring that the same callback isn’t added multiple times for the same eventName.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the next line we’re trying to reach the event by passing that key parameter to the subscribers store and then add the callback (second parameter) to it as a value.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;First We initialized a subscriber with a Set constructor. Then we added the receiving callback to it.&lt;br&gt;
Adding the key and its callback to the subscribers store allows us to unsubscribe/clear the event after it's been published.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the last condition, we check if the eventStore already contains a value for the given key. If it does, we immediately call the callback with that value. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Last part - Unsubscribing from the event:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyqaq22tystocq6ynmmt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyqaq22tystocq6ynmmt.png" alt="unsubscribe" width="640" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before explaining the code, let’s talk about &lt;strong&gt;the purpose of unsubscribing&lt;/strong&gt; from an event. &lt;strong&gt;Why should an event be cleared or removed after it has been published?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer is easy and short: &lt;strong&gt;to avoid memory leaks!&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With unsubscribing an event, we’re actually removing the reference to that callback, and this will help garbage collection work properly.&lt;br&gt;
Also, if we don't unsubscribe from an event, the logic might be triggered multiple times when only a single response was expected, which can lead to unexpected behavior in the app.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In our unsubscribe function, we first check if the key exists in the subscribers store. If it does, we simply delete that entry from the store.&lt;/p&gt;

&lt;p&gt;That’s the whole idea behind the pub-sub pattern. Now, let’s see it in action!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Emit method for creating an event
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lyezi5en6t4rpzfq74u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lyezi5en6t4rpzfq74u.png" alt="emitting an event" width="723" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine this is our home page and we want to navigate users to the dashboard page and also inform the page about some data.&lt;br&gt;
When the user clicks on the &lt;code&gt;Button&lt;/code&gt;, the &lt;code&gt;emit&lt;/code&gt; function will be called, an eventName with a payload will be created and stored in the eventsStore. Then we navigate the user to the dashboard page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using subscribe/unsubscribe for listening/clearing an event
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbv8kwiwic2qqi5ndptj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbv8kwiwic2qqi5ndptj.png" alt="listening to an event" width="667" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the Dashboard page, we wrap our &lt;code&gt;subscribe&lt;/code&gt; function inside a &lt;code&gt;useEffect&lt;/code&gt; hook to ensure that everything is properly mounted before the event is received.&lt;br&gt;
We call the &lt;code&gt;subscribe&lt;/code&gt; function with a callback, where the data parameter represents the exact value that was emitted earlier from the Home page using the &lt;code&gt;emit&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;In the cleanup part we use the &lt;code&gt;unsubscribe&lt;/code&gt; method to clear the event after we reach it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The reason that we must call these two methods inside the &lt;code&gt;useEffect&lt;/code&gt; is that we must be sure that the component is fully mounted and its state is ready and accessible. Also if we call &lt;code&gt;subscribe&lt;/code&gt; directly in the component we trigger it after each render and that could cause duplicated responses and &lt;strong&gt;memory issues&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This pattern helps us establish faster communication between components or pages. We can improve it further by &lt;strong&gt;creating a custom hook&lt;/strong&gt; like &lt;code&gt;useEventEmitter&lt;/code&gt;, which handles component mounting internally, so we don’t have to use &lt;code&gt;useEffect&lt;/code&gt; every time we want to listen to an event.&lt;/p&gt;

&lt;p&gt;you can see the eventEmitter.ts in my &lt;a href="https://github.com/mohsenKh75/simple-pub-sub" rel="noopener noreferrer"&gt;github repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, feel free to check out these articles if you're interested in exploring this pattern further:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/moayad523/implementing-a-pub-sub-based-state-management-tool-in-react-3e2l"&gt;Implementing a Pub-Sub Based State Management Tool in React&lt;/a&gt;&lt;br&gt;
&lt;a href="https://blog.octalabs.com/pub-sub-pattern-in-react-96de463b7cf5" rel="noopener noreferrer"&gt;pub-sub pattern in react&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.dhiwise.com/post/leveraging-react-event-emitter-for-component-communication" rel="noopener noreferrer"&gt;Leveraging React Event Emitter for Seamless Component Communication&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;In the next article I will talk about another way of communication between components. *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mohan KhademHosseini&lt;/strong&gt;&lt;br&gt;
&lt;a href="http://www.linkedin.com/in/mohsen-khadem-hoseini-07590b211" rel="noopener noreferrer"&gt;www.linkedin.com/in/mohsen-khadem-hoseini-07590b211&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mohsenKh75" rel="noopener noreferrer"&gt;https://github.com/mohsenKh75&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>react</category>
      <category>pubsub</category>
    </item>
  </channel>
</rss>
