<?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: Alex</title>
    <description>The latest articles on Forem by Alex (@buaiscia).</description>
    <link>https://forem.com/buaiscia</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%2F55331%2Fda92806b-00f9-4032-a9d1-cf5b7ee4514f.jpeg</url>
      <title>Forem: Alex</title>
      <link>https://forem.com/buaiscia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/buaiscia"/>
    <language>en</language>
    <item>
      <title>Printing Perfection, A Developer’s Journey with React-to-Print</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Mon, 15 Jan 2024 21:16:40 +0000</pubDate>
      <link>https://forem.com/buaiscia/printing-perfection-a-developers-journey-with-react-to-print-3eld</link>
      <guid>https://forem.com/buaiscia/printing-perfection-a-developers-journey-with-react-to-print-3eld</guid>
      <description>&lt;p&gt;Image by &lt;a href="https://pixabay.com/users/openclipart-vectors-30363/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=159336"&gt;OpenClipart-Vectors&lt;/a&gt; from &lt;a href="https://pixabay.com//?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=159336"&gt;Pixabay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a requisite for a commercial application, sometimes it's needed to implement a printing solution that is not the browser's default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the browser print API is limited
&lt;/h2&gt;

&lt;p&gt;While we are accustomed to using CTRL/CMD + P to print a page, we know as a fact that often the layout that is presented is not ideal. Especially if we are using other UI libraries that are injecting their components with their hidden styles.&lt;br&gt;
There can be elements out of order, fonts changing size, and so on.&lt;/p&gt;

&lt;p&gt;One solution that many of us have tried is just to save the pages as PDFs and print them instead. While this method sometimes worked, we wanted to provide an effective solution to our clients so that all the important data would be visible, clear, and organized on the layout of the printed page.&lt;/p&gt;
&lt;h2&gt;
  
  
  The search
&lt;/h2&gt;

&lt;p&gt;I checked various libraries but eventually, my eye fell on the one called "react-to-print".&lt;/p&gt;

&lt;p&gt;I'll be writing shortly about why I chose it, so it could maybe helpful to other developers who are starting their journey and would like to know how a new library is chosen for a work project. Compared to other libraries, it was a solution that, first of all, was not designed to create a PDF and then print it, but to use the native browser print API and it is just built on top of that.&lt;/p&gt;

&lt;p&gt;Secondly, the number of weekly downloads (400.000) and how many people were already using it from Github (30.5k) helped me move forward in this direction. The library is pretty weightless, just 51kB. It is just one Javascript file. The rest are Typescript definitions and other add-ons.&lt;/p&gt;

&lt;p&gt;Why wouldn't we do it ourselves, then?&lt;/p&gt;

&lt;p&gt;First of all, no need to reinvent the wheel and lose time when you have a timeline of features to follow for the clients.&lt;/p&gt;

&lt;p&gt;Secondly, the library has been so far maintained by 35 people and has multiple versions published in the year. Which is much more of what we could do, even sparing hours every week on it. Lastly, it is Typescript first, so it's easier to use and safer to use it correctly.&lt;/p&gt;
&lt;h2&gt;
  
  
  POC
&lt;/h2&gt;

&lt;p&gt;Before finishing the analysis, I did a proof of concept (POC). I opened a new branch and tried to implement it in a very rough way, just to see that nothing was breaking and it was working on the base concept.&lt;/p&gt;

&lt;p&gt;It was a little hard as the documentation is not so straightforward, especially as it highlights the usage of React's old class components, and there are just two examples with functional components.&lt;/p&gt;

&lt;p&gt;However, thanks to some other kind soul who posted some solution on its usage (which was different than what the documentation suggested) I could make it work, and show a good printing layout with a small print button.&lt;/p&gt;
&lt;h2&gt;
  
  
  Work in progress
&lt;/h2&gt;

&lt;p&gt;Our business analysts, then, prepared the specifications and assigned them to new ticket stories. After having been refining them, on the next Sprint, I took charge of them, as I already knew part of the job.&lt;/p&gt;

&lt;p&gt;Of course, it didn't come as easy as the POC. There were multiple requirements in the specs and lots of nuances that had to be checked. Also, lots of bugs in styling the printing layout. First of all, I had to add the CSS query for hiding elements on print. Normally it would be a new class like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.print&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="nb"&gt;none&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;Luckily we are using Tailwind, and the utility for this is simply to add: print:hidden to the components or divs we want.&lt;/p&gt;

&lt;p&gt;The first issue I came across was the usage of components of the library. As the POC worked fine, I started implementing it with the component. After struggling with it for some time, I realized that because I needed not only the component where was, but I also needed the reference in a child component, this couldn't be used.&lt;/p&gt;

&lt;p&gt;I figured then that I had to use the custom hook provided by the library, as the hook result could be passed as a prop and used elsewhere. Also, the hook provided a way to implement various custom options more easily. The main way on how to do it is this:&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;const&lt;/span&gt; &lt;span class="nx"&gt;handlePrint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useReactToPrint&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;content&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="nx"&gt;componentToPrintRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HandlePrint is a function, so it can be called anywhere you want that action. It can be passed to other components as prop to call the print action from somewhere else. The component that will be printed is inside the componentToPrintRef reference. So you can wrap it in a very simple 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;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;componentToPrintRef&lt;/span&gt;&lt;span class="p"&gt;}&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;Components&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="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;Then, you can add wherever you wish a button or link to call handlePrint. That's the basics, and on a simple page, it works nicely out of the box. However, I had to add a few things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Handle keys. We wanted the print happening not only with the button(s) but also on CTRL/CMD + P keys, as it happens with the browser.&lt;/li&gt;
&lt;li&gt; Hide not only CSS elements but also checkboxes and other elements depending on the state.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To make the first feature happen, I added the event listeners. A function taking the event as a parameter and, if the keys combination was of the aforementioned, calls handlePrint(). Then, a useEffect would be this simple 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="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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&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;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far, it's something pretty regular. However, when it came to the second point, things got a little more complex. The most immediate solution was to create a state for printing using useState.&lt;/p&gt;

&lt;p&gt;Then, somehow, setting it inside the print hook. ReactToPrint offers some methods to handle that inside the customHook. One is onBeforeGetContent to create a custom layout set before taking the actual CSS and HTML elements. The easier way was a function, as it is a function, to set the isPrinting boolean to true. Then pass isPrinting to the various components to hide the needed elements and not show them on the print layout.&lt;/p&gt;

&lt;p&gt;However, that wasn't working normally. Sometimes the components were hidden, sometimes not. It probably meant that the state was not synced or waited for. After some research, and thanks to the people who wrote examples also in the library GitHub Issues section, I saw that onBeforeGetContent was expecting a Promise. The issue above then made sense. The change of state was not waited as there was no callback to let it wait.&lt;/p&gt;

&lt;p&gt;Adding a new Promise() with parameters of resolve and value, I could then call setIsPrinting to true, and then resolve the value. On exit of the layout, instead, I used the method onAfterPrint, which was simple enough to just set setIsPrinting to false to get back the hidden components.&lt;/p&gt;

&lt;p&gt;Now, another issue came out. Whenever I was clicking on Cancel or Print on the browser print layout, the dialog was closing. But if I tried to print again, the layout was all scrambled, making it as if the library was not there at all and it was using the default from the browser. After some thinking, I realized that it wouldn't happen if I interacted with the page elements between two prints.&lt;/p&gt;

&lt;p&gt;So it must have been that, for some reason, without clicking on the page the library methods were temporarily removed. The solution was to focus on the page after exiting the print layout. As the element of reference is an HTML element, we can use that in the onAfterPrint method: componentToPrintRef?.current?.focus()&lt;br&gt;
However, it was not focusing!&lt;/p&gt;

&lt;p&gt;Why? It's because the focusable elements are only form elements, like input, select, and button. Or link tags with an href element. But the main point is the tabIndex attribute.&lt;br&gt;
It is indeed that which is causing the element to be focused. So I added it to the print reference div: &lt;code&gt;&amp;lt;div ref={componentToPrintRef} tabIndex={-1}&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Why -1 instead of 0? 0 makes the element focusable and adds it to the natural tab order of the page. But the page has already sections and headers and items that are possible to navigate with the keyboard, so it would create issues. -1, instead, makes the element focusable, but it removes the element from the natural tab order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In the ever-evolving world of web development, finding effective solutions to seemingly simple tasks, like printing, can often be a challenge.&lt;/p&gt;

&lt;p&gt;I have tried here to go through the process of implementing a robust printing solution using the “react-to-print” library. It focuses on utilizing the native browser print API, which has proven to be an effective solution, despite the hurdles along the way.&lt;/p&gt;

&lt;p&gt;This journey underscores the importance of continuous learning, problem-solving, and the power of community in the field of web development.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Handle Scroll Events in React</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Wed, 25 Oct 2023 06:08:00 +0000</pubDate>
      <link>https://forem.com/buaiscia/how-to-handle-scroll-events-in-react-10b5</link>
      <guid>https://forem.com/buaiscia/how-to-handle-scroll-events-in-react-10b5</guid>
      <description>&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@taypaigey?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Taylor Flowe&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/brown-wooden-rolling-pin-on-white-textile-ZHY7-YaGG2U?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll explore how to handle scroll events in a React application. We’ll focus on an issue developers could face: synchronizing state with the scroll position.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Imagine you’re building a complex UI with multiple sections, and you want to highlight the navigation link of the section currently visible in the viewport. Not only that, you would like to be able to click on the sections and scroll to the corresponding one. You might think of using a scroll event listener that checks the scroll position and updates the state accordingly.&lt;/p&gt;

&lt;p&gt;However, you may encounter an issue where your state updates continuously, causing unnecessary re-renders and performance issues.&lt;br&gt;
Unfortunately, the only browser API for it, called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/scrollend_event"&gt;scrollend event&lt;/a&gt;, is not compatible and implemented in Safari, nor in iOS, Samsung or Opera browsers, so it can't be really used on a large scale. &lt;/p&gt;
&lt;h2&gt;
  
  
  The Solution: Debouncing
&lt;/h2&gt;

&lt;p&gt;To solve this problem, we can use a technique called debouncing. Debouncing is a programming practice used to ensure that time-consuming tasks do not fire so often. This can be particularly useful for rate limiting execution of handlers on events that will trigger requests.&lt;/p&gt;

&lt;p&gt;Here’s how you could implement a debounce function in TypeScript, in a very abstract method:&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="nx"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NodeJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Timeout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;executedFunction&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;later&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="nx"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;later&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;wait&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;This debounce function takes two arguments: func, the function you want to debounce, and wait, the number of milliseconds to delay before executing the function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking if an Element is in the Viewport
&lt;/h2&gt;

&lt;p&gt;To determine which section is currently visible in the viewport, we can use a helper function:&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="nx"&gt;isElementInViewport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&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;rect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getBoundingClientRect&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;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bottom&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHeight&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientWidth&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;This function takes a DOM element as an argument and uses the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect"&gt;getBoundingClientRect&lt;/a&gt; method to get its position relative to the viewport. It then checks if the entire element (from top to bottom and left to right) is within the viewport dimensions. If it is, the function returns true; otherwise, it returns false.&lt;/p&gt;

&lt;p&gt;We can use this function in our scroll event listener to check if each section is in the viewport and update our selected state accordingly.&lt;/p&gt;

&lt;p&gt;By combining these techniques, we can create a dynamic navigation system that responds to both user interactions and scroll events, providing a smooth and intuitive user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying Debouncing to Scroll Event Listener
&lt;/h2&gt;

&lt;p&gt;We can apply our debounce function to the scroll event listener in our React component:&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;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;debounce&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;isScrolling&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;sections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.section&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;sections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;section&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;isElementInViewport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;setSelected&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;section&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="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Adjust this value as needed&lt;/span&gt;

  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&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;isScrolling&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code snippet, we’re adding a scroll event listener that fires our debounced function. This function checks if we’re currently scrolling and if not, it checks each section (through a class name to be applied) to see if it’s in the viewport. If it is, it sets the selected state to the ID of that section.&lt;/p&gt;

&lt;p&gt;By using debouncing, we ensure that our event handler doesn’t fire too often and cause performance issues. Instead, it waits until a certain amount of time has passed without the event being fired before executing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling Click Events
&lt;/h2&gt;

&lt;p&gt;In our React component, we may want to handle click events that trigger scrolling to a specific section. Here’s how we can do it:&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;const&lt;/span&gt; &lt;span class="nx"&gt;handleOnClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&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="kr"&gt;any&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;setIsScrolling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollIntoView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;smooth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="nx"&gt;setTimeout&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;setIsScrolling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;setSelected&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;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;500&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;In this function, we’re first setting isScrolling to true. Then, we’re getting the DOM element with the ID equal to the clicked value. If such an element exists, we’re using the scrollIntoView method to smoothly scroll to that element.&lt;/p&gt;

&lt;p&gt;After a timeout of 500ms (to allow for the scrolling animation to finish), we’re setting isScrolling back to false and updating our selected state to the ID of the clicked section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplifying debouncing
&lt;/h2&gt;

&lt;p&gt;It is even possible to use directly the setTimeout browser API directly, instead of making a function about debouncing. The effect, pardon the pun, will be the same, but the code simpler, if you don't need to reuse it. Otherwise, the debounce function, or even import lodash debounce, will do.&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;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="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NodeJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Timeout&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setTimeout&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;isScrolling&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;sections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.section&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;sections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;section&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;isElementInViewport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;setSelected&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;section&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="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// set to what is your need; can be lower than the handle on click for it doesn't need too much waiting&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&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;isScrolling&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Handling scroll events in React can be tricky due to the asynchronous nature of JavaScript and the way React batches state updates. However, with techniques like debouncing, we can efficiently handle these events and create smooth, responsive user interfaces.&lt;br&gt;
When we have to use two different listeners to take action on our DOM, they can interfere with each other. That's why we need to create some workaround to wait for the changes to happen.&lt;/p&gt;

&lt;p&gt;Remember to always remove event listeners when they’re no longer needed to prevent memory leaks and potential performance issues.&lt;br&gt;
If you have other ways of handling scroll events in such cases, please share them!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Testing the styles of DOM elements with React Testing Library</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Thu, 16 Feb 2023 15:49:01 +0000</pubDate>
      <link>https://forem.com/buaiscia/testing-the-styles-of-dom-elements-with-react-testing-library-3kk</link>
      <guid>https://forem.com/buaiscia/testing-the-styles-of-dom-elements-with-react-testing-library-3kk</guid>
      <description>&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@ro_ka?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Robert Katzki&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/jbtfM0XBeRc?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes -or often, depending on the case- we need to test some particular style that can change depending on some property.&lt;br&gt;
The way this is implemented depends on the library we use for the styling.&lt;/p&gt;

&lt;p&gt;Supposing that we have some text, inside a component, that depending on the prop it's white or black.&lt;br&gt;
In the DOM, it will reflect this way. However, especially as it's not a fixed element, we should test how it behaves on different pages.&lt;/p&gt;

&lt;p&gt;The test itself using React Testing Library is very simple because it checks directly the DOM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;render&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;MyComponent&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;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text in the page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveStyle&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#FFFFF&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The library converts the colour in hex code against RGB, so if they match, the test will pass; otherwise, it will return the returned RGB colour (i.e. 0,0,0) and the expected one (i.e. 255,255,255). With it, it's very easy to spot the mistake, or why a test is failing.&lt;/p&gt;

&lt;p&gt;We can also test directly the prop that we're passing and the consequent change of colour in the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rerender&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;render&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;MyComponent&lt;/span&gt; &lt;span class="nx"&gt;changingProp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text in the page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toHaveStyle&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#FFFFF&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nf"&gt;rerender&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;MyComponent&lt;/span&gt; &lt;span class="nx"&gt;changingProp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;black&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text in the page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toHaveStyle&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#00000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have to notice here that I had to call screen.getByText twice, because that function is returning immediately the DOM element. If I would set it as before in a variable, at the moment of checking 'text' the second time, it would have stored the previous DOM element and not the updated one.&lt;/p&gt;

&lt;p&gt;Thank you for reading! Let's connect on &lt;a href="https://twitter.com/AlexBuaiscia" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>uiux</category>
      <category>tooling</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Removing Default React Imports. For a Cleaner Code</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Tue, 14 Feb 2023 08:44:37 +0000</pubDate>
      <link>https://forem.com/buaiscia/removing-default-react-imports-for-a-cleaner-code-26kc</link>
      <guid>https://forem.com/buaiscia/removing-default-react-imports-for-a-cleaner-code-26kc</guid>
      <description>&lt;p&gt;&lt;em&gt;Photo by Liliana Drew: &lt;a href="https://www.pexels.com/photo/a-person-vacuuming-under-a-side-cabinet-9462147/"&gt;https://www.pexels.com/photo/a-person-vacuuming-under-a-side-cabinet-9462147/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you are one of the many people migrating their projects to React 18, maybe you skipped one great feature for your code coming along from the previous version (17): you can remove all default React imports! &lt;br&gt;
To be precise, it was present also in some previous React versions, but it was always somehow hidden from the general public (or maybe just me?). &lt;/p&gt;

&lt;p&gt;We were accustomed to the need of importing React in every. single. file.&lt;br&gt;
And maybe you are still doing it after the migration. I did it, indeed, for a while :D&lt;/p&gt;

&lt;p&gt;That is because this possibility is in the docs, but on a side note with an enigmatic title: &lt;a href="https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#removing-unused-react-imports"&gt;"Introducing the new JSX transform"&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In substance, it creates React as a global so it does not need to import it everywhere. How does it work? &lt;br&gt;
It is quite simple. Instead of having:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&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="nx"&gt;useEffect&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can have the normal destructured import without the need to import the whole library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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;useState&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or skip it entirely if you don't need any hook.&lt;/p&gt;

&lt;p&gt;Also, instead of removing all those imports manually, React offers an automated script that will make everything for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx react-codemod update-react-imports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just be careful to have all your work committed, as it will create changes probably on almost every file of your repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about linting?
&lt;/h2&gt;

&lt;p&gt;There was another small problem. Eslint was complaining if one was removing React from a file, saying it was not a UMD global. &lt;/p&gt;

&lt;p&gt;The missing piece is on this page, in a small note at the end of the page: &lt;a href="https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md"&gt;the eslint rule to disallow missing React when using JSX.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the bottom, there is a paragraph. If you are using the new JSX transform from React 17, you should disable this rule, adding "plugin:react/jsx-runtime" to "extends" in the eslint config file.&lt;/p&gt;

&lt;p&gt;Now everything will work as expected and you will have a much cleaner codebase!&lt;/p&gt;

&lt;p&gt;Thank you for reading! Let's connect on &lt;a href="https://twitter.com/AlexBuaiscia"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Fixing Material UI and Emotion's handling of Transient Options</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Tue, 31 Jan 2023 16:01:58 +0000</pubDate>
      <link>https://forem.com/buaiscia/fixing-material-ui-and-emotions-handling-of-transient-options-5clb</link>
      <guid>https://forem.com/buaiscia/fixing-material-ui-and-emotions-handling-of-transient-options-5clb</guid>
      <description>&lt;h2&gt;
  
  
  Passing Props to custom Emotion styles with Material UI
&lt;/h2&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@amandavickcreative?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Amanda Vick&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/zw_oaDbfzyE?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recently I encountered an issue with the Material UI that I couldn't wrap my head around. What was happening?&lt;/p&gt;

&lt;p&gt;Modern libraries for managing custom CSS, like Styled Components or Emotion, have accustomed us developers to the possibility to use styled elements as real, reusable components. They can even extend other styles or other components. CSS becomes building blocks like React, and that's just great.&lt;/p&gt;

&lt;p&gt;Using Material UI means using Emotion. It works similarly to Styled Components, although the syntax is slightly different. One of the advantages of using these libraries with React is that you can pass them props and you can change the style according to their values.&lt;/p&gt;

&lt;p&gt;However, it turns out that Emotion with Material UI lacks proper handling of this feature (as of now at least), which is called transient options. So if you pass a boolean value as a prop and use it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// component&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyStyledBox&lt;/span&gt; &lt;span class="nx"&gt;isdarktheme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
  &lt;span class="c1"&gt;// style file&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;Box&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;@mui/material&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyStyledBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;
    &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;isdarktheme&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="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;isdarktheme&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;black&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;React will throw a warning saying: 'Received &lt;code&gt;true&lt;/code&gt; for non-boolean attribute &lt;code&gt;isdarktheme&lt;/code&gt;'. It will work, but the warning will stay.&lt;/p&gt;

&lt;p&gt;How to fix it? I found that there's an issue opened with Emotion about this, and here's &lt;a href="https://github.com/emotion-js/emotion/issues/2193#issuecomment-766173118" rel="noopener noreferrer"&gt;the best working workaround answer.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So here's how I followed it and implemented it. In one util file, I added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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;transientOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Parameters&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CreateStyled&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;shouldForwardProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;propName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;propName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This identifies the props starting with $ as transientOptions through the React hook shouldForwardProp. As the name says, it will allow the prop to be passed.&lt;/p&gt;

&lt;p&gt;Then I can import the method and use it as an option for the emotion component. Here's with TS:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;transientOptions&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;utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;$isdarktheme&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyStyledBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transientOptions&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;Props&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;theme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$isdarktheme&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="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$isdarktheme&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The warning disappeared and the prop is correctly taken by Emotion.&lt;/p&gt;

&lt;p&gt;Thank you for reading! Let's connect on &lt;a href="https://twitter.com/AlexBuaiscia" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="//@alex_@uiuxdev.social"&gt;Mastodon&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>crypto</category>
      <category>blockchain</category>
      <category>web3</category>
      <category>offers</category>
    </item>
    <item>
      <title>Reduce your Jest tests running time (especially on hooks!) with the maxWorkers option</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Thu, 08 Dec 2022 15:52:29 +0000</pubDate>
      <link>https://forem.com/buaiscia/reduce-your-jest-tests-running-time-especially-on-hooks-with-the-maxworkers-option-4dhh</link>
      <guid>https://forem.com/buaiscia/reduce-your-jest-tests-running-time-especially-on-hooks-with-the-maxworkers-option-4dhh</guid>
      <description>&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@josholalde?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Josh Olalde&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/workers?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Many applications have hundreds (and sometimes thousands!) of tests. Sometimes those tests are run only manually; more often they're attached to some hook. For example, we can use 'husky' to run some action before the commit or the push. In my case, lint and prettier before the commit and tests before the push.&lt;br&gt;
Or the tests can be run during some actions on a CI/CD tool.&lt;/p&gt;

&lt;p&gt;I'm with a MacBook Pro 2020, and I've got around 170 unit and integration tests running on a frontend application. That means that at least half of it needs rendering the components many times - hence consuming much memory and CPU.&lt;/p&gt;

&lt;p&gt;When I run my tests manually, they usually are pretty fast, around 1 minute and some seconds of execution time.&lt;br&gt;
However, I found that when I'm pushing the code to our repository, many times the test suites fail on timeout. They exceed the default time limit of 5 seconds.&lt;/p&gt;

&lt;p&gt;Of course, this limit can be increased. But if 5 seconds is not enough for running a test, there's something wrong!&lt;/p&gt;

&lt;p&gt;Now, although Jest runs with Javascript (which is single-threaded), it uses workers to divide the workload among many Jest processes, imitating multi-threading.&lt;br&gt;
Jest calculates -on many factors- how many workers can activate and runs them. In my case, there were around 8. When I was running them continuously, my laptop fan started running as if it was going to melt.&lt;/p&gt;

&lt;p&gt;CPU got slower with the heating up and tests were starting to timeout because there was no more computational power to let them run properly.&lt;/p&gt;

&lt;p&gt;Luckily, Jest let us customize this option with --maxWorkers.&lt;br&gt;
On my CRA (Create React App) I added this option cutting in half the workers to the test command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"test": "react-scripts test --maxWorkers=50%"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets just 4 workers be spun and let the tests pass without timeout issues. Their execution was anyway fairly quick, and it prevented me from any more trouble! &lt;br&gt;
Of course, the option can be set even lower (or higher). It depends on many factors, so you can try and test yourself (pun intended)!&lt;/p&gt;

&lt;p&gt;Thank you for reading! Let's connect on &lt;a href="https://twitter.com/AlexBuaiscia" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="//@alex_@uiuxdev.social"&gt;Mastodon&lt;/a&gt;! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>design</category>
    </item>
    <item>
      <title>Finding a bug after writing a test, an example</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Wed, 30 Nov 2022 15:56:04 +0000</pubDate>
      <link>https://forem.com/buaiscia/finding-a-bug-after-writing-a-test-an-example-em4</link>
      <guid>https://forem.com/buaiscia/finding-a-bug-after-writing-a-test-an-example-em4</guid>
      <description>&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@alanemery?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Alan Emery&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/code-bug?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In almost every Sprint, at work, I try to reserve some space for solving tech debt and doing some refactoring. A part of resolving this debt is making integration tests. And sometimes it happens that those tests find some unknown bug. That's what happened a few days ago. As usual, the names of the methods and variables are just an example.&lt;/p&gt;

&lt;p&gt;The page I was writing the tests on is a simple one. Some text, three buttons, and nothing more. Yet, it has some hooks as well, defining the logic of those buttons (opening another URL, submitting the form, etc).&lt;/p&gt;

&lt;p&gt;I started writing the tests in the usual way, using React Testing Library. Checking the rendering and the behavior of the page by clicking on the different buttons. When I was writing the test for one of the three buttons, however, it forced me to let me think: is this button always visible? Why?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showButton&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;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;onApplyClick&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;DO&lt;/span&gt; &lt;span class="nx"&gt;THING&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;I checked the hooks and found out that it would render only when another property was true, or present. So why it was always there?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;showButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;secondaryProp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I followed the source of that property and I came across the point where its data was fetched from the (easy-peasy) store, and then it was set as an initial value of 0, instead of being undefined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IState&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="na"&gt;secondaryProp&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The type of that property was just "number", instead of "number?". So it was always true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;secondaryProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To fix it, I changed the type and set the initial values as undefined. &lt;/p&gt;

&lt;p&gt;Re-checking that property I saw that another value was dependent on it being present or not. So in another hook, I had to redefine the behavior in case the prop was falsy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;secondaryProp&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;FETCHED_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/prop=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;secondaryProp&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

&lt;span class="kd"&gt;const&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="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;newUrl&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newUrl&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;So that's an interesting case of how making tests helps you reflect on what the behavior, and the logic of the methods and components, should be.&lt;/p&gt;

&lt;p&gt;Thank you for reading! Let's connect on &lt;a href="https://twitter.com/AlexBuaiscia" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="//@alex_@uiuxdev.social"&gt;Mastodon&lt;/a&gt;! &lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Make a reusable test with React Testing Library</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Tue, 22 Nov 2022 19:34:42 +0000</pubDate>
      <link>https://forem.com/buaiscia/make-a-reusable-test-with-react-testing-library-272m</link>
      <guid>https://forem.com/buaiscia/make-a-reusable-test-with-react-testing-library-272m</guid>
      <description>&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@sigmund?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Sigmund&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/recycle?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It can happen to have very similar tests across our suites. In one of my recent examples, I had to test if the UI of the footer of the pages in the application was correctly rendered, depending on a prop change.&lt;/p&gt;

&lt;p&gt;The footer consists only of a box with inside an SVG icon and a text. But those are white when we have a dark background, and  dark gray when the background is white.&lt;/p&gt;

&lt;p&gt;The logic is already in place, and the simple test steps would be: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;render the page (component)&lt;/li&gt;
&lt;li&gt;get the elements to check&lt;/li&gt;
&lt;li&gt;check that the elements have the correct style.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next -and boring- step would be placing this test inside each page test suite, and check for the color individually.&lt;/p&gt;

&lt;p&gt;Instead, we can make a reusable test, like a normal function.&lt;br&gt;
We can put it in some shared.js file so it can be picked up anytime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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;screen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;waitFor&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;@testing-library/react&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;testPageFooterWithColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;renderPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expectedColor&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;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;it checks that the footer is present and has the correct color&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&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;renderPage&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;footerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;our footer text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitFor&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;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;footerText&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;footerText&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveStyle&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;expectedColor&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="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;testPageFooterWithColor&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can import it in our suites:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderCustomPage&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="nx"&gt;render&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;CustomPage&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="na"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MemoryRouter&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;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;our test suite&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="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="nx"&gt;our&lt;/span&gt; &lt;span class="nx"&gt;tests&lt;/span&gt;

    &lt;span class="nx"&gt;testPageFooterWithColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;renderCustomPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thank you for reading! Let's connect on &lt;a href="https://twitter.com/AlexBuaiscia"&gt;Twitter&lt;/a&gt; or &lt;a href="//@alex_@uiuxdev.social"&gt;Mastodon&lt;/a&gt;! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Making reusable get methods in React Testing Library</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Wed, 16 Nov 2022 15:47:37 +0000</pubDate>
      <link>https://forem.com/buaiscia/making-reusable-get-methods-in-react-testing-library-1ag5</link>
      <guid>https://forem.com/buaiscia/making-reusable-get-methods-in-react-testing-library-1ag5</guid>
      <description>&lt;h3&gt;
  
  
  Creating some abstractions to have ready to use getter functions
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@mohamadaz?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;A.Z&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/abstract?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While writing unit and integration tests, I'm trying to find the best way on how to write them cleanly.&lt;br&gt;
I'm using React Testing Library so that makes already a good job of using good patterns.&lt;br&gt;
However, recently I stumbled upon the fact that I'm reusing again and again the same methods to get the elements from the DOM.&lt;/p&gt;

&lt;p&gt;The majority of cases are using &lt;code&gt;screen.getByRole&lt;/code&gt; for the buttons and &lt;code&gt;screen.getByLabelText&lt;/code&gt; for the inputs, using the name prop. The only difference would be the first returing the element, and the latter returning the value of the input. Normally, I would use the first one this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/name of the button/i&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I like to use the names without having to think about capitalization of some letter, I use the parameter 'i' with Regex in order to ignore this case. Also, being with Regex, I don't have to worry whether it's a full sentence or just a part of it.&lt;/p&gt;

&lt;p&gt;So, I thought I could extract these methods in a more reusable way, in order to use them freely around the test suites.&lt;/p&gt;

&lt;p&gt;Here's how I did it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getButtonByName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btnName&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;regName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btnName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i&lt;/span&gt;&lt;span class="dl"&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;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;regName&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;getInputByLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;label&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;regName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i&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="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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByLabelText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regName&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;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I can easily use them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getButtonByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my button&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;inputValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getInputByLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my input label&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I made another method in a similar way for radio buttons. More could be done but these are the three methods I use the most. So for the rest, it could be a little of over-abstraction.&lt;/p&gt;

&lt;p&gt;Another improvement that can be done, in my opinion, would be change the strings of the names ('my button', etc.) with fixed objects (JS) or enums (TS). For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JS&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ButtonNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;ButtonOne&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button one&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;ButtonTwo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button two&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="nx"&gt;TS&lt;/span&gt;

&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;ButtonNames&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ButtonOne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button one&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;ButtonTwo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;



&lt;p&gt;Thank you for reading and let's connect on &lt;a href="https://twitter.com/AlexBuaiscia"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>testing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Memoize a React component</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Thu, 25 Aug 2022 12:29:29 +0000</pubDate>
      <link>https://forem.com/buaiscia/memoize-a-react-component-58lc</link>
      <guid>https://forem.com/buaiscia/memoize-a-react-component-58lc</guid>
      <description>&lt;p&gt;Memoization is a feature in React. The library compares (in a shallow way) two versions of an object and, if they are the same, does not re-render (or recompile) it, creating an optimization in performance and memory.&lt;/p&gt;

&lt;p&gt;The React.memo higher order component (to notice, not useMemo) used on a component is very easy to implement, but it's not always efficient or necessary. As everything about memoization in React, we shouldn't memoize everything but just the objects that are heavy, big, or re-renders very often.&lt;/p&gt;

&lt;p&gt;So in my job it happened  an interesting case. I had quite a big parent component that is wrapping inside smaller children components. I'll just change the type of subjects and component name, but the example I'm giving is the same I have.&lt;/p&gt;

&lt;p&gt;How do we memoize a component?&lt;/p&gt;

&lt;p&gt;Supposing we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BigComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;lots&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;props&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;lots&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;stuff&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then we just put memo on the export&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BigComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is it enough? Sometimes yes. But the more interesting part is another. How does React knows what to compare? It takes a previous version, and a next version (the one we're updating with new props). In the same way, memo could use those two version as callback arguments. They can be checked to make a quicker comparison, speeding up even more the memoization process.&lt;/p&gt;

&lt;p&gt;Supposing that our BigComponent is mostly managing a school student card, and we have the children components showing according to the student. Then we'll have BigComponent supposedly changing when the id of the student change (supposing that is mapped from a parent component).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BigComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;student&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;other&lt;/span&gt; &lt;span class="nx"&gt;props&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;lots&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;stuff&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now memoize the component comparing the IDs of the student. We can think of the IDs as the keys of the object. If they're the same, the component will remain the same, otherwise it will re-render.&lt;/p&gt;

&lt;p&gt;But as you can see, I've done it slightly differently!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BigComponent&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;next&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;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&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;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;student&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This above will say: if the previous ID is different comparing to the next one, return true. The problem here is that we're getting the props and we use them on a child component, so if the IDs are the same (===) it won't do anything (won't open the card). &lt;/p&gt;

&lt;p&gt;In my case, it checks that the IDs are different, and don't do anything. But if they're the same, it'll allow the rerender. It's similar to how ShouldComponentUpdate was working, as we're giving the condition on when to rerender.&lt;/p&gt;

&lt;p&gt;So, to sum up, we're memoizing (not rerendering) this component the opposite way only when the IDs (keys) change. That means that when we open a student card it will rerender. But when we add more students, or we use other student cards, they won't rerender in the page, and we will be getting a performance improvement.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>memoization</category>
    </item>
    <item>
      <title>Sending validation errors through a Formik form</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Fri, 05 Aug 2022 11:29:00 +0000</pubDate>
      <link>https://forem.com/buaiscia/sending-validation-errors-through-a-formik-form-18lb</link>
      <guid>https://forem.com/buaiscia/sending-validation-errors-through-a-formik-form-18lb</guid>
      <description>&lt;p&gt;When we need to validate a Formik form (often with Yup) we can use the following method: validateForm.&lt;br&gt;
It returns a promise so we have to check if it resolves or not.&lt;br&gt;
However, the validation errors are sent directly inside the promise as an argument and not caught. So the promise is always resolved in this case.&lt;/p&gt;

&lt;p&gt;To pass the validation error, then, we have to pass the errors as an argument of the promise itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;formik&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validateForm&lt;/span&gt;&lt;span class="p"&gt;({...})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;errors&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;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formik&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the errors can be checked and the logic can be written in the submit method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;submit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formik&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errors&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bonus: here are the types (for TS users) for the 3 arguments above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;formik&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormikContextType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FormikValues&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormikValues&lt;/span&gt;
&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormikErrors&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FormikValues&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thank you for reading, and let's connect on &lt;a href="https://twitter.com/AlexBuaiscia"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Epic React: Hooks. UseState, useEffect. What I'm learning..</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Wed, 23 Mar 2022 15:11:07 +0000</pubDate>
      <link>https://forem.com/buaiscia/epic-react-hooks-usestate-useeffect-what-im-learning-1a5j</link>
      <guid>https://forem.com/buaiscia/epic-react-hooks-usestate-useeffect-what-im-learning-1a5j</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Back into Epic React&lt;/li&gt;
&lt;li&gt;1 - useState&lt;/li&gt;
&lt;li&gt;2 - useEffect&lt;/li&gt;
&lt;li&gt;Other notes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Back into Epic React
&lt;/h2&gt;

&lt;p&gt;After a long break and quite more experience, I managed to get back to EpicReact. This is the second chapter of the series. Here's the link to the first one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/buaiscia/epic-react-fundamentals-what-i-m-learning-3dh7"&gt;Epic React. Fundamentals. What I'm learning.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As in the other post, this isn't a guide to React nor to EpicReact. They are just my notes, thoughts and learning on the course workshops. Few things can appear as confusing for lack of context. However, I hope you can find some interesting points to reflect upon. Repositories and solutions are anyway publicly available on Kent's Github.&lt;/p&gt;

&lt;p&gt;Let's dive into hooks, with a focus on useState and useEffect!&lt;/p&gt;

&lt;h2&gt;
  
  
  1 - useState
&lt;/h2&gt;

&lt;p&gt;A first good point is: in controlled components value is changed/updated by the state and uncontrolled by event handlers.&lt;/p&gt;

&lt;p&gt;The interesting part of useState is how under the hood is nothing else but an array declaration. When it's used, it gets two elements of the array, in which the first is the variable and the second one is the function to update the variable.&lt;/p&gt;

&lt;p&gt;So a code like this:&lt;br&gt;
&lt;code&gt;const [ count, setCount ] = useState(0)&lt;/code&gt;&lt;br&gt;
would be, not destructured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;array&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="nx"&gt;setCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;array&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first exercise is quite simple if one understands React states well. Every time (unless different specified) the state changes, in any part of the component, there will be a re-render of the component virtual DOM, updating what appears on the page.&lt;br&gt;
If I call a function on the onChange in the input, and that function changes the state (&lt;code&gt;setCount(event.target.value)&lt;/code&gt;), then I can call the updated state in any part of the render&lt;br&gt;
&lt;code&gt;{count ? &amp;lt;strong&amp;gt;Count is {count}&amp;lt;/strong&amp;gt; : 'Add a number to count'}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the second part the task would be to use a prop in the component as initial value to pass&lt;br&gt;
&lt;code&gt;&amp;lt;Counting initialCount={0}&lt;/code&gt;&lt;br&gt;
I find there are different ways. The best way is to setState to that initial value that is destructured in the function arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Counting&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;initialCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Destructuring is necessary because initialCount is an object so, if we're passing the argument just like it (initialCount), the result will be [Object object].&lt;br&gt;
The default value (= '') is also necessary in case we don't pass anything as a prop. In this case we don't cause a crash because of undefined value (unless we use Typescript and we define it as possible undefined).&lt;br&gt;
So one way is to setState(initialCount) and value=count in the input.&lt;/p&gt;

&lt;p&gt;Another possible way is to set the defaultValue of the input to the initialCount. This will have the same effect except that the state of the rendered text won't be updated until something is typed. It's possible to create a check to use the count (like a nested if but with ternary operator). However, it will make the code more difficult to read and follow in its flow.&lt;/p&gt;
&lt;h2&gt;
  
  
  2 - useEffect
&lt;/h2&gt;

&lt;p&gt;This hook is called at every render of the component whenever its dependencies change. Or at any render if the dependency array is empty.&lt;/p&gt;

&lt;p&gt;We can persist the state: call the localstorage methods inside useEffect (getter and/or setter) &lt;code&gt;const [name, setName] = React.useState(window.localStorage.getItem('name') || initialName)&lt;/code&gt;&lt;br&gt;
However in doing so we can run into a performance issue. Access to localstorage is slower than other methods.&lt;/p&gt;

&lt;p&gt;There are some workarounds for this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React’s useState hook allows you to pass a function instead of the actual value, and then it will only call that function to get the state value when the component is rendered the first time: &lt;code&gt;React.useState(() =&amp;gt; someExpensiveComputation())&lt;/code&gt; ... that's the same as the callback on setState in class components
&lt;code&gt;const [name, setName] = React.useState(() =&amp;gt; window.localStorage.getItem('name') || initialName)&lt;/code&gt;
If we put a console inside the callback we cans see it's called only on the first render.
It should be used only for bottleneck functions that require sync time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or using useEffect: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lazy initialization, or not reading from localStorage at every render.&lt;/li&gt;
&lt;li&gt;dependency array: second argument on useEffect which signals to React that your effect callback function should be called when (and only when) those dependencies change:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;React&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&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;name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If other states apart from name change setItem won't be called&lt;br&gt;
If left empty, it'll be called only at the first render.&lt;br&gt;
The state in the dependency array is an object that is compared on the render with the previous state through object comparison. If they're the same useEffect won't run , otherwise yes.&lt;/p&gt;

&lt;p&gt;Custom hooks. They are external functions called inside a method. Their names start with ”use”.&lt;br&gt;
If we have different functions inside the component method we can externalize those, even useEffect:&lt;/p&gt;

&lt;p&gt;If we have a method like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Greeting&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;initialCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&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="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;initialCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;React&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&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;count&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can convert it to this and then use it in the main method as custom hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorageWithState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&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="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;initialCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;React&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&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;count&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Greeting&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;initialCount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorageWithState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Other notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Setting up a callback inside useState makes the setting of the state as lazy, as it compares the states and doesn't change it if it's the same.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you ar getting an error that goes like: 'React Hook ... is called in function ... which is neither a React function component or custom React Hook function', then it's possible that you put a wrong name to the custom hook.&lt;br&gt;
As a React convention, your function should start with 'use' and probably is not. For example, useGetItems.&lt;br&gt;
So, instead of syncLocalStorageWithState, we call it useLocalStorageWithState.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;useLocalStorageWithState should have the same use as the useState hook, so it can return an array like useState, and we can store it in a similar array. So we have created a custom useState hook that does other stuff as well.&lt;br&gt;
We pass as well count and initialCount as parameters &lt;code&gt;useLocalStorageWithState(count, initialCount)&lt;/code&gt; and then making useLocalStorageWithState more generic, receiving as arguments &lt;code&gt;key, defaultValue&lt;/code&gt; , so the method can be reused freely and not stay chained to a count state. The same applies to the state. We can set [state, setState] and return the same.&lt;br&gt;
Having two arguments means that also useEffect should have two in the dependency array.&lt;/p&gt;

&lt;p&gt;The logic of the flexible localStorage hook is the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get the item from local storage&lt;/li&gt;
&lt;li&gt;if present, JSON parse it and return the result&lt;/li&gt;
&lt;li&gt;if not, return the default value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's for getting the state. For setting the changes using useEffect -in this case for creating/editing the local storage- se can move forward like this: once the state changes we can just stringify whatever the state will be and store it.&lt;br&gt;
Serialize will be for stringify the JSON, while deserialize for parsing it.&lt;/p&gt;

&lt;p&gt;In case as argument of useLocalStorageWithState, instead of a number, we'll pass a function, it's possible to create a check to return the results of another function.&lt;br&gt;
&lt;code&gt;const [name, setName] = useLocalStorageWithState('name', complexCounting() )&lt;/code&gt; --&amp;gt; pass a function as default value&lt;br&gt;
&lt;code&gt;return typeof defaultValue === 'function' ? defaultValue() : defaultValue;&lt;/code&gt; --&amp;gt; return to useState the result of the method&lt;/p&gt;

&lt;p&gt;Then it comes the complicated part. &lt;br&gt;
In the above case, we are passing two parameters to useLocalStorageWithState. The first one -the key- is a string and the second a primitive value or a method.&lt;br&gt;
What if somebody wants to pass another value to the 'key'? Now, for example, can be passed 'count' as string, but maybe somebody will want to pass something different (to store a different thing in local storage, for instance).&lt;/p&gt;

&lt;p&gt;There's no direct way to change the state of the key, so what could be done is storing the key into a variable that won't trigger the render, using useRef. Following that, in useEffect we can compare the old key with the new one.&lt;/p&gt;

&lt;p&gt;According to the docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.&lt;br&gt;
Note that useRef() is useful for more than the ref attribute. It’s handy for keeping any mutable value around similar to how you’d use instance fields in classes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The difference with useState is then that useRef doesn't trigger a rerender, so with this hook we can actually set the key without triggering the rerender. The purpose of this is clear in the useEffect&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prevKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;prevKeyRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevKey&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevKey&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;Usually we store in localStorage a value. But this value is in an object, and that object has a key. So for now it's 'count'. But if it will be 'sum', and we don't remove the initial key, we'll have two objects in localStorage. So if the new key and the old one, which is stored in the useRef var, is different, we will remove the object in localStorage with the old key.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
