<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by austin on Medium]]></title>
        <description><![CDATA[Stories by austin on Medium]]></description>
        <link>https://medium.com/@austinrt?source=rss-e5ab5bafb583------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*0qrwfbpCmyasf13uSRHCJw.png</url>
            <title>Stories by austin on Medium</title>
            <link>https://medium.com/@austinrt?source=rss-e5ab5bafb583------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 29 May 2026 17:51:43 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@austinrt/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Demystifying React Hooks — useReducer]]></title>
            <link>https://austinrt.medium.com/demystifying-react-hooks-usereducer-4efd32edc084?source=rss-e5ab5bafb583------2</link>
            <guid isPermaLink="false">https://medium.com/p/4efd32edc084</guid>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[austin]]></dc:creator>
            <pubDate>Thu, 02 Feb 2023 01:49:37 GMT</pubDate>
            <atom:updated>2023-02-02T04:39:10.015Z</atom:updated>
            <content:encoded><![CDATA[<p>In this article, we will explore when and how to use React’s useReducer hook and how it relates to the useState Hook.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*weVb29CEYejRkozvuVAoeA.png" /></figure><p>If you’d like to clone this down and run it locally, you can find the repo <a href="https://github.com/austin-rt/useReducer/">here</a></p><h3>Getting Started</h3><ul><li>fork and clone</li><li>cd client</li><li>npm i</li><li>npm start</li></ul><h3>useReducer</h3><p>The intended use case for useReducer is to manage complex state logic by taking advantage of the <a href="https://medium.com/edge-coders/the-difference-between-flux-and-redux-71d31b118c1">Flux</a>/<a href="https://redux.js.org/introduction/getting-started">Redux</a> pattern. And if you don&#39;t know Redux, don&#39;t worry. In my opinion, useReducer is the perfect place to start learning Redux.</p><h3>Why Bother?</h3><p>Imagine we wanted to pass down all three states for our user to alter them from inside a child component. We’d have to pass <strong>six</strong> different values: each state <strong>and</strong> its setter. useReducer can simplify our code by <strong>reducing</strong> all of our state logic into a single function, aptly named a reducer. Reducers allow us to pass <strong>predetermined</strong> actions to our state updater to avoid unintentional state updates. We can even bake in custom error handling to make debugging easier. Think of it as hand-rolling type-checking for your state. Kind of... But we&#39;re not going down that rabbit hole today.</p><h3>Starter Code</h3><p>As always, let’s start with a brief overview of the codebase before we refactor.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/891/1*jOp6v807Gqbwn3plM9QdmA.gif" /></figure><p>App.js has three sections: a counter, a theme changer, and a text input, all of which we&#39;ve neatly rolled into one component to spare us file surfing. Each section has a dedicated instance of the useState hook, which we all know and love.</p><p>So, we have three pieces of state: input, count, and darkMode.</p><p>Instead of updating our state inline, we’ve made four breakout functions: handleChange, incrementCount, decrementCount, and changeTheme, each of which does exactly what its name implies. The only thing to note here is that, with incrementCount and decrementCount, we&#39;re using an <a href="https://beta.reactjs.org/reference/react/useState#setstate-parameters">updater function</a> rather than directly passing the new state value. We&#39;ve done this because the next value of the state depends on the previous value. A longhand version of the same function would look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/688/1*Jd7W63mAPNE202sHDUHgiQ.png" /></figure><h3>A Simple Refactor</h3><p>Let’s jump into our refactoring, one piece of state at a time. We’ll start by importing useReducer from &#39;react&#39;.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/990/1*PqpAx_fHW6mqw8DhTbYj-Q.png" /></figure><p>Next, we’ll initialize our state with useReducer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ahqzI0C_7E3EmrsBfRVi-Q.png" /></figure><h3>useReducer Signature</h3><p>useReducer looks a lot like useState. We&#39;re still destructuring an array from the return and passing our initial values as arguments. However, you may notice that, unlike useState, useReducer requires two arguments: a reducer function and the initialState. The other difference is much more minor.</p><p>Our state is essentially the same, but rather than explicitly naming each piece of state, the convention is to create a state object, and our key/value pairs become our different &quot;pieces&quot; of state. The dispatch function is still our state setter but requires an action object as a second argument.</p><h3>Refactoring count</h3><p>First, we’ll refactor the count state. We&#39;ll start by defining our initialState variable. Typically this, along with the reducer function, would be defined elsewhere and imported into our component. For simplicity&#39;s sake, we&#39;ll define them in the same file, underneath our import statements but <strong>not</strong> inside our component.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/958/1*10bHCueB9xUNl7LUGR3lHg.png" /></figure><p>Next, we’ll define our reducer function in a &quot;separate file&quot; (same file, but outside our component). This reducer function requires two arguments: our state object and an action object. The action object will have two keys: type and payload. Later, when we dispatch an action, the type tells useReducer what we&#39;re trying to update, while the payload provides the updated value.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/872/1*QnfHl9_WZLOVekcGqlf6bQ.png" /></figure><p>Inside this reducer, we’ll switch on the action&#39;s type property to determine <strong>what</strong> to do. Of course, you could use any form of conditional logic, but a switch statement is the convention.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W5_paFZNk9YXJqTwdxupPg.png" /></figure><p>Notice that in our default, we console.log some simple feedback and return the unaltered state. So if we pass in an action type that doesn&#39;t exist, instead of breaking our app, we&#39;re simply made aware that we&#39;ve not yet built a case to handle this situation. This error handling can be as simple or robust as your company&#39;s style guide requires.</p><p>As our state complexity grows, we&#39;ll need to update and refactor our reducer. But for now, we&#39;ll move on to our functions.</p><p>Now, in incrementCount and decrementCount, instead of calling setCount, we call dispatch, and pass it the appropriate action as an object.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/806/1*uqOMatJtNaaTT6wx-YWWow.png" /></figure><p>And lastly, since count is now nested inside our state object, we need to update our count reference in our JSX.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/890/1*Y-61qZ6CoAFYahAZcDDvjw.png" /></figure><p>Now we can remove our count useState instance and test our App. It will work the same! And you&#39;ll notice our other two pieces of state still work just fine.</p><p>That’s great! We’ve added more code that’s complicated our app and reduced readability with no tangible advantages! How cool!</p><p>Settle down. Now is where we start to see some advantages. It’s time to <strong>reduce</strong> our state into a single object.</p><h3>Refactoring darkMode</h3><p>We’ll start this process by adding darkMode to our initialState object. In our case, the default is true because I&#39;m a gremlin.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*_yW-20-kRqfSJop2E5j1kA.png" /></figure><p>Next, we’ll add a case to our reducer to handle the darkMode update.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XNCr4SMhSgMr0ZifX-P3dQ.png" /></figure><p>As before, let’s update our changeTheme function to dispatch the appropriate action. This time, we need not only a type but also a payload. The type will be darkMode, and the payload will be the opposite of darkMode&#39;s current value.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kbnbfqgbaWGDHJB4FB2Kew.png" /></figure><p>Lastly, we’ll update the reference in our JSX.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5okxkyGV-FzM2GI7QilNGA.png" /></figure><p>Now you’ll see that we can, again, toggle between light and dark modes! And if we test our counter we find that…</p><p>We broke our app.</p><p>Luckily this is an easy fix. When we update our state object, it&#39;s completely overwriting the previous state object, but we want to preserve all previous values and only update the one being changed. So, in our reducer, all we need to do is <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread</a> the current state before updating.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*meyxmxg-HdN8NbguYYOFRA.png" /></figure><p>Works like a charm! We can now remove our darkMode useState instance.</p><h3>Refactoring input</h3><p>Our last piece of state to update is our input. This will be the same process as before.</p><p>First, we add an input to our initialState object.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*y5ie6_H5iZPEp-qNiNZFOA.png" /></figure><p>Next, we add a case to our reducer to handle the input update.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z6FF42eSvp5gIQsW4r1pGA.png" /></figure><p>Next, we update our handleInputChange function to dispatch the appropriate action.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-TRf9Th9M5bRm7rfZzPhHw.png" /></figure><p>And lastly, we update our JSX to reference the proper input value.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*L19raxmDJz2pfk1PgnBacQ.png" /></figure><p>Now we can remove our last instance of useState and test our app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/891/1*jOp6v807Gqbwn3plM9QdmA.gif" /></figure><p>It works! Congrats! You’ve just built your first React App that updates state without useState!</p><h3>Refactoring Our action Object</h3><p>Now that our app is fully functional, there are a few more things we can do to optimize our code. We’ll start by refactoring our action object. Rather than evaluating our state updates based on passing around strings, we can make our action object a const that we then reference in our reducer. Not only does this help us avoid typos, but if we need to update our action object, we only need to do so in one place, making our app much more maintainable.</p><p>Again, in a “separate” file, we’ll define a proper const using all caps.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/654/1*-YXv9faqlxcIDR4Fe0UUjA.png" /></figure><p>Now, in our reducer, instead of comparing action.type to a string, we can compare it to ACTION.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mH9chS0R5_u5AomW38J4ug.png" /></figure><p>And in our dispatch calls, we&#39;ll remove the strings and reference the ACTION const as our type.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mdAIbMWqkaSBZA8cBGqn9g.png" /></figure><p>You’ll notice that this approach not only avoids typos and makes your code more maintainable, but now your IDE offers you autocomplete suggestions.</p><h3>The Tradeoffs</h3><p>As with everything in development, there are tradeoffs. In this case, we seem to have simplified our state by complicating it. Obviously, this is overkill for a counter app with a random input field and a light/dark mode toggle. But as our apps grow, we’ll find that this pattern, while heavy on the setup, simplifies overall. For example, take a look at this state tree from Airbnb. Or, head to <a href="https://airbnb.com">airbnb.com</a> and see for yourself using the Redux DevTools.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nFRg__PSbymAkUINIKk4-Q.png" /></figure><p>Now, imagine a different useState hook for each of those values. And imagine if you needed to pass these values around your app. There would be so much prop drilling that your code would be entirely unreadable.</p><h3>Conclusions</h3><p>So, when should you use useState, and when should you use useReducer?</p><p>That, my friend, is up to you (or your future company’s style guide and coding principles). If you’re able to accurately predict the complexity of your app, the extra work to set up useReducer from the start might be worth it. If you know you won&#39;t be scaling up, or you&#39;re okay with the future tech debt, maybe you stick with useState. The most likely scenario is that you&#39;ll use a mixture of both.</p><p>Either way, you now have the tools to make an informed decision. And that’s arguably more important than what you decide. And now that you’re armed with this knowledge, add a central store or some slices for your state, and you’re using Redux!</p><blockquote>I’m always looking for new friends and colleagues. If you found this article helpful and would like to connect, you can find me at any of my homes on the web.</blockquote><blockquote><a href="https://github.com/austin-rt">GitHub</a> | <a href="https://twitter.com/0xstink">Twitter</a> | <a href="https://www.linkedin.com/in/austinrt">LinkedIn</a> | <a href="https://austinrt.io/">Website</a></blockquote><h3>Resources</h3><ul><li><a href="https://beta.reactjs.org/reference/react/useReducer">useReducer</a></li><li><a href="https://beta.reactjs.org/reference/react/useState">useState</a></li><li><a href="https://medium.com/edge-coders/the-difference-between-flux-and-redux-71d31b118c1">Flux</a></li><li><a href="https://redux.js.org/introduction/getting-started">Redux</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">ES6 Spread Operator</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4efd32edc084" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Demystifying React Hooks — useLayoutEffect]]></title>
            <link>https://austinrt.medium.com/demystifying-react-hooks-uselayouteffect-eac6773822?source=rss-e5ab5bafb583------2</link>
            <guid isPermaLink="false">https://medium.com/p/eac6773822</guid>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[austin]]></dc:creator>
            <pubDate>Sat, 07 Jan 2023 05:35:29 GMT</pubDate>
            <atom:updated>2023-01-07T16:11:37.340Z</atom:updated>
            <content:encoded><![CDATA[<h3>Demystifying React Hooks — useLayoutEffect</h3><h4>In this article, we will explore when and how to use React&#39;s useLayoutEffect hook and how it relates to the useEffect Hook.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*faEOYS-bwXTm4tWLwvLaGQ.png" /></figure><p>If you&#39;d like to follow along in your local IDE, you can find the GitHub Repo <a href="https://github.com/austin-rt/useLayoutEffect">here</a>.</p><h3>Getting Started</h3><ul><li>fork and clone</li><li>cd client</li><li>npm i</li><li>npm start</li></ul><h3>Creating the Problem</h3><p>Sure, useLayoutEffect is not something you&#39;ll use often. It actually took me longer to think of a use case than to code out the example. It&#39;s kinda like <a href="https://en.wikipedia.org/wiki/I_know_it_when_I_see_it">the US Supreme Court&#39;s definition of obscenity</a>, &quot;You know it when you see it.&quot;</p><p>The React beta docs offer a cool, albeit incredibly specific use case with &quot;<a href="https://beta.reactjs.org/reference/react/useLayoutEffect#usage">a tooltip that appears next to some element on hover. If there&#39;s enough space, the tooltip should appear above the element, but if it doesn&#39;t fit, it should appear below</a>&quot;… if you&#39;d like to check that out.</p><p>While you likely won&#39;t turn to useLayoutEffect often enough to need a snippet, understanding how it works will help you better understand useEffect, which you&#39;ll use daily as a React 18+ developer. And for the one time in your career when you need to pull it out, you&#39;ll know precisely the right tool for the job.</p><h3>What is useLayoutEffect?</h3><p>As every good developer pretends to do before Googling, let&#39;s turn to the <a href="https://beta.reactjs.org/reference/react/useLayoutEffect">docs</a>.</p><p>The first thing we see on the page for useLayoutEffect is a bright orange warning telling us not to use it.</p><p>Got it.</p><p>Reading on, we find the following description:</p><blockquote><em>useLayoutEffect is a version of </em><em>useEffect that fires before the browser repaints the screen.</em></blockquote><p>Sweet.</p><p>If you understand useEffect, this is a pretty straightforward explanation. However, if you&#39;ve found yourself here and don&#39;t have a firm grasp on <a href="https://beta.reactjs.org/reference/react/useEffect">useEffect</a>, I&#39;d recommend reading up on theat and revisiting this article. And since you didn&#39;t take my advice, let&#39;s quickly recap useEffect.</p><h3>useEffect Recap</h3><p>useEffect calls an anonymous function after the values in its dependency array have changed. It is asynchronous and non-blocking. It runs after the browser has painted the screen and can optionally return a &quot;clean-up&quot; function. Essentially, useEffect is all the old crusty component lifecycle methods rolled up into one tidy hook.</p><p>useEffect&#39;s primary purpose is to asynchronously run <a href="https://www.freecodecamp.org/news/react-useeffect-absolute-beginners/">side effects</a> without blocking the in-browser <a href="https://www.geeksforgeeks.org/why-javascript-is-a-single-thread-language-that-can-be-non-blocking/">JavaScript&#39;s Single Thread</a>, offering a more performant and responsive application resulting in a more seamless User Experience.</p><p>In plain English, your React App won&#39;t wait on useEffect to finish doing its thing before painting the DOM. Your virtual DOM will render and browser will paint while useEffect runs alongside that process, and if your useEffect affects the UI, it will only repaint what is needed.</p><p>Fetching data from an API and updating state is one of the most common use cases for useEffect.</p><p>So how does this compare to useLayoutEffect?</p><h3>useEffect vs. useLayoutEffect</h3><p>useLayoutEffect&#39;s signature is identical, but it is synchronous, blocking, and runs before the browser paints. So these two are exactly the same but exactly the opposite.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*M6KT8s47AH1GD041Fab-YQ.png" /></figure><h3>Starter Code</h3><p>Let&#39;s <em>finally</em> dive into the code.</p><p>In App.js, you&#39;ll see our entire app that aims to simulate a Super Exciting Live Stream with a chat functionality on the sidebar.</p><p>On lines 15 and 16, we&#39;re simply initializing a ref called afterChatRef and a state called messages.</p><p>After our imports, we have a setInterval function that counts to a billion every two milliseconds. React is getting better and better at outsmarting our clunky code, so this is purely a way to slow down the application. And the comment is just asking es-lint to cool it with the unused vars warning.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1008/1*q71y43tSXqlwxB6Bbx5Y2w.png" /></figure><p>On line 19, getMessages gets our data from a dummy API and sets that data to the messages state.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2g83fMHjL4JA1h-0l8dGRA.png" /></figure><p>On line 24, we have a useEffect with an empty dependency array that calls our getMessages function. So the component mounts, the virtual DOM is rendered and painted to the real DOM, then, when our useEffect runs, it updates messages which rerenders the virtual DOM, React compares the diff and causes the real DOM to repaint.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/518/1*V2JWzJs4nwMiVdSlVFVAFg.png" /></figure><p>There’s another useEffect on line 28, whose dependency array contains messages. Since this hook depends on the value of messages, it doesn&#39;t trigger until messages changes. When called, this useEffect scrolls the afterChatRef into view.</p><p>Practically speaking, it takes the user to the bottom of the chat. There is no functionality to add new messages, but as you can imagine, when the user adds a message, state changes, and our useEffect scrolls us to the bottom.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/924/1*e2C5W80jS201wEYXE5Mweg.png" /></figure><p>Nothing exciting in the JSX. Our &quot;stream&quot; is on the left, and we&#39;re conditionally rendering the messages in a container on the right.</p><h3>So What&#39;s the Problem?</h3><p>Admittedly, were it not for my function sandbagging our app, we would use useEffect like normal and not notice the issue. If your machine is significantly faster than mine, you still may not notice the problem. If that&#39;s the case, open your dev tools (shame on you for not already having them open), click the Performance tab, click CPU No throttling, and set it to 4x slowdown or even 6x slowdown, depending on how much richer you are than me.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/476/1*Cu3BDXGN_sTzNpfM0rrBmA.gif" /></figure><p>Refresh the page. Nice and slow.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pKpmJ4AUT11l-H4b2DxEHg.gif" /></figure><p>See how the chat loads and hangs at the top for a moment before snapping to the bottom? Let&#39;s reduce the for loop to 1e5 (100,000) instead of 1e9, save, and refresh.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4Ey1I4P96dMO69KCRM6uRQ.gif" /></figure><p>This is closer to how it may look out in the wild. This flicker is that &quot;obscenity&quot; I was talking about earlier.</p><p>Let&#39;s refer back to the React doc&#39;s tooltip example to see the root issue they&#39;re trying to solve.</p><blockquote><em>You don’t want the user to see the tooltip moving. Call </em><em>useLayoutEffect to perform the layout measurements before the browser repaints the screen.</em></blockquote><p><em>You don&#39;t want the user to see the tooltip moving.</em> Or, say, to see the chat flickering before snapping to the bottom?</p><h3>Implementing useLayoutEffect</h3><p>This refactor will be significantly less work than previous articles. All we need to do is import useLayoutEffect from &#39;react&#39;.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e6zzsNDdM4rMyTEbKxKd-A.png" /></figure><p>And replace our useEffect on line 28 with useLayoutEffect, leaving the useEffect on line 24 undisturbed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/924/1*1ho8oDS3Rbc7l3eHvnxAmw.png" /></figure><p>Now, when we save and refresh, voila! Our chat no longer flickers at the top before scrolling to the bottom.</p><p>To demonstrate further, change our arbitrary loop back to 1e9 and throttle your browser if needed. Refresh.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Nop8iffpWlnOcqcpMSQkNg.gif" /></figure><p>While painfully slow, you can see the DOM doesn&#39;t paint the chat section until after the useLayoutEffect has scrolled us to the bottom.</p><p>Our chat no longer flickers because, after the value of messages changes, we&#39;re <strong>blocking</strong> the browser from painting the DOM until the useLayoutEffect scrolls the chat to the bottom.</p><h3>Some Cautions</h3><p>No flicker. So why not always use useLayoutEffect over useEffect? Well, it&#39;s essential to understand what precisely is going on and why we should heed React&#39;s enormous orange warning.</p><p>Remember, useLayoutEffect is <a href="https://www.freecodecamp.org/news/synchronous-vs-asynchronous-in-javascript/"><strong>synchronous</strong></a> and <strong>blocking</strong>. These are actually both standard function behavior JavaScrip in-browser. Synchronous means it runs from the top down line-by-line, and blocking means it is a resource hog that won’t return until completed.</p><p>Because of this blocking behavior, we should only implement useLayoutEffect when we <strong>notice</strong> the need. If we go around useLayoutEffect-ing all over the place, we&#39;ll unnecessarily bog down our app and may as well be writing in vanilla JavaScript.</p><p>This is why the docs recommend useEffect or useLayoutEffect. We should approach useLayoutEffect with the same opt-in mentality as useCallback or useMemo. Only implement it after you notice the need.</p><p>Preemptively optimizing our app will often introduce bugs and complicate the codebase with little benefit. In general, if you don&#39;t know whether you should implement useLayoutEffect, you probably shouldn&#39;t.</p><h3>Conclusions</h3><p>useLayoutEffect is a nifty little hook, and truthfully, you won’t use it very often. But if you do, it’s important to acknowledge the tradeoffs and make conscious sacrifices. Don’t go preoptimizing willy-nilly. As we used to say in the film industry, “Do nothing. Stay ahead.”</p><p>And hey, being able to discuss useLayoutEffect intelligently might impress some fellow React nerds in your favorite comments section and even a Hiring Manager or two. But let’s circle back to the question that started this all. “When should I use useLayoutEffect?”</p><p>You&#39;ll know it when you see it.</p><blockquote>I’m always looking for new friends and colleagues. If you found this article helpful and would like to connect, you can find me at any of my homes on the web.</blockquote><blockquote><a href="https://github.com/austin-rt">GitHub</a> | <a href="https://twitter.com/0xstink">Twitter</a> | <a href="https://www.linkedin.com/in/austinrt">LinkedIn</a> | <a href="https://austinrt.io/">Website</a></blockquote><h3>Resources</h3><ul><li><a href="https://github.com/austin-rt/useLayoutEffect">GitHub Repo</a></li><li><a href="https://beta.reactjs.org/reference/react/useLayoutEffect">useLayoutEffect</a></li><li><a href="https://beta.reactjs.org/reference/react/useEffect">useEffect</a></li><li><a href="https://www.freecodecamp.org/news/react-useeffect-absolute-beginners/">Side Effects</a></li><li><a href="https://www.geeksforgeeks.org/why-javascript-is-a-single-thread-language-that-can-be-non-blocking/">Why JavaScript is a Single-Thread Language That Can Be Non-Blocking</a></li><li><a href="https://www.freecodecamp.org/news/synchronous-vs-asynchronous-in-javascript/">Synchronous vs Asynchronous in JavaScript</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=eac6773822" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Demystifying React Hooks — useRef]]></title>
            <link>https://austinrt.medium.com/demystifying-react-hooks-useref-a2c7155d0cd5?source=rss-e5ab5bafb583------2</link>
            <guid isPermaLink="false">https://medium.com/p/a2c7155d0cd5</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[software-enginnering]]></category>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[austin]]></dc:creator>
            <pubDate>Mon, 12 Dec 2022 14:50:38 GMT</pubDate>
            <atom:updated>2023-02-16T21:01:11.386Z</atom:updated>
            <content:encoded><![CDATA[<h3>Demystifying React Hooks — useRef</h3><h4>In this article, we will discuss some common use cases for React’s useRef Hook.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YKcFDZOHKUsAxuFnCaP8vA.png" /></figure><h3>Getting Started</h3><p>We will use the Profiler from the React Dev Tools to see how our components are rendering. If you don’t have the React Dev Tools and plan to follow along, you’ll need to pause and download it now.</p><ul><li><a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi">Chrome React Dev Tools</a></li><li><a href="https://addons.mozilla.org/en-US/firefox/addon/react-devtools/">Firefox React Dev Tools</a></li></ul><p>If you’d like to follow along in your local IDE, you can find the GitHub Repo <a href="https://github.com/austin-rt/useRef">here</a>.</p><ul><li>fork and clone</li><li>cd client</li><li>npm i</li><li>npm start</li></ul><h3>Starter Code</h3><p>As always, we’ll start with a tour of our codebase. This time, App.js is a simulated Login Form.</p><p>We have initialFormValues, an object with a blank email and password, which we use to initialize our formValues state.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v_-4R6YSaVKqF-1Yko55TQ.png" /><figcaption>formValues initialization</figcaption></figure><p>We then have boilerplate handleChange and handleSubmit functions, and the handleSubmit logs formValues to the console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/840/1*UBbVXB74A7T2FZJo3B42JQ.png" /><figcaption>handleChange and handleSubmit</figcaption></figure><p>Finally, our JSX renders the form and assigns the appropriate onChange and onSubmit attributes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RvdNmElo7n1z3QK7e6gMtg.png" /><figcaption>our return statement</figcaption></figure><h3>What’s the Problem?</h3><p>So you may be asking, <em>“What’s wrong with this component? It works as expected, and I’ve written forms like this countless times.”</em></p><p>So have I, friend. So have I.</p><p>Open your React Dev Tools and click the Settings cog. Next, click the ‘Profiler’ tab and tick on the option, “Record why each component rendered while profiling.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/1*YUIUDDtbWGZkrwYCQh0HAg.gif" /><figcaption>setup profiler to record why each render occurs</figcaption></figure><p>Now open the Profiler tab, and you will see a blue dot in the upper left corner. Click it to start profiling. Next, type in the inputs and click the (now red) dot to stop profiling.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*u16x_BPNpmVYwB2yJUhjzQ.gif" /><figcaption>begin profiling</figcaption></figure><p>Click the App component on the left inside the Profiler tab, and you&#39;ll see a list of all the renders. Notice the Profiler provides the same reason for each:</p><p><strong>Why did this render?</strong></p><ul><li>Hook 1 changed</li></ul><p>The component re-rendered on <strong>every keystroke</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AEI0QloajmLaqxjMmTPgMA.gif" /><figcaption>Profiler telling us the reason for each render</figcaption></figure><h3>Minimizing Renders</h3><p>If our form’s sole purpose is to submit the inputs elsewhere, then we don’t need the component to re-render in real time. We don’t care what the value is while the user is typing. We only care about the value when the form is submitted.</p><p>This may seem harmless in a small application, but it can significantly impact our application as it scales. And part of being a good React developer is being mindful of the performance of our applications by minimizing renders.</p><h3>Enter <a href="https://beta.reactjs.org/apis/react/useRef">useRef</a></h3><p>In the broadest sense, the useRef Hook creates a mutable variable that persists between renders. It provides the ability to store a value we can access outside the render cycle.</p><p>Let’s try using useRef to store our render count.</p><p>We’ll start by importing useRef in our current import.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/924/1*3a61mc6K4PJx2u3_WJAYlg.png" /><figcaption>importing useRef</figcaption></figure><p>We will initialize renders with useRef and set it to 0. When we initialize a ref, the Hook creates an object with a current property. current is the property we must use to update the ref&#39;s value.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/722/1*T1PZXYUsxVYcPgHiEzWfJA.png" /><figcaption>initializing rendersRef</figcaption></figure><p>We&#39;ll use a useEffect Hook without the dependency array to increment renders every time the component renders. And take note that we change the value of a ref, unlike useState, we can do so <strong>directly</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vMF38fmHlCGZuiLwf2F7HA.png" /><figcaption>importing useEffect and incrementing rendersRef</figcaption></figure><p>Let’s render renders in our JSX.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/992/1*lAMPfti-R8Yh571EvKzemw.png" /><figcaption>displaying rendersRef.current in our JSX</figcaption></figure><p>When we type in the input, we see our render count incrementing in real-time. Neat, I guess, but not particularly useful.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/707/1*i-ooO8GFQC7n5GtlaK9AMw.gif" /><figcaption>render count increments as we type</figcaption></figure><p>From the React Docs:</p><blockquote><em>useRef returns a ref object with a single </em><em>current property initially set to the initial value you provided. On the next renders, </em><em>useRef will return the same object. You can change its </em><em>current property to store information and read it later. This might remind you of </em><a href="https://beta.reactjs.org/apis/react/useState"><em>state</em></a><em>, but there is an important difference.</em></blockquote><blockquote><strong><em>Changing a ref does not trigger a re-render</em></strong><em>. This means refs are perfect for storing information that doesn’t affect the visual output of your component.</em></blockquote><p><em>…information that doesn’t affect the visual output of your component.</em></p><p>Kind of like a login form?</p><h3>Refactoring Our Form with useRef</h3><p>Let’s start by creating two new refs to store our email and password values and initialize them as null.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/788/1*-I_PkVU3HtdIJAt1r3XQBQ.png" /><figcaption>initializing emailRef and passwordRef</figcaption></figure><p>When using the useRef Hook to reference a DOM element, associating it is incredibly simple. All we need to do is add a ref attribute to the element and provide it our ref variable as its value.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/654/1*41oTbpu5zlpfcuwvtw7G8Q.png" /><figcaption>assigning the refs to their JSX elements</figcaption></figure><p>Next, we need to refactor our handleSubmit function. Instead of logging formValues, we&#39;ll create an object, setting the values as each ref&#39;s current property.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/890/1*vakpYBlxAuHAcO07nG6aDA.png" /><figcaption>refactored handleSubmit</figcaption></figure><p>Type in the inputs and click Login. You should see your object logged properly while the render count remains 0. The Profiler also finds no activity. Changing the value of our refs did not cause the component to re-render.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/818/1*ZLFeHuo2ybBgO2ro9B7Waw.gif" /><figcaption>useRef is not causing our component to re-render</figcaption></figure><p>With that working, we no longer need the following:</p><ul><li>email onChange attribute</li><li>password onChange attribute</li><li>handleChange function</li><li>formValues state</li><li>initialFormValues object</li><li>useState import</li></ul><blockquote>Though we aren’t directly using it anymore, we should keep the name attributes for accessibility.</blockquote><p>Test the application again. We removed a lot of code, but it still works as expected!</p><h3>useRef vs. useState</h3><p>This accurately demonstrates the point raised in the React Docs: updating useRef does not trigger a re-render, which is probably the most significant difference between useRef and useState.</p><p>In addition, you’ll notice that when we updated the current property on our ref, we did so directly. <strong>Never</strong> do this with useState. Instead, you must always use the setter function if you wish your UI to <em>react</em> to the change. You can read about this behavior <a href="https://beta.reactjs.org/apis/react/useState#ive-updated-the-state-but-the-screen-doesnt-update">here</a>.</p><blockquote>Yes, I know. We literally just used useRef to affect a change in the DOM. In my defense, try to use useState to track your render count and include itself in that count. If you can figure out a way without causing an infinite re-render, please reach out. I&#39;d like to know.</blockquote><h3>One Last Use Case</h3><p>Before concluding this article, I’d like to address what I think is the simplest common use case for useRef. Let’s start by moving our render count below the section tag containing our form. We’ll put it in its own section tag.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/992/1*v1ttjUHxXrtosH4PzzJFYA.png" /><figcaption>moving renders to its own section tag</figcaption></figure><p>Next, we will create a formRef for our form and assign it accordingly. Let’s add a button with the text, Scroll to Render Count.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/890/1*tr3Xrcr7MAwK0kw4TCP7og.png" /><figcaption>initializing forRef, assigning it, adding a button</figcaption></figure><p>Then we will initialize renderCountSectionRef, assign it to our render count container, and add a button with the text Scroll to Form.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/992/1*j1kU0ZBoGTkLzWxwPLZRMg.png" /></figure><p>Let’s create a new function called scrollToElement that expects a ref as a parameter and scrolls us to said ref.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LKLDEFvKjMMPUXz6gM0MmQ.png" /><figcaption>srollToElement function</figcaption></figure><p>Now, we will set the onClick property to scrollToElement with the appropriate ref as its argument.</p><blockquote>Please note that using inline functions will make for a less performant app, but that refactor would require more custom logic and is outside the scope of this article.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/958/1*7olabtvtS1-rv_6VLLSn1A.png" /><figcaption>setting button onClick to scrollToElement</figcaption></figure><p>Now, when we click the buttons, we scroll about the page! This feels a lot like a Scroll To Top or Jump to Recipe button, doesn&#39;t it?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/818/1*sboCym0SIBhvM7yisM-QcQ.gif" /><figcaption>scrollTo buttons working</figcaption></figure><p>Since scrolling to a specific element doesn’t demand a re-render, it is a much better use case for useRef than useState.</p><h3>A Caution</h3><p>After realizing that we can affect changes on DOM Elements directly with useRef, it may be tempting to use this method as an analog to querySelector or getElementBy—.</p><p>This is an <strong>anti-pattern</strong> and should be avoided if possible. It can cause your UI to fall out of sync with your state and, in a larger application, can have an unforeseen ripple effect. These bugs will be challenging to track down.</p><h3>Conclusions</h3><p>In this article, we discussed the functionality of useRef, how it persists through renders, and how, unlike useState, it does not cause re-renders. We also explored one of the most common uses of useRef: to navigate our user to different DOM elements.</p><blockquote>I’m always looking for new friends and colleagues. If you found this article helpful and would like to connect, you can find me at any of my homes on the web.</blockquote><blockquote><a href="https://github.com/austin-rt">GitHub</a> | <a href="https://twitter.com/0xstink">Twitter</a> | <a href="https://www.linkedin.com/in/austinrt">LinkedIn</a> | <a href="https://austinrt.io/">Website</a></blockquote><h3>Resources</h3><ul><li><a href="https://github.com/austin-rt/useRef">GitHub Repo</a></li><li><a href="https://beta.reactjs.org/docs/hooks-reference.html#useref">useRef</a></li><li><a href="https://beta.reactjs.org/docs/hooks-reference.html#usestate">useState</a></li><li><a href="https://beta.reactjs.org/blog/2018/09/10/introducing-the-react-profiler#profiling-an-application">React Profiler</a></li><li><a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en">React Dev Tools for Chrome</a></li><li><a href="https://addons.mozilla.org/en-US/firefox/addon/react-devtools/">React Dev Tools for Firefox</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a2c7155d0cd5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Demystifying React Hooks — useMemo]]></title>
            <link>https://austinrt.medium.com/demystifying-react-hooks-usememo-1219661d0af0?source=rss-e5ab5bafb583------2</link>
            <guid isPermaLink="false">https://medium.com/p/1219661d0af0</guid>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[austin]]></dc:creator>
            <pubDate>Thu, 08 Dec 2022 23:36:24 GMT</pubDate>
            <atom:updated>2023-02-16T20:59:18.130Z</atom:updated>
            <content:encoded><![CDATA[<h3>Demystifying React Hooks — useMemo</h3><p>In this article, we will explore when and how to use React&#39;s useMemo Hook to increase your app&#39;s performance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*luZNw_zseK1SAbHwYNI5Xg.png" /></figure><h3>TL;DR</h3><p>If you’re here solely to understand when to (and not to) use useMemeoand don’t want to work through the examples, I’ll spare you. According to the <a href="https://beta.reactjs.org/apis/react/useMemo#should-you-add-usememo-everywhere">React Docs</a>, much like <a href="https://medium.com/@austinrt/demystifying-react-hooks-usecallback-7c78fac08947">useCallback</a>, useMemo is an <strong>opt-in </strong>performance enhancer Hook used to create referential equality for function results. The three most common use cases are:</p><ol><li>if the calculation causes noticeable slowdown in other parts of your app</li><li>if you’re passing the calculation as a prop to a child component</li><li>if the calculation is used as a dependency in a Hook</li></ol><p>If none of those conditions is being met, you’re likely wasting time, lines, and sacrificing readability (and memory) by proactively “optimizing” your app.</p><p>With that out of the way, Let’s get started.</p><h3>Getting Started</h3><p>Buckle up and strap in. This article is on the heavier side for both theory and length.</p><p>If you&#39;d like to follow along in your local IDE, you can find the GitHub Repo <a href="https://github.com/austin-rt/useMemo">here</a>. Otherwise, you can reference the code snippets, though you will miss out on the performance comparisons.</p><ul><li>fork and clone</li><li>cd client</li><li>npm i</li><li>npm start</li></ul><h3>Starter Code</h3><p>We&#39;ll begin with a quick overview of our starter code. In App.js, you&#39;ll find a function named &quot;jacobsthal,&quot; two pieces of state, and a variable named “calculation”. Notice we wrapped jacobsthal in a useCallback Hook, and calculation is the returned value from calling jacobsthal.</p><p>The JSX renders both inputs and their respective values. If you need a refresher on what service the useCallback Hook provides, I&#39;d suggest you pause here and give my <a href="https://medium.com/@austinrt/demystifying-react-Hooks-usecallback-7c78fac08947">useCallback</a> article a quick read.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RidzEQiM9qz1xnZYsmVdRQ.png" /><figcaption>our App.js starter code</figcaption></figure><blockquote>Our jacobsthal function is a simple, <a href="https://www.geeksforgeeks.org/javascript-memoization/">recursive</a> function that returns the <a href="https://en.wikipedia.org/wiki/Jacobsthal_number">Jacobsthal Number</a> at a given index. The specifics of the code and Jacobsthal Number don&#39;t matter for useMemo. All we care about is that it&#39;s defined <strong>within</strong> our component, hence the implementation of useCallback, and that it’s computationally expensive.</blockquote><p>If we provide a small value to the number input, our React app behaves as expected, snappily rendering the result. However, as we increase the value of our input, while the app still provides the desired output, it takes increasingly longer to render.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/828/1*m4q5AXAAq_7Fxb9HaDSJrA.gif" /></figure><h3>Why is This Happening?</h3><p>Thirty-five will be our test case because it is slow enough to be annoying but still testable. So we’ll type 35 and wait for our output to calculate.</p><p>Now start typing into the second input. See how slow it is to render? That’s because when the input changed, the <strong>entire</strong> component re-rendered, and our expensive function recalculated the output before re-rendering, even though our jacobsthal output didn’t change.</p><p>This is obviously a problem.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/828/1*RoABauX80z1BzH8v7OHpHA.gif" /><figcaption>speed demonstration</figcaption></figure><blockquote>A Quick Aside:</blockquote><blockquote>Junior Developers make this mistake far too often. You don’t always need useState for your forms. I&#39;ll even propose that you <strong>usually don&#39;t</strong>. If no part of your application needs to see the real-time value, like when submitting a form to an API, you should be using useRef instead. We will get into how and why in a later article.</blockquote><p>So with the stage set and the curtains drawn, how do we resolve the issue at hand?</p><h3>Memoization</h3><p>Memoization is a Programming technique that stores the <strong>results</strong> of a function call, so the next time you call that function, it doesn’t have to recalculate the output. Instead, it can return the stored result, saving <a href="https://www.freecodecamp.org/news/time-complexity-of-algorithms/">time complexity</a> with recursive functions.</p><p>That’s all you need to know for now, but if you’d like a more in-depth explanation, check out this <a href="https://www.geeksforgeeks.org/javascript-memoization/">Memoization in JavaScript</a> article by GeeksforGeeks. And at the end of this article, we will refactor our jacobsthal function to implement proper JavaScript memoization.</p><h3>useMemo vs. useCallback</h3><p>To sum it up, useCallback stores the <strong>definition</strong> of the function, so it doesn&#39;t unnecessarily <strong>redefine</strong> on every render. useCallback creates referential equality between instances of the function across renders.</p><p>Similarly, useMemo stores the <strong>result</strong> of the function call, so it doesn&#39;t unnecessarily <strong>recalculate</strong> on every render. useMemo creates referential equality between instances of the value across renders.</p><p>You can already see how this is helpful and leads directly to the primary purpose of useMemo. In short, the aptly named useMemo Hook is React’s built-in memoization tool.</p><h3>useMemo in Action</h3><p>Let’s write some code!</p><p>We’ll start by importing useMemo from &#39;react&#39;.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SOCLV03f5rsaixHs2NodNw.png" /><figcaption>importing useMemo from ‘react’</figcaption></figure><h3>useMemo Syntax</h3><p>You guessed it, useMemo has a similar syntactical skeleton to both useEffect and useCallback: an anonymous callback with a dependency array.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/722/1*JEX6Kep0tqJe-yNYCdgkOg.png" /><figcaption>useMemo syntax comparison</figcaption></figure><p>As in our useCallback example, we want to cache what&#39;s <strong>returned</strong> from this Hook. So we will assign our calculation variable to the return value of useMemo, wrapping our function call in an anonymous callback.</p><p><em>Remember to </em><em>return the result of your function call so it is accessible by </em><em>useMemo!</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/822/1*FYdHCKf1pSAV_sMuVqVBDg.png" /><figcaption>useMemo implementation</figcaption></figure><p>After we save, we’ll notice a familiar warning from React. Our Hook is missing a dependency.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bi16CtIjDvqnifUTK-UFtQ.png" /><figcaption>dependency warning</figcaption></figure><p>Before blindly obeying React’s warnings, let’s first think through the purpose of this dependency array and the functionality it extends to our application.</p><p>The intent of dependency arrays with React Hooks is to trigger our Hook more intentionally and specifically. When the value of the variable being “tracked” changes, the Hook knows it&#39;s time to <em>do its thing</em>.</p><p>In our specific case, when number changes, we want our jacobsthal function to recalculate the result.</p><p>So let’s add number to our dependency array.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/822/1*fQ0d9_qJ1srxHZqE-hWBEQ.png" /><figcaption>dependency array added</figcaption></figure><p>Now that we’ve memoized our function, let’s test it out. We’ll start by inputting 35. Our calculation still takes time because our jacobsthal function is still computationally expensive. But now, when we type in the second input, our React app is again snappy and responsive. It&#39;s no longer recalculating our jacobsthal output because number has not changed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/828/1*JYSwQDmwLhURgtHtcAs34A.gif" /></figure><h3>Conclusion (kind of)</h3><p>Because we memoized the results of our function, we’ve created referential equality and eliminated any unnecessary renders, making our React app more performant.</p><p>If you only came here for the React piece, thanks so much for reading, and look out for the useRef article next!</p><p>But what to do about our computationally expensive jacobsthal function? Time to refactor.</p><p>We begin by creating a previousValues parameter with a default value of an empty array. This will be our cache that we will later pass to our recursive sequence. Doing so will spare our recursive sequence from working overtime.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ld5LAUl89dplV1AmoOUogQ.png" /><figcaption>jacobsthal with default previous values array</figcaption></figure><p>Next, inside our code block, we’ll create a results variable. We will later reassign the value, so we’ll need to use our let keyword.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Dc8vFcZBn69sa3zUYrfuiQ.png" /><figcaption>adding our result variable</figcaption></figure><p>Instead of returning our computations directly, we’ll explicitly wrap our recursive sequence in an else block and assign our return options to result.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*85VCayIMkx5fGuQ0eKN2xw.png" /><figcaption>saving returns as result rather than returning them directly</figcaption></figure><p>Now, after our conditionals have evaluated and assigned a value to result, we set previousValues at index n equal to our current result, then return result, thus caching this value and making it accessible as a return.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MvVjvLd70_Ak5zYRyMQlkA.png" /><figcaption>returning result</figcaption></figure><p>Next, the first thing our function should do is check to see if previousValues at index n exists. If it does, we return it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qeMfpF3CZ-CASIT66CBa7A.png" /><figcaption>check if previousValues at index n exists</figcaption></figure><p>Lastly, we’ll pass previousValues as an argument to our recursive sequence.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BrPbBmX6QUxVZc2JC9qxWw.png" /><figcaption>final jacobsthal function</figcaption></figure><h3>Conclusions (for real this time)</h3><p><em>Whew</em>. We can now test our newly (and thoroughly) memoized component. Try 35 again. Pretty snappy, huh? So snappy, in fact, that if we enter 1026 as our input, it’s still responsive. Even calculating ‘Infinity&#39; doesn&#39;t crash our app. And yes, useMemo is still doing its thing.</p><p>There is no lag in our other input.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/828/1*t9lJLV_YcQYLJ5Q5cxXTMw.gif" /></figure><p>If you’d like to dive deeper with useMemo, you can learn more in the <a href="https://beta.reactjs.org/apis/react/useMemo">official React docs</a>.</p><blockquote>I’m always looking for new friends and colleagues. If you found this article helpful and would like to connect, you can find me at any of my homes on the web.</blockquote><blockquote><a href="https://github.com/austin-rt">GitHub</a> | <a href="https://twitter.com/0xstink">Twitter</a> | <a href="https://www.linkedin.com/in/austinrt">LinkedIn</a> | <a href="https://austinrt.io/">Website</a></blockquote><h3>Resources</h3><ul><li><a href="https://beta.reactjs.org/apis/react/useMemo">useMemo</a></li><li><a href="https://medium.com/@austinrt/demystifying-react-Hooks-usecallback-7c78fac08947">useCallback</a></li><li><a href="https://www.freecodecamp.org/news/understanding-recursion-in-javascript-1938884c6be8/">Recursion</a></li><li><a href="https://www.freecodecamp.org/news/time-complexity-of-algorithms/">Time Complexity</a></li><li><a href="https://www.geeksforgeeks.org/javascript-memoization/">Memoization</a></li><li><a href="https://en.wikipedia.org/wiki/Jacobsthal_number">Jacobsthal Number</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1219661d0af0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Demystifying React Hooks — useCallback]]></title>
            <link>https://austinrt.medium.com/demystifying-react-hooks-usecallback-7c78fac08947?source=rss-e5ab5bafb583------2</link>
            <guid isPermaLink="false">https://medium.com/p/7c78fac08947</guid>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[austin]]></dc:creator>
            <pubDate>Fri, 02 Dec 2022 18:35:54 GMT</pubDate>
            <atom:updated>2023-02-16T20:57:01.811Z</atom:updated>
            <content:encoded><![CDATA[<h3>Demystifying React Hooks — useCallback</h3><h4>In this article, we will explore when and how to use React’s useCallback hook and a mistake made by most Junior Developers.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e5F4jpWF-LaPc8es0pL1-w.png" /></figure><h3>TL;DR</h3><p>If you’re here for a quick definition and don’t want to traverse through the examples, I’ll spare you. According to the <a href="https://beta.reactjs.org/apis/react/useCallback#should-you-add-usecallback-everywhere">React Docs</a>,useCallback is an <strong>opt-in </strong>performance enhancer Hook used to create referential equality for function definitions. The two most common use cases are:</p><ol><li>when you’re passing a function as a prop to a child component</li><li>if the function is used as a dependency in a Hook.</li></ol><p>If neither of those two conditions is being met, you’re likely wasting time, lines, and sacrificing readability (and memory) by proactively “optimizing” your app.</p><p>With that out of the way, Let’s get started.</p><h3><strong>Getting Started</strong></h3><p>If you’d like to follow along in your local IDE, you can find the GitHub Repo <a href="https://github.com/austin-rt/useCallback">here</a>.</p><ul><li>clone</li><li>cd client</li><li>npm i</li><li>npm start</li></ul><h3><strong>Referential Equality</strong></h3><p>Referential Equality is a foundational concept in both JavaScript and Computer Science as a whole. So let’s start with a demonstration of it in action.</p><p>I’ve embedded screenshots throughout the article for ease of use on mobile. If you’re on desktop and have cloned it down, run referentialEquality.js to observe the output or just play with the JSFiddle snippet embedded below.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fjsfiddle.net%2Faustinrt%2Fgxwtf0dp%2Fembedded%2F&amp;display_name=jsFiddle&amp;url=https%3A%2F%2Fjsfiddle.net%2Faustinrt%2Fgxwtf0dp%2F205%2Fembed%2Fjs%2Cresult%2Fdark%2F%3FbodyColor%3D252525&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=jsfiddle" width="600" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/f65c1c65037b7441636caafff2cbea44/href">https://medium.com/media/f65c1c65037b7441636caafff2cbea44/href</a></iframe><p>When evaluating whether the integer 1 is strictly equal to the integer 1, the console prints true. This is because, well… the integer 1 <strong>is</strong> strictly equal to the integer 1.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OO4o_D986OVPxnb2yYZhRQ.png" /><figcaption>the integers are strictly equal</figcaption></figure><p>We see the same result when evaluating two strings.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BL2qNuRhgrX5g4bzkj2h3A.png" /><figcaption>the strings are strictly equal</figcaption></figure><p>Obviously, this will always be the case for two <a href="https://developer.mozilla.org/en-US/docs/Glossary/Primitive">primitive data types</a> of the same value.</p><p>Now, what about data structures? For example, two object literals with the same key/value pairs? What about empty object literals?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bgAIqvY9VQXTPMRRqPq2Ng.png" /><figcaption>the objects are not strictly equal</figcaption></figure><p>Why would this print false? When comparing whether these two object literals are strictly equal, JavaScript uses their respective <strong>memory addresses</strong>.</p><p>In other words, these two objects may contain the same <strong>values</strong>, but they’re not <strong>referencing the same object</strong>. They <em>look</em> the same but occupy two different <em>spaces in memory</em>.</p><p>The same applies whether you’re comparing two object literals, two array literals, or two functions!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wYL17gSi5ixjG2SKqM3nSQ.png" /><figcaption>the arrays are not strictly equal</figcaption></figure><p>To demonstrate this further, we will define a function func, which returns an anonymous function that, in turn, returns something else (<em>like a JSX element</em>).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Zx2PNZhHJF2_3_skwyiTmg.png" /><figcaption>creating a pretend functional component</figcaption></figure><p>We will then assign two different functions, firstRender and secondRender, equal to the value returned by func.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ldL_bp7Utpw3j0k3yKzkmg.png" /><figcaption>assigning our function definitions</figcaption></figure><blockquote>Think of func as your React functional component, while firstRender is a function <em>inside</em> of it on the first render, and secondRender is a function <em>inside </em>of it on the second render.</blockquote><p>Even though firstRender and secondRender return the same value and are assigned from the same definition, they do not have <em>referential equality</em>. As a result, every time the component renders, it redefines this function.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*M67NMo9oWUmGA-Yt1KXuiw.png" /><figcaption>our two functions are not strictly equal</figcaption></figure><p>Unfortunately, in JavaScript, it isn’t easy to print these memory addresses like in Python, but for a slightly more in-depth explanation of reference vs. value, take a look at <a href="https://www.freecodecamp.org/news/how-to-get-a-grip-on-reference-vs-value-in-javascript-cba3f86da223/">this article</a> from freeCodeCamp.</p><p>This topic can get dense, and you don’t need to teach a class on it tonight. So, for now, just remember:</p><ul><li>primitive data type === primitive data type</li><li>data structure !== data structure.</li></ul><p>With referential equality out of the way, let’s dive into our React code and see why this is relevant.</p><h3><strong>Starter Code</strong></h3><p>After we spin up our app, open the BookDetails.jsx component and re-save. The first thing we may notice in our React dev server is a common WARNING that young developers tend to ignore. As you hit the workforce and start writing code for production, your linters will be even more strict than what’s built into create-react-app. WARNINGS will turn to ERRORS, and some linters won’t allow you to push before you address these ERRORS.</p><p>So rather than ignore it, let’s figure out how to treat it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JJOawDok3Y537SCmh6QrPA.png" /><figcaption>React’s proposed solutions</figcaption></figure><blockquote><em>NOTE: you may first need to re-save </em><em>BookDetails.jsx to create this </em><em>WARNING</em></blockquote><p>If we dig into the <a href="https://beta.reactjs.org/learn/synchronizing-with-effects#step-2-specify-the-effect-dependencies">React Docs</a>, we can decode the semi-confusing proposed solutions to this WARNING as follows:</p><p>1. Include the function definition inside of the useEffect .</p><ul><li>We cannot call this function elsewhere unless we redefine it.</li></ul><p>2. Remove the dependency array.</p><ul><li>This will trigger the useEffect <strong>every time</strong> state or props change, sometimes causing an infinite re-render. And in our case, since we’re calling our state setter function after an API call, it could overload our API with infinite endpoint requests.</li></ul><p>3. Remove the function call from the useEffect.</p><ul><li>The function won’t get called.</li></ul><p>4. Include the function in the dependency array.</p><ul><li>The first time the component renders, it will define our function, which will trigger the useEffect, which will cause the component to re-render, which will redefine the function, which will trigger the useEffect, which will cause the component to re-render, which will redefine the function…</li></ul><p><em>So what’s a developer to do?</em></p><p>The simplest and preferred solution would be to ‘include it,’ that is, move the getBookDetails function definition inside the useEffect. This adheres to an Object-Oriented Programming principal known as <a href="https://stackify.com/oop-concept-for-beginners-what-is-encapsulation/">Encapsulation</a>.</p><p>But let’s say we know we need to call the function elsewhere. Should we redefine it later? That’s not very DRY of us.</p><p>Let’s change our dependency array to include our function reference. Your useEffect should now look like this.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-9kybqG-xp_k6CcpqhWKPA.png" /><figcaption>including our function in the dependency array</figcaption></figure><p>And getBookDetails remains defined <strong>above </strong>the useEffect.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0EiORyQCuWzHTt7uyiyPVg.png" /><figcaption>our function’s original definition</figcaption></figure><p>Now we have a new WARNING</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_j_gx1PRyvg_pnFSXCQJMw.png" /><figcaption>defining our function outside of the useEffect while including it in the dependency array will cause an infinite re-render</figcaption></figure><h3><strong>Enter the useCallback Hook</strong></h3><p>In short, the useCallback hook allows you to cache, or ‘memoize,’ a function between re-renders of your component. It performs a similar task to useMemo, the nuances of which we will get into in a different article.</p><p>If the nitty-gritty of this interests you, you can read more in the <a href="https://beta.reactjs.org/apis/react/useCallback">React docs</a>.</p><p>Please notice their warning:</p><blockquote>You should only rely on <em>useCallback</em> as a performance optimization. If your code doesn’t work without it, find the underlying problem and fix it first. Then you may add <em>useCallback</em> to improve performance.</blockquote><h3><strong>useCallback Syntax</strong></h3><p>useCallback’s syntax is very similar to the useEffect’s syntax which we already know. Look at the skeletons of each.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TkWf8Bq4erHq3aWlauosOQ.png" /><figcaption>the two hooks have identical syntactical skeletons</figcaption></figure><p>The slight difference is with useEffect, we tell the anonymous function to <strong>execute our function</strong> while with useCallback, we assign the <strong>return</strong> <strong>value</strong> to a reference to be called elsewhere.</p><h3>Using useCallback</h3><p>First, we will import useCallback from &#39;react&#39;. Rather than adding a new line, it’s best to destructure it along with our other imports.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DswQIQ0yvrnOFJ6yPUrOgA.png" /><figcaption>items destructured from the same package are best imported on the same line</figcaption></figure><p>Now we can assign getBookDetails to the value returned from a useCallback function call.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hfWcIKiiSz_1qJw3Esagkw.png" /><figcaption>assign useCallback’s return to our reference</figcaption></figure><p>Then we add all the syntax for useCallback. Remember your dependency array!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VRvu8qAjOiI9ihHUkP4jDA.png" /><figcaption>fill in useCallback’s skeleton</figcaption></figure><p>In our example, we need async before our parameters.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KEOV3l3DZzATjnwXMvC3EQ.png" /><figcaption>add async</figcaption></figure><p>And finally, we add the logic of our function into the code block.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ylu4qKTDgNd8zmFKIEEQ3g.png" /><figcaption>add our logic to useCallback’s code block</figcaption></figure><p>Once we save, we get… another WARNING .</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8kHvG5BIE4kswLo0seEzKQ.png" /><figcaption>useCallback’s return depends on the value of id</figcaption></figure><p>Why should our dependency array track the id variable?</p><p>Let’s think through this.</p><ul><li>If the value of id changes, getBookDetails needs to hit a different endpoint, so React should redefine it. The definition of getBookDetails literally <strong>depends</strong> on the value of id .</li></ul><p>After we add id to our dependency array, our finished getBookDetails and useEffect functions should look like this. Look closely at the differences between the way we implement the two hooks.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c3bIRxI9-1uQ_hAMW4iKSg.png" /><figcaption>finished versions of both hooks</figcaption></figure><p>And finally, that’s it! We see green in our React dev server. A happy linter is a happy Senior Developer. And a happy Senior Developer is a happy you!</p><blockquote>I’m always looking for new friends and colleagues. If you found this article helpful and would like to connect, you can find me at any of my homes on the web.</blockquote><blockquote><a href="https://github.com/austin-rt">GitHub</a> | <a href="https://twitter.com/0xstink">Twitter</a> | <a href="https://www.linkedin.com/in/austinrt">LinkedIn</a> | <a href="https://austinrt.io">Website</a></blockquote><h3><strong>Resources</strong></h3><ul><li><a href="https://www.freecodecamp.org/news/how-to-get-a-grip-on-reference-vs-value-in-javascript-cba3f86da223/">Referential Equality</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Glossary/Primitive">JavaScript Primitive Data Types vs. Data Structures</a></li><li><a href="https://stackify.com/oop-concept-for-beginners-what-is-encapsulation/">Encapsulation</a></li><li><a href="https://beta.reactjs.org/apis/react/useCallback">useCallback</a></li><li><a href="https://beta.reactjs.org/learn/synchronizing-with-effects#step-2-specify-the-effect-dependencies">React Docs</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7c78fac08947" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>