<?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>Forem: RAJIB DAS</title>
    <description>The latest articles on Forem by RAJIB DAS (@rajib18197).</description>
    <link>https://forem.com/rajib18197</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1260501%2F788e954d-1cf2-43d5-8aab-251ef7bd641d.jpeg</url>
      <title>Forem: RAJIB DAS</title>
      <link>https://forem.com/rajib18197</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rajib18197"/>
    <language>en</language>
    <item>
      <title>The Elements of Browsers Rendering</title>
      <dc:creator>RAJIB DAS</dc:creator>
      <pubDate>Wed, 04 Feb 2026 13:09:13 +0000</pubDate>
      <link>https://forem.com/rajib18197/the-elements-of-browsers-rendering-547k</link>
      <guid>https://forem.com/rajib18197/the-elements-of-browsers-rendering-547k</guid>
      <description>&lt;p&gt;What web browsers do when a user requests a page is quite a remarkable journey. My goodness, the process behind the curtains reflects such a diligent effort by the folks who work on browsers. So far, I find it very interesting to navigate through the steps that are taken to draw pixels on the screen. I’ll admit it, this is a surprisingly deep and interesting area. As developers, we sustained the focus quite a bit on performance, especially when building things on scale.&lt;/p&gt;

&lt;p&gt;If we want to have a strong hold on the rendering performance metrics of browsers and on improving bottlenecks, I feel we’d better keep on detouring on this route to better off ourselves with the right combination of knowledge, experience, and tooling. Otherwise, taking a long time to load a fully interactive page as well as responding to user interactions can ruin a good user experience. After all, the only thing that matters, and we’ll ever need in software, is the good user experience.&lt;/p&gt;

&lt;p&gt;So what I want to do today is put down some of the insights I’ve learned by writing code, reading articles and watching various conference talks about the absolutely critical, need-to-know bits of page rendering procedures in the web-space. Let’s put in the work.&lt;/p&gt;

&lt;p&gt;It all starts with hitting a request in the address bar. That submission will initiate a DNS lookup if the website is requested for the first time, as some caching might appear to speed things up. DNS lookup returns an actual IP address, which is the location of the server where the requested file is stored. The browser has the IP now. It now establishes a connection to that IP so that they can communicate effectively, which is known as TCP Handshake. But effective isn’t the only goal. It needs to be secured in that no 3rd party entity can read the data that is being exchanged by them. To ensure that another handshake is done, called TLS Negotiation.&lt;/p&gt;

&lt;p&gt;All the back and forth messages are done via HTTP protocol. Once the connection part is done, the browser then sends a get request for the HTML file, and the server starts to send the raw data in batches, as the server has the ability to send the response in chunks, especially for larger responses since that’s the core part of web infrastructure.&lt;/p&gt;

&lt;p&gt;I like the analogy that I found in the MDN docs. It states like this: If we imagine that the internet is a road. At one end of the road is the client, which is like our house. On the other end of the road is the server, which is like a shop we want to buy something from.&lt;/p&gt;

&lt;p&gt;Then the internet connection is basically like the street between our house and the shop. DNS is like looking up the address of the shop before we visit it. TCP is like a car or a bike (or however else we might travel along the road), and HTTP is like the language we use to order our goods.&lt;/p&gt;

&lt;p&gt;Once the handshake and connection are done, the browser starts to assemble them into something meaningful that the user wants to see.&lt;/p&gt;

&lt;p&gt;To achieve that, it has a couple of pipelines to go through to convert the bytes to visual pixels on the screen.&lt;/p&gt;

&lt;p&gt;As soon as the browser gets the first chunk of raw bytes, it needs to build a structure they can work with. And for that, it converts the raw bytes to tokens, which are like vocabularies of a language. From tokens, it generates nodes, which contain all the information necessary about a certain HTML element, and all the nodes are modeled into a tree data structure, which functions as a relationship model between things. This internal representation of the HTML file is known as the DOM tree. It can be manipulated by various DOM methods and properties in JavaScript.&lt;/p&gt;

&lt;p&gt;While parsing the HTML, the parser may find stylesheets, which can’t modify the DOM, so building of the DOM tree process continues along with downloading and parsing CSS to build the CSSOM tree. Parsing the CSS involves resolving conflicting CSS declarations, as CSS can come from different sources, i.e., user agent, author declarations etc.&lt;/p&gt;

&lt;p&gt;The browser needs to build both trees independently because the next step, which is render tree creation, can't be done unless DOM and CSSOM are ready. Had it done only the DOM tree, then we’d have experienced an un-styled page for a moment, and after some time proper rearrangement will get placed because of styling, which would feel broken.&lt;/p&gt;

&lt;p&gt;Speaking of external resources such as images, stylesheets, scripts, and fonts, optimization happens alongside parsing HTML through the preload scanner, which starts downloading the CSS, font, and script files that are high priority. The browser has internal rules of which files get prioritized but we can also control this behavior by  tag.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;link rel="preload" href="very_important.js" as="script"&amp;gt;&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This optimization was invented because back in the old days when a script tag was found, then that would pause the HTML parsing because JS can manipulate the DOM. Instead, that script was first fetched, parsed, and executed before starting to resume the parsing. This way would delay the discovery of other files and bring waterfalls. 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%2Fhlfb5l1jwplausdidklo.jpg" 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%2Fhlfb5l1jwplausdidklo.jpg" alt="Waterfall problems" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To prevent this waterfall, resources are downloaded in parallel so that when the HTML parser finds resources, those might already be in flight or have been downloaded. 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%2Fqeht7opli1eri7nmfe3k.jpg" 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%2Fqeht7opli1eri7nmfe3k.jpg" alt="Preload resources" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JS can also manipulate styles. So before JS execution, all the CSS files have to be downloaded and parsed and the CSSOM must be ready.&lt;/p&gt;

&lt;p&gt;For instance, if we place the script tag in the head and before that script we put a link tag with a stylesheet, then when the HTML parser encounters the script, it stops parsing, but at the same time, JS also can’t be executed if CSSOM is not ready. As we can see, the consequences of delaying building the CSSOM and code structure can drag down both the JS and HTML parsing. That’s why the preload scanner’s main goal is to download the CSS files as quickly as possible so that CSSOM can be available in quick times.&lt;/p&gt;

&lt;p&gt;CSS needs to be downloaded and parsed completely before JS can be parsed and executed. Even though browsers have preload scanners, we should place the script tag at the very end and styles at the top for that reason.&lt;/p&gt;

&lt;p&gt;But nowadays we have better alternatives. If we place the script in the head and don’t want to pause the HTML parsing, we can mark the defer attribute to the script tag, and that will fetch the script in the background and start execution after the HTML has been fully parsed.&lt;/p&gt;

&lt;p&gt;Coming back to the pipelines, since the DOM and CSSOM are ready, the browser starts to traverse the DOM tree, and for each node, it makes sure it has all the information for that element, plus it calculates the computed values from the CSSOM tree, figures out which styles apply to which elements, and forms a render tree. This tree excludes invisible elements like the head tag and its descendants and CSS declaration with display: none.&lt;/p&gt;

&lt;p&gt;Now that the browser has the render tree in place nicely, it starts to traverse the render tree to calculate what dimensions each node should have and exactly where on the screen the node will sit based on couple of factors. Some of these are: device viewport size, CSS box model, CSS layout modes (flex layout mode, grid layout, positioned layout, flow layout etc.). This process is referred to as layout calculation, if this is running for the first time, but on subsequent reruns it’s called reflow.&lt;/p&gt;

&lt;p&gt;So far the browser has the render tree consisting of nodes and has done all the calculations of where they need to be painted. Coming to the actual drawing work, this is where the browser figures out which colors to assign to every visual element in the render tree (“rasterization”) and filling it in.&lt;/p&gt;

&lt;p&gt;To ensure repainting can be done faster, drawing the page split up into distinct layers, sometimes depending on the styles we are using, so that it can re-paint only the part that needs to be changed, and after repainting, the browser then offloads layers to the compositing phase so that it can merge all the layers together into one final image. Similar to design mockups in Figma and others. With this method, the painting process can reuse the work it has done in the previous paint and only change what hadn’t been done previously.&lt;/p&gt;

&lt;p&gt;Styles calculation, layout, and paint phases happen in the main thread in the CPU. The Compositing phase happens on a different thread, which is inside the GPU, where the expensive calculations are done much faster than on the CPU.&lt;/p&gt;

&lt;p&gt;When the browser breaks up the paint process into layers, after the painting process, those layers consist of painted pixels (A.K.A. textures or flat images). Earlier I mentioned depending on the styles browsers create separate layers, and those are transform, opacity, will-change, filters, and a couple more. And if we animate these properties, they don’t trigger layout or paint phases. Instead, they can be animated with compositing alone and a little bit of style re-calculation. Layout and paint phases won't rerun in this case, which reduces the work greatly. Otherwise we would have done those expensive measurements many times a second. Leveraging this leads to a smoother motion.&lt;/p&gt;

&lt;p&gt;Make use of any of these properties treats our element like a single image on a separate layer and then does the texture-based transformation, which is essentially to move, scale, rotate or fade the already painted pixels and then merge that layer with other layers to form a single bitmap, which can be shown on the UI. Since these happen on the GPU, it makes the animation very slick and performant. This is known as hardware acceleration.&lt;/p&gt;

&lt;p&gt;Sometimes it brings one problem though: when the CPU hands it to the GPU to animate the transform property, there's a slight glitch that can appear in text when animating because of a slight difference in the method they use to render things. To remove that, we can use the following CSS:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.btn { will-change: transform; }&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This now will be managed by the GPU all the time, with no handing off. You can try this exercise by yourself. Try creating a button, and then on hover translate it a little bit up or down. You will notice that the text shifts slightly or the characters’ thickness grows or shrinks a bit.&lt;/p&gt;

&lt;p&gt;Compositing can also be very useful with smooth scrolling. For example, in the early days of the web, when user scrolled, the entire page had to be re-painted again which felt laggy and kind of redundant.&lt;/p&gt;

&lt;p&gt;So to skip the paint process, the browser now transforms the page's content up or down when the user scrolls. So by sliding up and down, it speeds up the frame rate in lightning quick time, as it doesn’t have to do many calculations because that has already been done by the paint process. It just stacks up the layers in correct orders, transform them up or down and combine them correctly into a single image.&lt;/p&gt;

&lt;p&gt;Important to remember here is this layering work is done by the GPU instead of the CPU, which improves performance, but it does take up memory, so that’s the tradeoff we need to be aware of.&lt;/p&gt;

&lt;p&gt;Which steps will re-run in the pixel pipeline depends on CSS properties. If an element width is changed from 200px to 300px on hover, then that will trigger the layout phase since an item growing might mean that its siblings move to fill the space. And then the re-paint and compositing. That’s the reason it’s best to avoid changing layout properties like width, height, margin etc., especially when animating, because that’s how we can skip a bunch of operations. Libraries like framer motion achieve animating layout properties with various techniques like FLIP.&lt;/p&gt;

&lt;p&gt;But elements that have been taken out of the normal flow (i.e., absolute), changing width or height don’t affect the other elements. So cases like this, layout calculation, repaint usually happen much faster.&lt;/p&gt;

&lt;p&gt;A quick plug: all the pipeline work that I mentioned (render tree construction, layout, painting, and compositing) is constrained with a tight time of ~16ms to make the UI motion feel fluid and believable. And the steps are blocking and sequential, as we’ve witnessed, done by one thread, which is the main thread. However main thread must also perform other tasks, such as responding to user input and executing JavaScript to keep the UI responsive also. And it is considered a bad and sluggish experience if a response to the user interactions and rendering steps both take greater than ~50ms.&lt;/p&gt;

&lt;p&gt;To maintain optimal performance, it is also important to make sure JS execution doesn’t take that long.&lt;/p&gt;

&lt;p&gt;Like I said earlier, this stuff is really deep. There are obviously many more nuances and intricacies that you can get into at each steps. I'll attach some helpful resources for you to dig even deeper. Not sure if I did a decent job of explaining things. Let me know how that turns out for you. I find it quite hard to keep this all straight in my head. But understanding this helps developers to build a pleasurable experience for the end-users.&lt;/p&gt;

&lt;p&gt;Hopefully this writeup helped to add some light on your understanding and you are eager to learn more about it. Thank you so much for the ride. &lt;br&gt;
You can &lt;a href="https://www.linkedin.com/in/rajuzest/" rel="noopener noreferrer"&gt;connect with me on LinkedIn&lt;/a&gt;. There, I share programming related things just like this one as I learn them.&lt;/p&gt;

&lt;p&gt;Resources:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://medium.com/@addyosmani/how-modern-browsers-work-7e1cc7337fff" rel="noopener noreferrer"&gt;how-modern-browsers-work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hacks.mozilla.org/2017/09/building-the-dom-faster-speculative-parsing-async-defer-and-preload/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;building-the-dom-faster-speculative-parsing-async-defer-and-preload&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;P.S. If you wish to see how many layers a webpage has then browser dev-tool has a "layer tab" in which we can visualize them.&lt;/p&gt;

</description>
      <category>webperf</category>
    </item>
    <item>
      <title>Making Sense of Bipartite Graphs</title>
      <dc:creator>RAJIB DAS</dc:creator>
      <pubDate>Sun, 01 Feb 2026 12:56:15 +0000</pubDate>
      <link>https://forem.com/rajib18197/making-sense-of-bipartite-graphs-5bok</link>
      <guid>https://forem.com/rajib18197/making-sense-of-bipartite-graphs-5bok</guid>
      <description>&lt;p&gt;&lt;strong&gt;Developing strength in the area of graph is a great outlet to sharpen your programming craft&lt;/strong&gt;. It also has ripple effect. You wander with queue, stack, priority queue and what not, while dealing with graph.&lt;/p&gt;

&lt;p&gt;To get a glimpse of it, in today’s issue, I’d like to communicate briefly, the idea of Bipartite Graph and its implementation in a very gentle manner. Let's go.&lt;/p&gt;

&lt;p&gt;The Whole idea with graph is, we make &lt;strong&gt;connections between things&lt;/strong&gt;, which forms a network along its perimeter. A connection sets a bond between two nodes. And &lt;strong&gt;If it is possible for two distinct colors to be exhausted on each edge, then we wind up calling it a Bipartite. You’ve gotta run out of two colors&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%2Fux4zovlhqlyrzq8x3uqy.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%2Fux4zovlhqlyrzq8x3uqy.png" alt="Examples of Bipartite Graphs" width="800" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since the structure of a graph can be as broad as Ocean and simultaneously it can be as high as mountains, we can either traverse broad by exploiting neighbor nodes before descendants or can go deep by striking descendants first.&lt;/p&gt;

&lt;p&gt;These two are the most common techniques to lean into when information is organized like this. First one is BFS (Breadth First Search) and Latter one is DFS (Depth First Search).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let’s lining out what steps the BFS Algorithm takes internally for Bipartite check:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;→ entering the function with a starting node, first thing it does is enqueue the starting node into the queue data structure&lt;/p&gt;

&lt;p&gt;→ gives the starting node a color (0 | 1, model as 2 distinct colors) in the colors[] array&lt;/p&gt;

&lt;p&gt;→ runs a loop until the queue is empty and on each iteration:&lt;br&gt;
1) dequeues a node&lt;br&gt;
2) fires yet another loop to see all of its neighbors and look for 3 things for each neighbors: If the neighbor node is not yet colored, it gives a color opposed to dequeued node’s color and enqueue that afterwards,&lt;br&gt;
else if the neighbor is already colored and its color got blended in with the dequeued node then it is not a bipartite graph, it then terminates the function straight away but if it is having the opposite color then continue.&lt;/p&gt;

&lt;p&gt;→ Finally, the queue becomes empty here, which means, it didn’t fall into the identical color consequences, sure thing, we can safely say the given graph conforms the bipartite rules.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Here’s the BFS implementation in TypeScript:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum COLORS {
  COLORED_RED = 0,
  COLORED_GREEN = 1,
  NOT_COLORED = -1,
}


const checkBipartiteBFS = function (
  startingNode: number,
  adj: number[][],
  colors: COLORS[]
): boolean {

  // define a queue and give starting node a color and enqueue it
  const queue: number[] = [];
  colors[startingNode] = 0;
  queue.push(startingNode);

  // run a loop until queue becomes empty
  while (queue.length !== 0) {
    // dequeues a node
    const node = queue.shift() as number;

    // look for its neighbour nodes and do those checking stuffs and all
    for (let j = 0; j &amp;lt; adj[node].length; j++) {
      const neighbourNode = adj[node][j];

      // both the neighbour and dequeued node are having same color, not a bipartite
      if (colors[neighbourNode] === colors[node]) {
        return false;
      }

      //  neighbour node is not colored,so color and enqueue it in turn         
      if (colors[neighbourNode] === -1) {
        colors[neighbourNode] = (colors[node] + 1) % 2; // 0 becomes 1 and 1 becomes 0
        queue.push(neighbourNode);
      }
    }
  } 

  // queue becomes empty here, it is a bipartite graph surely
  return true;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;A quick Primer on Recursion —&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;since DFS is recursive by nature, thereby, we don’t push a node into the queue every time we discover an un-colored node. Instead we invoke the function again with the un-colored node. That’s it. That’s the only major difference to observe.&lt;/p&gt;

&lt;p&gt;we are repeating the same thing on each iteration if we look closely on BFS. So why not calling the function itself from within itself but with different node, otherwise the pitfall of recursion pops up, business as usual (shoutout to stack overflow).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With that in mind, let’s look at the steps of DFS Algorithm for Bipartite:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;→ entering the function with a node and a color, it starts by giving the node that color in the colors[] array&lt;/p&gt;

&lt;p&gt;→ fires a loop to see all of its neighbors and look for the followings:&lt;br&gt;
If the neighbor node is not yet colored, it calls the DFS function again with the neighbor node and a color opposed to dequeued node’s color. If the call comes back with a “false” value then no need to iterate further, return “false” here as well. Because rules broken by one node in the graph is enough to call it not a bipartite.&lt;br&gt;
else if the neighbor is already colored and its color got blended in with the dequeued node then it is not a bipartite graph, it then terminates the function straight away with return “false” but if it is having the opposite color then continues.&lt;/p&gt;

&lt;p&gt;→ Lastly, the queue becomes empty here, this node didn’t fall into the identical color consequences. So it returns “true” here, which simply means, this node is not the one that break the bipartiteness and exit this execution to go back to where the function came from.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Here’s the DFS implementation in TypeScript:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum COLORS {
  COLORED_RED = 0,
  COLORED_GREEN = 1,
  NOT_COLORED = -1,
}


const checkBipartiteDFS = function (
  node: number,
  color: 0 | 1,
  colors: COLORS[],
  adjList: number[][]
) {
  // give that node a color 
  colors[node] = color;

  // look for its neighbours and do the checking and call the function recursively if needed
  for (const neighbourNode of adjList[node]) {
    // both having the same color, return false right away
    if (colors[neighbourNode] === colors[node]) return false;

    // neighbour node is not yet been colored, so call the function again with the opposite color
    if (
      colors[neighbourNode] === -1 &amp;amp;&amp;amp;
      !checkBipartiteDFS(neighbourNode, color === 0 ? 1 : 0, colors, adjList)
    ) {
      return false;
    }
  }

  // the iteration has been done and this node did not break the bipertiteness, so we return true
  return true;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There you have it. I hope, it was helpful. Thanks so much for reading.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://www.linkedin.com/in/rajuzest/" rel="noopener noreferrer"&gt;connect with me on LinkedIn&lt;/a&gt;. There, I share programming related things just like this one as I learn them.&lt;/p&gt;

</description>
      <category>graph</category>
      <category>bipartitegraph</category>
      <category>datastructures</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Reactive Effects that preserves component's Cohesiveness</title>
      <dc:creator>RAJIB DAS</dc:creator>
      <pubDate>Sat, 01 Nov 2025 08:25:40 +0000</pubDate>
      <link>https://forem.com/rajib18197/reactive-effects-that-preserves-components-cohesiveness-17p6</link>
      <guid>https://forem.com/rajib18197/reactive-effects-that-preserves-components-cohesiveness-17p6</guid>
      <description>&lt;p&gt;It’s not fairly new that when we have bunch of complex data which lives in a database then mainly the essential job of a web application is to act as an interface (a window) to those data that let users read and manipulate. To perform these user centric action we usually need to implement filter, sort, search, pagination etc.&lt;/p&gt;

&lt;p&gt;When working on the implementation, we often need to handle quirky behaviors, for instance: to keep them sync with each other. If a user is on page 3 and then start typing on search input or change the filter, the pagination should adapt, right?&lt;/p&gt;

&lt;p&gt;I can hear you saying, this edge case isn’t a big deal after all the solution is remarkably straightforward. But that’s not the point here. I want to share some perspective change that I’ve had working with it. &lt;/p&gt;

&lt;p&gt;That said, in terms of solution, we can reset the page state on Search Component. Like when setting the new search input value we’ll also set the page state to 0. Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Using a package for managing type safe url query&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQueryState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useURLQueryStates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parseAsString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parseAsInt&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nuqs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SearchInput&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/search-input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;RegistrationRequestsSearchInput&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// use "nuqs" hook to manage the search input state in the url&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSearch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQueryState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;parseAsString&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;shallow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;clearOnDefault&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// only needed to call this hook to reset the page state &lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPagination&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useURLQueryStates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parseAsInt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parseAsInt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;shallow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="nf"&gt;setSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// reset the page state to 1&lt;/span&gt;
      &lt;span class="nf"&gt;setPagination&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SearchInput&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSearch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sure it’s a viable solution and for a long time I used to solve this way. But as my experience with component driven approach becoming more mature I start to realize why it’s better to avoid this pattern. &lt;/p&gt;

&lt;p&gt;Let’s take a moment to analyze this a little bit and see if we can extract a lesson or two from here. &lt;/p&gt;

&lt;p&gt;Setting a new page state leans heavily into Pagination component - that’s why it exist in the first place. Search Component is interfering with it by setting a new value technically works alright it becomes hard to keep track of which code is doing page state manipulations with time and code move slightly towards in the direction of spaghetti.&lt;/p&gt;

&lt;p&gt;Think about the case when we have to do the same inside Filter Component if resetting page state also necessary whenever filter state changes. Wouldn’t it be nice to co-locate setting the page state stuff entirely on the Pagination Component? &lt;/p&gt;

&lt;p&gt;You might be thinking it’s a global state as we set it in a url but that “global” here is in the sense of, we need it in a multiple different corners in our app but we don’t necessarily need to set it from those different components at least in this case I think so. we can reserve the setter function for the Pagination component only. &lt;/p&gt;

&lt;p&gt;So from Pagination component, how do we know when we need to reset state. well use-effect hook could be the great use case for this.&lt;/p&gt;

&lt;p&gt;I applied this reactive solution quite often now a days when building apps in my current job.&lt;/p&gt;

&lt;p&gt;here’s the new lens in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;RegistrationRequestsPagination&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// use "nuqs" hook to manage the pagination state in the url&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPagination&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useURLQueryStates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parseAsInt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parseAsInt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;shallow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSearch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQueryState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;parseAsString&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;shallow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;clearOnDefault&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prevSearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// we can also listen for other changes i.e. filter. The idea is we can add &lt;/span&gt;
      &lt;span class="c1"&gt;// more reactive state in here whenever we need to reset the page state.&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;prevSearch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;prevSearch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;setPagination&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPagination&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Pagination&lt;/span&gt;
      &lt;span class="na"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pagination&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onPagination&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setPagination&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;paginatedMetadata&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;paginatedRegistrationsMetadata&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fvupgpvk7iuu4a54legto.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%2Fvupgpvk7iuu4a54legto.png" alt="Here's a visual diagram to make it more prominent" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what do you think about this? Is this actually outshine the previous one? Essentially this method of Reactive Effects preserves component's Encapsulation. &lt;/p&gt;

&lt;p&gt;We are lean into the idea of cohesive approach (the degree to which elements of a module belong together) and reactive approach something radical that react brought with it when they introduced Component for writing application.&lt;/p&gt;

&lt;p&gt;Reactive in the sense that here, we describe the reset page state with an effect. we are saying when the search input is different then backtrack the page state to 0. Describing it once and for all. we can listen the filter state change also if needed.&lt;/p&gt;

&lt;p&gt;and cohesion in the sense, Pagination component is now the ultimate contract holder for setting page state and that’s what makes sense in this case I guess. &lt;/p&gt;

&lt;p&gt;In the example above, Search Component and Pagination Component is like self independent thing, they only think about them, they act like they do not have the contract of changing other components things. This cohesiveness, this single source of truth makes the application more predictable and more organized.&lt;/p&gt;

&lt;p&gt;This is One of the best things about Component pattern, that they encourage this sort of good habits.&lt;/p&gt;

&lt;p&gt;Thank you so much for taking the time to read it. Feel free to drop your  thoughts about this because I think it's a bit subjective. &lt;/p&gt;

</description>
      <category>architecture</category>
      <category>frontend</category>
      <category>react</category>
    </item>
    <item>
      <title>The “Why” Behind React Suspense: Quest for the Original Vision</title>
      <dc:creator>RAJIB DAS</dc:creator>
      <pubDate>Fri, 03 Oct 2025 14:59:30 +0000</pubDate>
      <link>https://forem.com/rajib18197/quest-about-suspense-41n7</link>
      <guid>https://forem.com/rajib18197/quest-about-suspense-41n7</guid>
      <description>&lt;p&gt;&lt;strong&gt;Discover the why something was originally thought of&lt;/strong&gt; makes us appreciate &lt;strong&gt;the tool + the way we use the tool&lt;/strong&gt; as well as promote us to a couple of levels of &lt;strong&gt;we know what we are doing&lt;/strong&gt;. It’s one of those &lt;strong&gt;inside job&lt;/strong&gt; feeling.&lt;/p&gt;

&lt;p&gt;I continuously invest in this quest, in this lightbulb moment when it comes to learning. Feeding mind with this gives us a right conceptual model of something. That way we can make and move things faster with accuracy. It's no brainer why &lt;strong&gt;right mental models&lt;/strong&gt; are the &lt;strong&gt;ideal interface&lt;/strong&gt; for holding essence of something.&lt;/p&gt;

&lt;p&gt;Recently I’ve been fortunate enough to meet one such moment. It was really an eye-opening realization for me. So this is my attempt to write some words of my understanding. Optimistic you’ll find some values through this. It’s about React Suspense Component. Let’s dive in.&lt;/p&gt;

&lt;p&gt;A very common theme we notice in applications is that they fetches and manipulate data that lives in a database. And there's a whole category of challenges of this and one of them is Data Fetching. How do we fetch Data or more preciously how do we fetch data with component driven framework like react. I deliberately bring component here because that's how most of us build products at least on the Frontend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const res = await fetch("https://www.yourapp.com/users");
const data = await res.json(); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s talk about couple of cases that need to take care of this two lines of code. First noticeable case, between the await and fetch calls for getting data, there’s definitely going to be some delay. So need to handle the loading period. Other case would be what happens when calling doesn’t go well - maybe it’s a 404 or 500. Showing Loading &amp;amp; Showing Error are things we need to be aware of.&lt;/p&gt;

&lt;p&gt;In react, the way we can do that is with use hook. Although It’s a versatile tool but let’s only focus on one thing here, data fetching.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  return (
    &amp;lt;div className="app"&amp;gt;
      &amp;lt;ErrorBoundary fallback={&amp;lt;div&amp;gt;Something went wrong&amp;lt;/div&amp;gt;}&amp;gt;
        &amp;lt;Suspense fallback={&amp;lt;InvestmentSeekingLoading /&amp;gt;}&amp;gt;
          &amp;lt;InvestmentSeekingBox /&amp;gt;
        &amp;lt;/Suspense&amp;gt;
       &amp;lt;/ErrorBoundary&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

const investmentSeekingPromise = getInvestmentSeeking()

function InvestmentSeekingBox() {
  const data = use(investmentSeekingPromise);

  return &amp;lt;div&amp;gt;{/* Stuff using `data` */}&amp;lt;/div&amp;gt;;
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So as we can see from the code, It takes a promise as a parameter. If we call this with a promise then component will stop it’s execution right off the bat and bubble up to a closest Suspense component and showed us the given loading spinners. And when the promise is resolved then react will unmount the loading fallback and start executing the component again but since the promise has been resolved so we don’t have to fall into the halting process again (this is also the reason we're not allowed to create the promise inside components otherwise every time we'll fall into the loading consequences again and again) instead it returns us the actual data this time and as a result showing it on the UI. but If the promise rejects then react will not try to render the component again instead it bubble up even more to find out an Error-Boundary and swap the loading with this.&lt;/p&gt;

&lt;p&gt;Two steps does the job pretty cleanly: &lt;strong&gt;1) wrap the component with Suspense and 2) prompt react to stop processing the rendering until the promise has resolved by throwing promise.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;use hook throws a pending promise that we give. That's how component is able to communicate that it is not ready to render yet. Internally there's some mechanism inside React to catch that promise and suspend the render unless the promise resolves to render the components as this time promise is not pending so we got the actual data to work with.&lt;/p&gt;

&lt;p&gt;After some time digesting this pattern, A question comes into my mind, why we need Suspense and Error-Boundary when dealing with loading and error. Can’t we handle these inside the component itself? &lt;/p&gt;

&lt;p&gt;I mean "the thinking of component model" is, it’s A package, it should own it’s markup, it should own it’s styling, it should own it’s logic and it also should own it’s data fetching. No other components on the other side of the app should be able to meddling with this component. But with Suspense and Error-Boundary it’s not happening (sure data request is happens inside components but not loading and errors). If use hook gives us loading and error variable then it would be completely owned it’s own things component and satisfied the component definition. React did not design the API this way because there’s actually a real problem with this which is known as Layout Shift.&lt;/p&gt;

&lt;p&gt;The way I was introduced to this from a &lt;a href="https://twitter.com/acdlite/status/991503599246098432" rel="noopener noreferrer"&gt;tweet by andrew clark&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Spinners all around. The fact that component has to be highly cohesive, it has to contains and receive everything they need to render the UI is lead us to this problem of things shifted around on the initial load which not offers a good experience for the user. Each Component resolves data at different time, and so the problem arises.&lt;/p&gt;

&lt;p&gt;Here we can see, each components for themselves, doing their own thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function InvestmentSeekingBox() {
  const { isLoading, data, error } = useQuery({
    queryKey: ["InvestmentSeeking"],
    queryFn: getInvestmentSeeking,
  });


  if (isLoading) {
    return &amp;lt;Spinner /&amp;gt;;
  }

  return &amp;lt;div&amp;gt;{/* Stuff using `data` */}&amp;lt;/div&amp;gt;;
}

function InvestmentVerificationBox() {
  const { isLoading, data, error } = useQuery({
    queryKey: ["InvestmentVerification"],
    queryFn: getInvestmentVerification,
  });

  if (isLoading) {
    return &amp;lt;Spinner /&amp;gt;;
  }

  return &amp;lt;div&amp;gt;{/* Stuff using `data` */}&amp;lt;/div&amp;gt;;
}

function Dashboard() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;InvestmentSeekingBox /&amp;gt;
      &amp;lt;InvestmentVerificationBox /&amp;gt;
    &amp;lt;/&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine 5 or 6 components on this Dashboard then components pushing other components will be visible clearly each time they finished their loading because different component finished their loading at different point in time because of asynchronous nature, like we saw in the tweet.&lt;/p&gt;

&lt;p&gt;One way to avoid this experience is to hoist the data fetching to a common ancestor component and pass the data at once when all of the fetching is completed.&lt;/p&gt;

&lt;p&gt;Here, Dashboard is in charge for all of the components to audit the Spinners mess:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Dashboard() {
  const { isLoading: isInvestmentSeekingLoading, data: investmentSeekingData } =
  useQuery({
    queryKey: ["InvestmentSeeking"],
    queryFn: getInvestmentSeeking,
  });

  const { isLoading: isInvestmentVerificationLoading, data: investmentVerificationData }
  = useQuery({
    queryKey: ["InvestmentVerification"],
    queryFn: getInvestmentVerification,
  });

  // If *either* request is still pending, we'll show a spinner:
  if (isInvestmentSeekingLoading || isInvestmentVerificationLoading) {
    return &amp;lt;Spinner /&amp;gt;
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;InvestmentSeekingBox data={investmentSeekingData} /&amp;gt;
      &amp;lt;InvestmentVerificationBox data={investmentVerificationData} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this solution doesn’t go well with component mentality because the actual component that work with the data can not completely owned their data fetching logic. We'll lose that ergonomic of encapsulation here. Also as the data fetching requests increases, component would be bloated.&lt;/p&gt;

&lt;p&gt;So in the first case when every components for themselves, on plus side, we get a great DX but on minus side elements were not being gentle.&lt;/p&gt;

&lt;p&gt;Talk about second case, it's the opposite. We control the components of how they behave but components can not own their data requests.&lt;/p&gt;

&lt;p&gt;Suspense offers the best of both worlds, an ideal sweet spot with an addition of much more declarative-ish. Now components can own their data requests and also we can control how they show up on initial load by wrapping them with Suspense Boundary, similar to “hoisting fetching up” strategy. Now the only thing is to decide which components are wrap around which Suspense Component and part of the same group so that layout shifting don’t happen. Some Careful thinking needs on this depending on the application.&lt;/p&gt;

&lt;p&gt;So Loading and Error state is attached with Suspense, outside of individual components because of the strict isolation of components make the whole space of UI a disaster. With Suspense we still retains the isolation as major thing the data request is still rests with the components but without that baffling experience.&lt;/p&gt;

&lt;p&gt;I hope I was able to convey my understanding about why suspense was originally created.&lt;/p&gt;

&lt;p&gt;Warm thanks to &lt;a href="https://www.joshwcomeau.com/" rel="noopener noreferrer"&gt;Joshua Comeau&lt;/a&gt;, who taught me this eye-opening realization about Suspense original Vision. This is my reflection note of that &lt;strong&gt;WHY&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>suspense</category>
      <category>react</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>𝐅𝐫𝐚𝐦𝐢𝐧𝐠 𝐒𝐭𝐚𝐭𝐞 𝐃𝐞𝐬𝐢𝐠𝐧</title>
      <dc:creator>RAJIB DAS</dc:creator>
      <pubDate>Fri, 19 Jan 2024 03:43:41 +0000</pubDate>
      <link>https://forem.com/rajib18197/-1c01</link>
      <guid>https://forem.com/rajib18197/-1c01</guid>
      <description>&lt;p&gt;State let component remember information and we need it when a certain user action needs to change data from one value to other value.&lt;/p&gt;

&lt;p&gt;When Designing state in React Apps I follow a couple of guidelines that might be helpful for you:&lt;/p&gt;

&lt;p&gt;1) 𝐎𝐮𝐭𝐥𝐢𝐧𝐞 𝐔𝐬𝐞𝐫𝐬 𝐁𝐞𝐡𝐚𝐯𝐢𝐨𝐫𝐬 𝐚𝐧𝐝 𝐜𝐨𝐧𝐬𝐞𝐪𝐮𝐞𝐧𝐜𝐞𝐬&lt;/p&gt;

&lt;p&gt;The first step is to write all the steps users will do and what are the results they will see by using that component. This will force us to think about deeply what our component’s purpose actually is. &lt;/p&gt;

&lt;p&gt;So we observed what are the commands that can be given by users as they interact with that component on the screen and what are the responses they got.&lt;/p&gt;

&lt;p&gt;2) 𝐈𝐦𝐦𝐞𝐫𝐬𝐞 𝐲𝐨𝐮𝐫𝐬𝐞𝐥𝐟 𝐢𝐧 𝐨𝐧𝐥𝐲 𝐜𝐡𝐚𝐧𝐠𝐞𝐬 &lt;/p&gt;

&lt;p&gt;We need to set a specific intention here and don’t let ourselves be distracted by what is static in that component.&lt;/p&gt;

&lt;p&gt;Our only awareness here should be what is changing on the screen and remove static parts from our mind. This leads us to narrow down our focus to one thing only and simplify things.&lt;/p&gt;

&lt;p&gt;Alright, that's for state design. Time for think of a few strategies of where to place a state: Ask Yourself,&lt;/p&gt;

&lt;p&gt;⇒ which other components need that state? If the answer is 0, then place that state only in that component and we are done.&lt;/p&gt;

&lt;p&gt;⇒ Does that state needed by many different components such as - children, sibling, parent - then it’s a global state.&lt;/p&gt;

&lt;p&gt;𝑻𝒉𝒂𝒏𝒌 𝒚𝒐𝒖 𝒇𝒐𝒓 𝒓𝒆𝒂𝒅𝒊𝒏𝒈 📖. 𝑰 𝒉𝒐𝒑𝒆 𝒚𝒐𝒖 𝒉𝒂𝒗𝒆 𝒈𝒐𝒕 𝒔𝒐𝒎𝒆 𝒎𝒆𝒂𝒏𝒊𝒏𝒈𝒇𝒖𝒍 𝒊𝒏𝒔𝒊𝒈𝒉𝒕𝒔 𝒂𝒃𝒐𝒖𝒕 𝒔𝒕𝒂𝒕𝒆 𝒎𝒂𝒏𝒂𝒈𝒆𝒎𝒆𝒏𝒕.&lt;/p&gt;

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