<?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: Antonio Moruno Gracia</title>
    <description>The latest articles on Forem by Antonio Moruno Gracia (@moruno21).</description>
    <link>https://forem.com/moruno21</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%2F703397%2F63818246-2645-49ed-b436-7f880d0f4abc.JPG</url>
      <title>Forem: Antonio Moruno Gracia</title>
      <link>https://forem.com/moruno21</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/moruno21"/>
    <language>en</language>
    <item>
      <title>99% of frontend devs don't use this</title>
      <dc:creator>Antonio Moruno Gracia</dc:creator>
      <pubDate>Mon, 14 Jul 2025 18:55:05 +0000</pubDate>
      <link>https://forem.com/moruno21/99-of-frontend-devs-dont-use-this-1g44</link>
      <guid>https://forem.com/moruno21/99-of-frontend-devs-dont-use-this-1g44</guid>
      <description>&lt;p&gt;In the React world, most developers don’t think twice before using &lt;strong&gt;closures&lt;/strong&gt; in their component render methods, especially when mapping over lists. &lt;/p&gt;

&lt;p&gt;But what if I told you there's an underutilized, yet powerful alternative that can help with performance, readability, and even better integration with tools?&lt;/p&gt;

&lt;p&gt;Let’s talk about &lt;strong&gt;HTML data-* attributes&lt;/strong&gt;: a feature that’s rarely used by frontend developers, but deserves a second look.&lt;/p&gt;

&lt;h2&gt;
  
  
  ❓ What are data-* Attributes?
&lt;/h2&gt;

&lt;p&gt;HTML’s &lt;code&gt;data-*&lt;/code&gt; attributes allow you to &lt;strong&gt;embed custom data inside DOM elements&lt;/strong&gt;. In plain HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;John&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;strong&gt;React&lt;/strong&gt;, you can use them the same way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&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="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They are accessible in event handlers via the dataset object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧠 The Common Pattern: Closures in .map()
&lt;/h2&gt;

&lt;p&gt;Let’s say you’re rendering a list of items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;))}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works fine. It’s readable and easy to write.&lt;/p&gt;

&lt;p&gt;But behind the scenes, &lt;strong&gt;you're creating a new function for each item on every render&lt;/strong&gt;: a closure that captures &lt;code&gt;item.id&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In many apps, this has no practical impact. However...&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ The Downsides of Closures
&lt;/h2&gt;

&lt;p&gt;While closures are a fundamental part of JavaScript and React, using them inside &lt;code&gt;.map()&lt;/code&gt; can have drawbacks:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Unnecessary Re-Renders
&lt;/h3&gt;

&lt;p&gt;If you're using &lt;code&gt;React.memo&lt;/code&gt;, &lt;code&gt;React.useCallback&lt;/code&gt;, or virtualized lists (like &lt;a href="https://github.com/bvaughn/react-window" rel="noopener noreferrer"&gt;react-window&lt;/a&gt;), &lt;strong&gt;new function references can cause unwanted re-renders&lt;/strong&gt;. Since the function is recreated every time, memoization doesn't help.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Harder to Optimize
&lt;/h3&gt;

&lt;p&gt;Imagine you're building a highly interactive list that renders hundreds of items. Minimizing re-renders becomes important, and &lt;strong&gt;inline closures can work against that&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ The Alternative: &lt;code&gt;data-*&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Instead of creating a closure for each item, attach metadata directly to the DOM using &lt;code&gt;data-*&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Clicked item:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&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;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;))}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single function reference&lt;/strong&gt; → plays nicely with &lt;code&gt;React.memo&lt;/code&gt; or &lt;code&gt;React.useCallback&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved performance&lt;/strong&gt; for large lists or re-render-sensitive components&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🤔 So Why Isn’t Everyone Doing This?
&lt;/h2&gt;

&lt;p&gt;Because closures are easy, intuitive, and performant enough for most apps. &lt;code&gt;data-*&lt;/code&gt; feels a bit "old-school," and it’s rarely mentioned in modern React/Frontend tutorials.&lt;/p&gt;

&lt;p&gt;But in situations where performance or memoization matters, &lt;strong&gt;this approach can be a hidden gem&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ In Summary
&lt;/h2&gt;

&lt;p&gt;While &lt;code&gt;data-*&lt;/code&gt; attributes aren’t a common tool in a React developer’s toolbox, they offer real advantages in specific scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reduce unnecessary function creations&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improve memoization and rendering performance&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enable simpler and cleaner event handling&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They’re not a replacement for closures, but they’re a great alternative when performance or architecture calls for it.&lt;/p&gt;

&lt;p&gt;Have you ever used &lt;code&gt;data-*&lt;/code&gt; attributes like this? Or do you usually stick with closures? &lt;strong&gt;I’d love to hear your thoughts and experiences&lt;/strong&gt;! &lt;/p&gt;

&lt;p&gt;I hope you found this post interesting. Let me know what you think in the comments 👇&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>react</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Goodbye useCallback and useMemo: How React Compiler Takes Over</title>
      <dc:creator>Antonio Moruno Gracia</dc:creator>
      <pubDate>Sun, 10 Nov 2024 17:10:02 +0000</pubDate>
      <link>https://forem.com/moruno21/goodbye-usecallback-and-usememo-how-react-compiler-takes-over-40m8</link>
      <guid>https://forem.com/moruno21/goodbye-usecallback-and-usememo-how-react-compiler-takes-over-40m8</guid>
      <description>&lt;p&gt;For React developers, optimizing component performance often means managing a set of tools like &lt;code&gt;useCallback&lt;/code&gt;, &lt;code&gt;useMemo&lt;/code&gt;, and &lt;code&gt;memo&lt;/code&gt; to prevent unnecessary re-renders. These hooks allow developers to &lt;strong&gt;memoize values and functions&lt;/strong&gt;, keeping their React apps efficient. &lt;/p&gt;

&lt;p&gt;However, most of the times they also clutter the code and require frequent tuning, &lt;strong&gt;making their usage more of a headache&lt;/strong&gt; rather than a helpful tool for clean, maintainable code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React Compiler&lt;/strong&gt; changes this paradigm by &lt;strong&gt;automatically handling these optimizations&lt;/strong&gt;, allowing developers to focus on writing clean, maintainable code that follows React's best practices without being distracted by performance concerns. &lt;/p&gt;

&lt;p&gt;By analyzing your component code and applying performance enhancements behind the scenes, React Compiler makes it possible to write React code that’s both high-quality and efficient, without manually configuring memoization. &lt;/p&gt;

&lt;p&gt;With this, we’re looking at a future where developers can concentrate on building components the right way—using React principles—while React Compiler takes care of performance and optimization.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Current State of Memoization in React
&lt;/h2&gt;

&lt;p&gt;To understand how React Compiler changes things, let’s review how manual memoization works in React today.&lt;/p&gt;

&lt;h3&gt;
  
  
  useCallback
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;useCallback&lt;/code&gt; hook allows us to &lt;strong&gt;memoize functions&lt;/strong&gt;, ensuring they’re only recreated when their dependencies change. This is particularly useful when functions are passed as props to child components, as it prevents those components from re-rendering unnecessarily.&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useCallback&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&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;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&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;// handle click event&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="cm"&gt;/* dependencies */&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  useMemo
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;useMemo&lt;/code&gt; works similarly but is used to &lt;strong&gt;memoize values&lt;/strong&gt; rather than functions. It’s commonly used for heavy computations or data transformations that don’t need to be recalculated every render.&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMemo&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&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;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&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;data&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChildComponent&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;processedData&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  memo
&lt;/h3&gt;

&lt;p&gt;Finally, the &lt;code&gt;memo&lt;/code&gt; function can be used to memoize entire components. If the props passed to the component haven’t changed, memo skips re-rendering the component.&lt;/p&gt;

&lt;p&gt;When could this be useful? Well, imagine this situation:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;count2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setCount1&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setCount2&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;&amp;lt;/&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;Anytime &lt;code&gt;count1&lt;/code&gt; or &lt;code&gt;count2&lt;/code&gt; changes, &lt;strong&gt;the whole component and its children are rerendered&lt;/strong&gt; (even if those children doesn't use the state). Wrapping those components with &lt;code&gt;memo&lt;/code&gt; will avoid those unnecessary rerenders.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memo&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;Title&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="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="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memo&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;Counter&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="p"&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;Now, the only children components that will rerender are those whose props have changed. If &lt;code&gt;count1&lt;/code&gt; changes, only the first &lt;code&gt;&amp;lt;Counter/&amp;gt;&lt;/code&gt; will rerender. If &lt;code&gt;count2&lt;/code&gt; changes, only the second &lt;code&gt;&amp;lt;Counter/&amp;gt;&lt;/code&gt; will rerender.&lt;/p&gt;

&lt;h2&gt;
  
  
  How React Compiler Changes the Game
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;React Compiler seeks to make these optimizations for us&lt;/strong&gt;, eliminating the need for manually configuring &lt;code&gt;useCallback&lt;/code&gt;, &lt;code&gt;useMemo&lt;/code&gt;, or &lt;code&gt;memo&lt;/code&gt;. By analyzing each component and its dependencies, React Compiler can automatically determine where and when to apply memoization. This means no more worrying about remembering which hooks to use or fine-tuning dependencies lists—React Compiler handles it all.&lt;/p&gt;

&lt;p&gt;To highlight this, I will make use of this &lt;a href="https://github.com/jherr/compiler-repl/tree/main" rel="noopener noreferrer"&gt;react compiled code visualizer&lt;/a&gt;. Let's take a look at an example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Current transpiler
&lt;/h3&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%2Fzr135z2spy48j18ja9lg.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%2Fzr135z2spy48j18ja9lg.png" alt="Simple react example transpiled" width="800" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that the transpiler simply calls the &lt;code&gt;__jsx&lt;/code&gt; function (which works similarly to &lt;code&gt;React.createElement&lt;/code&gt;) to build the virtual DOM.&lt;/p&gt;

&lt;h3&gt;
  
  
  React compiler
&lt;/h3&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%2Fw41dlrfvsdxkrn99f138.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%2Fw41dlrfvsdxkrn99f138.png" alt="Simple react example compiled" width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s break this code down:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;React introduces the &lt;code&gt;c&lt;/code&gt; hook and uses it within the component. This creates an &lt;strong&gt;array of cacheable slots&lt;/strong&gt; (called &lt;code&gt;$&lt;/code&gt; in this case), with as many slots as the compiler deems necessary (two in this case).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The first slot is always reserved for the component's hash&lt;/strong&gt;—a unique identifier for each component, calculated based on its contents, including subcomponents, hooks, and other properties.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The remaining slots are reserved for the memoized version of the JSX&lt;/strong&gt; (in this case, there is one slot, the second one).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We check if these slots have stored data. If they do, &lt;strong&gt;the memoized component is stored in the slot&lt;/strong&gt; for reuse.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a rerender occurs and this function is called again, the memoized component is retrieved from the &lt;code&gt;$&lt;/code&gt; array without needing to call the &lt;code&gt;__jsx&lt;/code&gt; function again, &lt;strong&gt;preventing unnecessary rerendering&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is a simple example, but it illustrates the concept well. Here are some other key points about the React compiler:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It handles nested components&lt;/strong&gt;, hooks, and other complex structures seamlessly.&lt;/li&gt;
&lt;li&gt;It identifies constants in the component that won’t change, &lt;strong&gt;avoiding redundant creation&lt;/strong&gt; by directly using their values.&lt;/li&gt;
&lt;li&gt;If a component breaks any of the &lt;a href="https://es.react.dev/reference/react#rules-of-react" rel="noopener noreferrer"&gt;Rules of React&lt;/a&gt;, the compiler switches to a &lt;strong&gt;safe mode&lt;/strong&gt;. In this mode, the component isn’t memoized, which prevents potential bugs or unexpected behavior.&lt;/li&gt;
&lt;li&gt;And more.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;React Compiler promises to revolutionize how we approach performance optimization in React. By eliminating the need for manual memoization hooks, it simplifies code and allows developers to build applications without getting bogged down in performance tweaks. As React Compiler becomes more integrated, it will free us from useCallback, useMemo, and memo, making React development more intuitive and accessible than ever, letting us focus on what really matters: &lt;strong&gt;building great apps&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That said, React Compiler is still in development and is not yet recommended for production use. However, there are some linting rules available, such as &lt;code&gt;eslint-plugin-react-compiler&lt;/code&gt;, that prepare us for when the compiler becomes production-ready by surfacing problematic React code detected by the compiler.&lt;/p&gt;

&lt;p&gt;This post is inspired in &lt;a href="https://www.youtube.com/watch?v=PYHBHK37xlE" rel="noopener noreferrer"&gt;this youtube video&lt;/a&gt;. Don't hesitate to check it out in case you want to learn more about React compiler!&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactcompiler</category>
      <category>performance</category>
      <category>compiling</category>
    </item>
    <item>
      <title>Keep it Silly, Stupid</title>
      <dc:creator>Antonio Moruno Gracia</dc:creator>
      <pubDate>Sun, 31 Mar 2024 15:46:27 +0000</pubDate>
      <link>https://forem.com/moruno21/keep-it-silly-stupid-4hg2</link>
      <guid>https://forem.com/moruno21/keep-it-silly-stupid-4hg2</guid>
      <description>&lt;p&gt;If you've entered this article because you think I misspelt the KISS principle, I'm sorry, but you've been clickbaited.&lt;/p&gt;

&lt;p&gt;Let me explain myself.&lt;/p&gt;

&lt;p&gt;The desing of reusable and flexible components has almost become a form of art (like any part of development actually).&lt;/p&gt;

&lt;p&gt;However, it's easy to fall into the trap of creating overly complex components that are tightly coupled to specific use cases.&lt;/p&gt;

&lt;p&gt;My take here is to &lt;strong&gt;keep them silly&lt;/strong&gt;. That is, making them as dumb as possible. By doing so, we can maximize their reusability.&lt;/p&gt;

&lt;p&gt;The key aspect of this paradigm is &lt;strong&gt;managing state from the outside&lt;/strong&gt;. Instead of storing component state internally, we delegate state management to higher-level components that utilize them.&lt;/p&gt;

&lt;p&gt;Let's take a look at how we can achieve that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing state internally
&lt;/h2&gt;

&lt;p&gt;Imagine we're creating a &lt;strong&gt;Dropdown component&lt;/strong&gt;. The typical approach that many developers would take is as follows: when a user selects a field from the dropdown, we set that value within the dropdown component itself.&lt;/p&gt;

&lt;p&gt;This way, we can set the component's state from the inside.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnm4kvup8slwbal90tpj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnm4kvup8slwbal90tpj.png" alt="Managing state internally" width="800" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, while creating the dropdown component with its internal state may seem sufficient for most scenarios, let's consider a different use case.&lt;/p&gt;

&lt;p&gt;Imagine we want to reuse the Dropdown component in a filter page within our application. In this scenario, instead of setting the selected value within the dropdown itself, we would set a filter tag just below the dropdown when a user selects a field.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now, our previous approach doesn't work&lt;/strong&gt;. Some people might consider one of these options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create another new component just for this new use case.&lt;/li&gt;
&lt;li&gt;Create a prop that indicates the component how it should behave.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice that both these two alternatives break the &lt;a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle"&gt;Open Closed Principle&lt;/a&gt;: &lt;strong&gt;any time we want our component to support one new use case, we'll have to modify it&lt;/strong&gt;. None of those are a desirable choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing state with callbacks
&lt;/h2&gt;

&lt;p&gt;The best approach here is to make our original component reusable by &lt;strong&gt;uplifting its state&lt;/strong&gt;. But, how will we be able to set the component's state if we uplift it? Well, that's where &lt;strong&gt;callbacks&lt;/strong&gt; come into play.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy68jnfzon8jvq4sw2o4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy68jnfzon8jvq4sw2o4w.png" alt="Managing state from the outside" width="800" height="902"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rather than having a complex component manage its own state depending on its use case, we lift the state up to the parent component and pass down the necessary data and callbacks as props.&lt;/p&gt;

&lt;p&gt;This way now, our component is &lt;strong&gt;opened for extension&lt;/strong&gt;, but &lt;strong&gt;closed for modification&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The dropdown component doesn't know what the callback does. It can set the dropdown value, set some filters, etc. It can do whatever we want. &lt;/p&gt;

&lt;p&gt;The component just knows that it has to execute the callback. What the callback does is not its responsability. It's its parent's.&lt;/p&gt;




&lt;p&gt;There are situations where we develop a component that we know we're not going to reuse. In such cases, applying this paradigm could potentially increase complexity. Therefore, it's important to use this approach wisely.&lt;/p&gt;

&lt;p&gt;Instead of tightly coupling your components to specific use cases, consider &lt;strong&gt;composing&lt;/strong&gt; them from the outside when necessary.&lt;/p&gt;

&lt;p&gt;And that's why you should remember to &lt;strong&gt;Keep it &lt;del&gt;Simple&lt;/del&gt; Silly, Stupid&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Thinking in Frontend</title>
      <dc:creator>Antonio Moruno Gracia</dc:creator>
      <pubDate>Mon, 26 Feb 2024 20:34:56 +0000</pubDate>
      <link>https://forem.com/moruno21/thinking-in-frontend-2k41</link>
      <guid>https://forem.com/moruno21/thinking-in-frontend-2k41</guid>
      <description>&lt;p&gt;In the dynamic universe of crafting software of any kind, there are a thousand roads to take. However, sometimes finding the best combination is the key. Frontend applications are no exception.&lt;/p&gt;

&lt;p&gt;It's like having a bunch of Lego pieces at your disposal. Imagine that you want to build a new fancy house with your building blocks. You can achive it in multiple ways, but not all of them are the best way to do it: some bricks may be too big, others too small; others won't fit exactly as desired, etc.&lt;/p&gt;

&lt;p&gt;In this article, we'll structure our minds so we'll be able to &lt;strong&gt;create more readable and manteinable layouts&lt;/strong&gt;. We'll learn how thinking in frontend is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Boxes, boxes and more boxes
&lt;/h2&gt;

&lt;p&gt;At its core, this article encourages you to &lt;strong&gt;think of every element on the webpage as a box&lt;/strong&gt;. This mental model simplifies the complexity of design by treating each component (be it text, images, or interactive elements) as a modular and self-contained entity: a box.&lt;/p&gt;

&lt;p&gt;Try to think of any webpage. Even this article itself. It's full of boxes all over the place. They're everywhere!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpal8wimrhrnu551ut7e8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpal8wimrhrnu551ut7e8.gif" alt="Boxes everywhere meme" width="498" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rather than focusing on specific properties like width, height, padding, border, or margin; the box paradigm urges developers to focus on the whole mix. Each box contributes to the overall visual harmony, and their arrangement determines the flow and structure of the entire interface.&lt;/p&gt;

&lt;p&gt;In the example below, I've highlighted some of the boxes that compose a tipical Dev.to article page. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqlmja4dvm59gz81tw3rl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqlmja4dvm59gz81tw3rl.png" alt="Devto Article Layout" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I encourage you to do the same exercise on your own. Try to imagine the boxes that compose this page. Some boxes are bigger, and boxes are smaller, but they all play an important role in composing the article. &lt;/p&gt;

&lt;p&gt;Before starting coding your layout, do this mental exercise:  &lt;strong&gt;think about which boxes does and contains what&lt;/strong&gt;. Have in mind what responsability (positioning, aligning, containing) each of them should have in order to create a flexible and organized layout. &lt;/p&gt;

&lt;p&gt;Talking about responsability, I encourage you to check &lt;a href="https://dev.to/moruno21/dont-use-margin-in-css-33f9"&gt;this article&lt;/a&gt; afterwards 😄&lt;/p&gt;

&lt;p&gt;If we start thinking that way, structuring our frontend applications turns out to be much easier, even entertaining! It's like being able to choose and create our own building blocks, which will compose the whole picture. &lt;strong&gt;It simplifies frontend chaos&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why worrying that much?
&lt;/h2&gt;

&lt;p&gt;Although this way of thinking might sound pretty straightforward (even obvious for some of you), you wouldn't believe how many times I've run into layouts in which this reasoning hasn't been applied.&lt;/p&gt;

&lt;p&gt;Something that easy as creating the layout of some component or page could turn into a &lt;strong&gt;nightmare&lt;/strong&gt;, resulting in creating messy code where, if you change any part of it, the complete layout falls to pieces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Break down your design into manageable chunks&lt;/strong&gt;, and suddenly, everything becomes way easier to handle. Styling, positioning, responsiveness – it all falls into place like pieces of a puzzle; easier code to read and mantain.&lt;/p&gt;

&lt;p&gt;I encourage you to do this mental exercise before starting writing your code. Spend some time at it. You will save time later.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>cleancode</category>
      <category>html</category>
      <category>react</category>
    </item>
    <item>
      <title>Avoid Over-Propping with Accessible Components in React</title>
      <dc:creator>Antonio Moruno Gracia</dc:creator>
      <pubDate>Sun, 21 Jan 2024 20:14:43 +0000</pubDate>
      <link>https://forem.com/moruno21/avoid-over-propping-with-accessible-components-in-react-5gbc</link>
      <guid>https://forem.com/moruno21/avoid-over-propping-with-accessible-components-in-react-5gbc</guid>
      <description>&lt;p&gt;One of React's basics are &lt;strong&gt;props&lt;/strong&gt;. They are used to pass data from a parent component to its child components. While they are a great way to handle flow of data, sometimes we tend to overuse them, leading to increasing code complexity and reduced readability. It may make the component harder to maintain, understand and reuse.&lt;/p&gt;

&lt;p&gt;In this short article I'd like to propose one way to handle this problem, taking advantage of the &lt;strong&gt;ARIA Attributes&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ❌ The problem
&lt;/h2&gt;

&lt;p&gt;Sometimes we need to pass some props to our components for styling purposes. In this example, we need to create a &lt;strong&gt;Radio Button&lt;/strong&gt;, which changes its border color depending of whether it's checked or not (in this case we're using styled-components).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ComponentProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;$checked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ComponentProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;`
  // Some styles...

  &lt;/span&gt;&lt;span class="p"&gt;${({&lt;/span&gt; &lt;span class="nx"&gt;$checked&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;$checked&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="s2"&gt;`
          border-color: 1px solid blue;
        `&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="s2"&gt;`
          border-color: 1px solid grey;
        `&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
`&lt;/span&gt;

&lt;span class="c1"&gt;// Some code&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; 
  &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt;
      &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="na"&gt;checked&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;checked&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"component"&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"radio"&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"component"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Radio input&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we already have the &lt;code&gt;checked&lt;/code&gt; prop (html input has it natively), we'd have to &lt;strong&gt;create another prop&lt;/strong&gt; if we wanted to apply some styles depending on it: &lt;code&gt;$checked&lt;/code&gt;. We also need to type our component so Typescript knows that it has this new prop.&lt;/p&gt;

&lt;p&gt;This technique adds a lot of unnecessary code and, moreover, it isn't accessible at all. Let's fix that.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ The solution
&lt;/h2&gt;

&lt;p&gt;There are certain situations where we can avoid creating these props by ourselves. Instead, we can accomplish the same behaviour with &lt;strong&gt;ARIA Attributes&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="s2"&gt;`
  // Some styles...
  border-color: 1px solid grey;

  &amp;amp;[aria-checked='true'] {
    border-color: 1px solid blue;
  }
`&lt;/span&gt;

&lt;span class="c1"&gt;// Some code&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; 
  &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt;
      &lt;span class="na"&gt;aria-checked&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;checked&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"component"&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"radio"&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"component"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Radio input&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we're using the &lt;code&gt;aria-checked&lt;/code&gt; attribute here. Not only we're &lt;strong&gt;avoiding creating unnecessary props&lt;/strong&gt;, but also &lt;strong&gt;our application is much more accessible&lt;/strong&gt;, keeping also the behaviour &lt;strong&gt;as close to native as possible&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Another examples where this approach might be useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;aria-expanded&lt;/code&gt; for a dropdown component.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aria-disabled&lt;/code&gt; when we want to disable operations over a certain element.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aria-selected&lt;/code&gt; for an element selected in a tablist.&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Take into account that, as said before, this only applies for certain situations. Some ARIA Attributes might not provide the intented utility. You must be careful and responsible, taking accessibility seriously. Use this approach wisely.&lt;/p&gt;

&lt;p&gt;The main point of this article is to state that, most of the times, is better to remain as close to native as possible, rather than creating unnecessary code.&lt;/p&gt;

&lt;p&gt;I hope you liked it!&lt;/p&gt;

</description>
      <category>react</category>
      <category>frontend</category>
      <category>cleancode</category>
      <category>webdev</category>
    </item>
    <item>
      <title>GraphQL Infinite Scroll</title>
      <dc:creator>Antonio Moruno Gracia</dc:creator>
      <pubDate>Sun, 26 Nov 2023 18:08:23 +0000</pubDate>
      <link>https://forem.com/moruno21/graphql-infinite-scroll-4oan</link>
      <guid>https://forem.com/moruno21/graphql-infinite-scroll-4oan</guid>
      <description>&lt;p&gt;Ever wonder how to enhance your website with an infinite scroll feature that keeps your users endlessly engaged?&lt;/p&gt;

&lt;p&gt;In this article, we’re breaking down the process of creating an &lt;strong&gt;infinite scroll using GraphQL and React&lt;/strong&gt;. By the end of this guide, you’ll be able to implement it in your own web projects. &lt;/p&gt;

&lt;p&gt;Let’s dive in and unlock the secrets of infinite scrolling with GraphQL and React—it’s easier than you might think!&lt;/p&gt;




&lt;h2&gt;
  
  
  The Posts List
&lt;/h2&gt;

&lt;p&gt;We are implementing a simple post list to serve as an example for this article. We will use this &lt;a href="https://graphqlzero.almansi.me/" rel="noopener noreferrer"&gt;api&lt;/a&gt; to get some dummy posts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fa701ndp3ckuhmxutxn7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fa701ndp3ckuhmxutxn7i.png" alt="Main Layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our case, we want to show the top 100 most rated post. Initially, we don't want to load all the posts at once. It would be more appropiate to load some posts, and when the user scrolls down the least then we load some more, and so on. That's the purpose of infinite scrolling: &lt;strong&gt;saving users from an initial full page load&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, here we have the code that renders the page where we show all the posts.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/pages/posts/index.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Spinner&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/components/Spinner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useLayout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Post&lt;/span&gt;&lt;span class="dl"&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;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PageTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;,&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="s1"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Layout&lt;/span&gt; &lt;span class="o"&gt;=&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;thresholdElementRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useLayout&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PageTitle&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Infinite&lt;/span&gt; &lt;span class="nx"&gt;Scroll&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/PageTitle&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="nx"&gt;Most&lt;/span&gt; &lt;span class="nx"&gt;rated&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Title&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Check&lt;/span&gt; &lt;span class="nx"&gt;them&lt;/span&gt; &lt;span class="nx"&gt;all&lt;/span&gt; &lt;span class="nx"&gt;by&lt;/span&gt; &lt;span class="nx"&gt;scrolling&lt;/span&gt; &lt;span class="nx"&gt;down&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Description&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Spinner&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;
                &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;thresholdElementRef&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;))}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/List&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;)}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Content&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Container&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&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="nx"&gt;Layout&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We are using a &lt;strong&gt;custom hook&lt;/strong&gt; &lt;code&gt;useLayout&lt;/code&gt;, from where we are extracting three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;loading&lt;/code&gt;: Not relevant to this article. Just tells us if the query is still loading.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;posts&lt;/code&gt;: &lt;strong&gt;The posts that are being rendered&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;thresholdElementRef&lt;/code&gt;: &lt;strong&gt;A reference attached to the element that will serve as a threshold&lt;/strong&gt;. In our case, that element will be the last post.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's take a look at our &lt;code&gt;useLayout&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/pages/posts/hooks.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;usePosts&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/hooks/usePosts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useInfiniteScroll&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/lib/use-infinite-scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useLayout&lt;/span&gt; &lt;span class="o"&gt;=&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetchMorePosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;usePosts&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;thresholdElementRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useInfiniteScroll&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;fetchNextPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fetchMorePosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;rootMargin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;400px&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;thresholdElementRef&lt;/span&gt; &lt;span class="p"&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="nx"&gt;useLayout&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Right here, we are creating the &lt;code&gt;thresholdElementRef&lt;/code&gt; using &lt;br&gt;
&lt;code&gt;useInfiniteScroll&lt;/code&gt;. This library receives the &lt;code&gt;fetchMorePosts&lt;/code&gt; function and some options as props. Let's break everything down step by step.&lt;/p&gt;




&lt;h2&gt;
  
  
  The &lt;code&gt;useInfiniteScroll&lt;/code&gt; lib
&lt;/h2&gt;

&lt;p&gt;This library will allow us to obtain a threshold reference, which we will asign to the element that will serve as a threshold.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/lib/use-infinite-scroll/index.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useIntersectedElement&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../use-intersected-element&lt;/span&gt;&lt;span class="dl"&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;UseInfiniteScrollProps&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="s1"&gt;./types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useInfiniteScroll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThresholdElement&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Element&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;fetchNextPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;UseInfiniteScrollProps&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;thresholdElementRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useIntersectedElement&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThresholdElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fetchNextPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;options&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="nx"&gt;thresholdElementRef&lt;/span&gt; &lt;span class="p"&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="nx"&gt;useInfiniteScroll&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This library just passes the received props to another library: &lt;code&gt;useIntersectedElement&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/lib/use-intersected-element/index.ts&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;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&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;UseIntersectedElementProps&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="s1"&gt;./types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useIntersectedElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThresholdElement&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Element&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;UseIntersectedElementProps&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;thresholdElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;thresholdElementRef&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThresholdElement&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;entry&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;],&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;thresholdElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thresholdElement&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unobserve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thresholdElement&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;thresholdElement&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;thresholdElementRef&lt;/span&gt; &lt;span class="p"&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="nx"&gt;useIntersectedElement&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UseIntersectedElementProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here, we create a state, whose &lt;em&gt;setter&lt;/em&gt; is the ref that we've been talking about. Remember that, ultimately, &lt;strong&gt;this threshold element will be the last post of the list&lt;/strong&gt;, as we mentioned before.&lt;/p&gt;

&lt;p&gt;Then, we use &lt;code&gt;IntersectionObserver&lt;/code&gt; to create an observer, which will execute the &lt;code&gt;callback&lt;/code&gt; function received as an argument (&lt;strong&gt;remember the&lt;/strong&gt; &lt;code&gt;fetchMorePosts&lt;/code&gt; &lt;strong&gt;function in the&lt;/strong&gt; &lt;code&gt;useLayout&lt;/code&gt; &lt;strong&gt;hook?&lt;/strong&gt;). If the &lt;code&gt;entry&lt;/code&gt; (the target element) is not been intersected, then we execute nothing.&lt;/p&gt;

&lt;p&gt;It can also receive some options. In our case (&lt;strong&gt;remember the&lt;/strong&gt; &lt;code&gt;useLayout&lt;/code&gt; &lt;strong&gt;hook&lt;/strong&gt;), we only use the &lt;code&gt;rootMargin: '400px'&lt;/code&gt;, which increase the size of the root element's bounding box before computing intersections. You can take a look at the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; in case of any doubts.&lt;/p&gt;

&lt;p&gt;Finally, in the &lt;code&gt;useEffect&lt;/code&gt; we are observing the threshold element, and unobserving it when the component unmounts.&lt;/p&gt;




&lt;h2&gt;
  
  
  The &lt;code&gt;fetchMorePosts&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What does GraphQL have to do with all of this?&lt;/strong&gt; Well, here it comes!&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/hooks/usePosts/index.ts&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;useQuery&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="s1"&gt;@apollo/client&lt;/span&gt;&lt;span class="dl"&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;useCallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMemo&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;POSTS&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/graphql/queries/posts&lt;/span&gt;&lt;span class="dl"&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;PostsQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PostsQueryVariables&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="s1"&gt;~/graphql/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/models/post&lt;/span&gt;&lt;span class="dl"&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;MAX_NUMBER_OF_POSTS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;POSTS_LIMIT&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="s1"&gt;./constants&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usePosts&lt;/span&gt; &lt;span class="o"&gt;=&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fetchMore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
    &lt;span class="nx"&gt;PostsQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;PostsQueryVariables&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;POSTS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;POSTS_LIMIT&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="p"&gt;})&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(&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="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromDto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&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;fetchMorePosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;MAX_NUMBER_OF_POSTS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="nf"&gt;fetchMore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;updateQuery&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetchMoreResult&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fetchMoreResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;data&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;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&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;fetchMoreResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;??&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="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;paginate&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;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;POSTS_LIMIT&lt;/span&gt; &lt;span class="o"&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="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;fetchMore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;posts&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;fetchMorePosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&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="nx"&gt;usePosts&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We need to use &lt;code&gt;useQuery&lt;/code&gt; to fetch the data from the api. It is important that the api supports &lt;strong&gt;pagination&lt;/strong&gt;. Pagination is a process used to &lt;strong&gt;divide a large dataset into smaller chunks&lt;/strong&gt; (pages). This will allow us to request a "page" per request (ultimately allowing the implementation of an infinite scroll). In our case, we will request 10 posts per "page". We will store all those posts in &lt;code&gt;posts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, here we have (finally 😅) the &lt;code&gt;fetchMorePosts&lt;/code&gt; function. It makes use of the &lt;code&gt;fetchMore&lt;/code&gt; function, which allows to send followup queries to our GraphQL server to obtain additional pages. &lt;/p&gt;

&lt;p&gt;The behaviour would be the following: &lt;strong&gt;If we've reached the maximum number of posts, we stop requesting data. If not,&lt;/strong&gt; &lt;code&gt;fetchMorePosts&lt;/code&gt; &lt;strong&gt;will request the next 10 posts, adding them to&lt;/strong&gt; &lt;code&gt;posts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can find more information about GraphQL pagination in the &lt;a href="https://www.apollographql.com/docs/react/pagination/core-api/" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demonstration
&lt;/h2&gt;

&lt;p&gt;We did it! Now we have an infinite scroll in our posts list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fl6zhkespspua0ivnc3eh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fl6zhkespspua0ivnc3eh.gif" alt="infinte-scroll"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, to sum up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We &lt;strong&gt;set the threshold reference to the last post&lt;/strong&gt; that is being rendered (firstly, it will be the 10th, then the 20th, etc.)&lt;/li&gt;
&lt;li&gt;We set the callback &lt;code&gt;fetchMorePosts&lt;/code&gt; to the threshold, and &lt;strong&gt;execute it when the threshold is reached&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fetchMorePosts&lt;/code&gt; will query 10 posts at a time, &lt;strong&gt;adding them to the ones that have already been requested&lt;/strong&gt;, until the limit is reached.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All the project code is available in this &lt;a href="https://github.com/moruno21/infinite-scroll" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Deciding to use GraphQL shouldn't be about adding infinite scroll. It's a bigger decision. However, GraphQL is a versatile tool that allows us to apply and implement some great things, and infinite scroll is not an exception.&lt;/p&gt;

&lt;p&gt;I hope you've enjoyed the article and that it has encouraged you to add it to your projects. Thanks for your time!&lt;/p&gt;

</description>
      <category>react</category>
      <category>graphql</category>
      <category>infinitescroll</category>
      <category>webdev</category>
    </item>
    <item>
      <title>CSS Learning Roadmap</title>
      <dc:creator>Antonio Moruno Gracia</dc:creator>
      <pubDate>Mon, 23 Oct 2023 20:18:43 +0000</pubDate>
      <link>https://forem.com/moruno21/css-learning-roadmap-1f1p</link>
      <guid>https://forem.com/moruno21/css-learning-roadmap-1f1p</guid>
      <description>&lt;p&gt;Cascading Style Sheets (CSS) is a fundamental technology for web development, empowering you to transform raw HTML into stunning, well-designed web pages.&lt;/p&gt;

&lt;p&gt;In this roadmap, we'll provide a &lt;strong&gt;straightforward enumeration of key concepts&lt;/strong&gt;, techniques, and areas of focus to help you progress in your CSS journey. Whether you're a novice or a seasoned developer, this roadmap is designed to be your reference for &lt;strong&gt;what to learn next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's begin.&lt;/p&gt;




&lt;h2&gt;
  
  
  CSS Syntax
&lt;/h2&gt;

&lt;p&gt;Understading CSS Syntax is &lt;strong&gt;fundamental&lt;/strong&gt; in order to start learning CSS. This section introduces learners to selectors, properties, and values, explaining how to target HTML elements and apply styling.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Basic syntax&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selectors&lt;/strong&gt;: (pseudo)classes, (pseudo)elements, attributes and combinators&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Media queries&lt;/strong&gt; and responsiveness&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  CSS Basics
&lt;/h2&gt;

&lt;p&gt;In this section, you will dive into &lt;strong&gt;core styling principles&lt;/strong&gt;. This provides a strong foundation for fundamental CSS concepts, which are used in many different situations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Color&lt;/strong&gt;, &lt;strong&gt;Texts&lt;/strong&gt; and &lt;strong&gt;Fonts&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size&lt;/strong&gt; and &lt;strong&gt;Units&lt;/strong&gt;: absolute (&lt;code&gt;px&lt;/code&gt;, &lt;code&gt;in&lt;/code&gt;, &lt;code&gt;pt&lt;/code&gt;, etc) and relative (&lt;code&gt;em&lt;/code&gt;, &lt;code&gt;rem&lt;/code&gt;, &lt;code&gt;vh&lt;/code&gt;, &lt;code&gt;vw&lt;/code&gt;, &lt;code&gt;%&lt;/code&gt;, etc)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CSS Cascade&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Basic display: &lt;strong&gt;Block elements&lt;/strong&gt; and &lt;strong&gt;Inline elements&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Height&lt;/strong&gt; and &lt;strong&gt;Width&lt;/strong&gt;: &lt;code&gt;(min, max, fit)-content&lt;/code&gt;, maximum and minimum, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS Box Model&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;Margin&lt;/li&gt;
&lt;li&gt;Border&lt;/li&gt;
&lt;li&gt;Padding&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Managing &lt;strong&gt;overflow&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Images&lt;/strong&gt;: sizing, positioning and fitting&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Positioned Layout
&lt;/h2&gt;

&lt;p&gt;The use of position layout allows to &lt;strong&gt;control the placement of elements&lt;/strong&gt; on a webpage. By mastering these key concepts, you'll gain the skills to design complex web layouts and add creative touches to your projects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Relative&lt;/strong&gt; positioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Absolute&lt;/strong&gt; positioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixed&lt;/strong&gt; positioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sticky&lt;/strong&gt; positioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stacking contexts&lt;/strong&gt; and &lt;strong&gt;z-index&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Flexbox
&lt;/h2&gt;

&lt;p&gt;Flexbox, or the Flexible Box Layout, is a powerful CSS layout model for creating &lt;strong&gt;responsive and dynamic page structures&lt;/strong&gt;. This section serves as an introduction of these layout key concepts. As soon you understand them all, you will master this type of layout.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding &lt;strong&gt;Flex layout basics&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content&lt;/strong&gt; vs &lt;strong&gt;Items&lt;/strong&gt; vs &lt;strong&gt;Self&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spacing&lt;/strong&gt;, &lt;strong&gt;Justifying&lt;/strong&gt; and &lt;strong&gt;Aligning&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;flex&lt;/code&gt; property: &lt;code&gt;flex-grow&lt;/code&gt;, &lt;code&gt;flex-shrink&lt;/code&gt; and &lt;code&gt;flex-basis&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Grid Layout
&lt;/h2&gt;

&lt;p&gt;CSS Grid Layout is another essential layout tool. It allows to &lt;strong&gt;create two-dimensional grids&lt;/strong&gt; and control the placement and alignment of elements with precision. This section presents some of the main grid concepts and properties, providing the steps to follow to build intricate page layouts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding &lt;strong&gt;Grid layout basics&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Managing &lt;strong&gt;rows&lt;/strong&gt; and &lt;strong&gt;columns&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content&lt;/strong&gt; vs &lt;strong&gt;Items&lt;/strong&gt; vs &lt;strong&gt;Self&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spacing&lt;/strong&gt;, &lt;strong&gt;Justifying&lt;/strong&gt; and &lt;strong&gt;Aligning&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Bonus
&lt;/h2&gt;

&lt;p&gt;This last section includes some CSS topics and practical applications that don't really fit in the sections above. This encompass topics like CSS animations, transitions, responsive design, and best practices for optimizing CSS code. It's a space to explore more specialized concepts and techniques that &lt;strong&gt;enhance a web developer's skill set&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Accessibility&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Animations&lt;/strong&gt; and &lt;strong&gt;effects&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Transitions, transforming, keyframes&lt;/li&gt;
&lt;li&gt;Shadows, effects and gradients&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Learning to manage CSS in the &lt;strong&gt;Browser Inspector&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Styled-components&lt;/strong&gt; and &lt;strong&gt;SASS&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;From my experience, I have always found it challenging to discover a guide to follow in order to master CSS. I must point out that this list is based on my personal experience. Each person should have its own path. Use this list as a guide, not as the source of true.&lt;/p&gt;

&lt;p&gt;I hope this list proves to be useful for you.&lt;/p&gt;

&lt;p&gt;Thanks for your time!&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>learning</category>
      <category>react</category>
    </item>
    <item>
      <title>Don't use margin in CSS</title>
      <dc:creator>Antonio Moruno Gracia</dc:creator>
      <pubDate>Tue, 10 Oct 2023 19:52:30 +0000</pubDate>
      <link>https://forem.com/moruno21/dont-use-margin-in-css-33f9</link>
      <guid>https://forem.com/moruno21/dont-use-margin-in-css-33f9</guid>
      <description>&lt;p&gt;Nowadays, CSS has a wide range of tools and properties that allow designs that, until a few years ago, seemed impossible to implement. Many developers focus on learning this style language to the smallest detail, which can be quite challenging for some.&lt;/p&gt;

&lt;p&gt;Despite not being considered a programming language by most, it's important to note that it's also a part of many applications. As developers, we should be responsible, making the code we develop as easy to &lt;strong&gt;understand, modify, and maintain&lt;/strong&gt; as possible. CSS is no exception.&lt;/p&gt;

&lt;p&gt;The goal of this post is to shed some light on a well-known property in CSS: &lt;strong&gt;margin&lt;/strong&gt;. We will discuss its sometimes incorrect usage and propose alternative approaches that are much more maintainable and clean.&lt;/p&gt;




&lt;h2&gt;
  
  
  ❌ When not to use
&lt;/h2&gt;

&lt;p&gt;The main reason for not using margin lies in a matter of &lt;strong&gt;responsibility&lt;/strong&gt;. When designing the layout of an application or an individual component, we should consider who is responsible for what.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(For the sake of the post, we will omit border styles and other details).&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Between parent and children
&lt;/h3&gt;

&lt;p&gt;Let's imagine that we want to implement the following layout. The goal is to position the blocks as shown in the image. Who is responsible for placing the child at a certain distance from the parent: the child or the parent?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fp8oz3urp37ud8awkptft.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fp8oz3urp37ud8awkptft.png" alt="Layout with one block as child"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's the parent&lt;/strong&gt; who should define the distance at which their children are positioned. This is the key. &lt;strong&gt;The responsibility lies within the parent block&lt;/strong&gt;. If we wanted to change the content of the parent, we would probably want to preserve the distance that their children have from it, so these styles should belong to the parent.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.parent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/*No margin needed*/&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Of course, there are exceptions. It's possible that we may need to create a layout where the children are not at the same distance to the parent, as shown in the following image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9qfcnpflzmy03w70zjcx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9qfcnpflzmy03w70zjcx.png" alt="Layout with many blocks as children"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, it's possible to approach the design as follows: &lt;strong&gt;the parent of the last two elements is not the same as the parent of the first element&lt;/strong&gt;. We can create another element to serve as a &lt;strong&gt;wrapper for the last two elements&lt;/strong&gt; and apply the "extra margin" they have as padding.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F66bgws9vh6xxyj5m0a4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F66bgws9vh6xxyj5m0a4p.png" alt="Adding wrapper to the last two children"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.parent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/*Extra padding for the last two children*/&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/*No margin needed*/&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note: The borders are shown simply to illustrate the blocks we would have at code level. The presence of an additional parent block would be invisible to the application end-user.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Between siblings
&lt;/h3&gt;

&lt;p&gt;You may have noticed a detail in the previous layout: &lt;strong&gt;the child elements are also separated from each other.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This separation can be achieved by applying top or bottom margin to all of them. However, we come back to the same question: who should be responsible for separating the children from each other? Well, surprisingly, &lt;strong&gt;it should be the parent.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But, from the parent, how can we separate children from each other? The best option is to harness the power of the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout" rel="noopener noreferrer"&gt;Grid Layout&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This post doesn't cover the use of this type of layout in detail. In summary, the &lt;strong&gt;Grid Layout&lt;/strong&gt; allows us to treat the children of an element as if they were in a grid, organizing how they are positioned relative to each other. Among its options, it's possible to determine the exact distance at which elements are positioned from each other. How? Well, by using the &lt;code&gt;gap&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fdtlnpxe6esg1m3soafcn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fdtlnpxe6esg1m3soafcn.png" alt="Container with elements positioned using grid layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.parent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/*Changes the display layout to grid*/&lt;/span&gt;
    &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/*Desired gap between elements*/&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/*No margin needed*/&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The major advantage of using this alternative is that the &lt;code&gt;gap&lt;/code&gt; property &lt;strong&gt;adds space only between the elements, neither at the beginning nor at the end&lt;/strong&gt;. If we were to use margins for each element, we would need to ensure that these margins are not applied incorrectly to the first or last element to avoid unnecessary spacing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazing! Isn't it?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ When to use
&lt;/h2&gt;

&lt;p&gt;There are some occasions when using margin is not a bad alternative.&lt;/p&gt;

&lt;h3&gt;
  
  
  Margin: auto
&lt;/h3&gt;

&lt;p&gt;If an element uses &lt;code&gt;margin: auto&lt;/code&gt;, &lt;strong&gt;it will be centered horizontally with respect to its parent&lt;/strong&gt;. However, there are several considerations to keep in mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This only works for centering elements horizontally, not vertically.&lt;/li&gt;
&lt;li&gt;Inline elements (&lt;code&gt;&amp;lt;a/&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;em/&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;span/&amp;gt;&lt;/code&gt;, etc) cannot be centered using this declaration. It only works for block elements.&lt;/li&gt;
&lt;li&gt;We come back to the same question again: who is responsible for centering the element? In this case, the element would be centered by itself, not by its parent.&lt;/li&gt;
&lt;li&gt;There are other properties within the flex and grid layouts that allow both vertical and horizontal centering (&lt;code&gt;justify-content&lt;/code&gt;, &lt;code&gt;align-items&lt;/code&gt;, etc), which could be more appropiate.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Despite these disadvantages, sometimes using &lt;code&gt;margin: auto&lt;/code&gt; is simpler and quicker than any of the alternatives, so it's not a bad choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overlapping
&lt;/h3&gt;

&lt;p&gt;When it comes to overlaying elements, using margins can be very handy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fjf3hkbs2y1inao4dhyxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fjf3hkbs2y1inao4dhyxw.png" alt="Container that overlaps its parent"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To achieve the layout from the previous image, we can apply a &lt;strong&gt;negative margin&lt;/strong&gt; to the child element (such as &lt;code&gt;margin-left: -120px&lt;/code&gt;), causing it to be displayed overlapped with its parent element.&lt;/p&gt;

&lt;p&gt;There are other alternatives, such as the &lt;code&gt;position&lt;/code&gt; property, which allows to position elements relative to another element. However, using this property may, among other things, cause the child element not to respect the parent's padding.&lt;/p&gt;

&lt;p&gt;In this case, using negative margins is much simpler and more straightforward.&lt;/p&gt;




&lt;p&gt;I hope you found this post interesting and that it helps you in your programming projects. The proposed alternatives are just one of the many options that CSS offers. In programming, there is not a single way to do things. In CSS, neither is there.&lt;/p&gt;

&lt;p&gt;If you have any questions or want to share any ideas, please leave a comment below.&lt;/p&gt;

&lt;p&gt;Thanks for your time!&lt;/p&gt;

</description>
      <category>css</category>
      <category>cleancode</category>
      <category>webdev</category>
      <category>react</category>
    </item>
  </channel>
</rss>
