<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Brett Thurston</title>
    <description>The latest articles on DEV Community by Brett Thurston (@brettthurs10).</description>
    <link>https://dev.to/brettthurs10</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%2F211803%2F190327e8-eb33-4b0c-a4c1-10d6317e43cc.jpg</url>
      <title>DEV Community: Brett Thurston</title>
      <link>https://dev.to/brettthurs10</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brettthurs10"/>
    <language>en</language>
    <item>
      <title>How I built my AI powered book insights app</title>
      <dc:creator>Brett Thurston</dc:creator>
      <pubDate>Tue, 17 Oct 2023 18:35:27 +0000</pubDate>
      <link>https://dev.to/brettthurs10/how-i-built-my-ai-powered-book-insights-app-be7</link>
      <guid>https://dev.to/brettthurs10/how-i-built-my-ai-powered-book-insights-app-be7</guid>
      <description>&lt;h3&gt;
  
  
  Brief introductions
&lt;/h3&gt;

&lt;p&gt;Hi, my name is Brett Thurston. I'm a developer and maker who enjoys working in the front-end spectrum of development and design. I've made an app and wanted to recap some highlights and lessons learned from my journey so far. I'd like to post more frequent updates on working on Book Scout.&lt;/p&gt;

&lt;p&gt;I hope this will interest you, the reader, and encourage you to share your journey in creating something, too. This isn't meant to be a tutorial, but more talking about the process and knowledge gained.&lt;/p&gt;

&lt;h3&gt;
  
  
  What did I just buy?
&lt;/h3&gt;

&lt;p&gt;My 15-year-old daughter and I were at a bookstore recently. She picked up a book she remembered her friend was reading and recommended to her. I took a look at the cover and read the blurb on the back of the book. After a passing moment I said, sure we'll get it. I purchased the book then and gifted it to her. On the way home my wife and I had a sneaking suspicion that the book probably deserved a little more investigation. After 30-45 minutes of researching Amazon reviews, Goodreads, and Common Sense Media it was decided that the book purchase was a mistake. The book was way, way too spicy (and dark) for what we believed was acceptable for her age. It pained me to return the book, but after explaining to her she agreed, that it was not the book for her, anyhow.&lt;/p&gt;

&lt;p&gt;At that moment I thought about a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Why can't books come with some movie-like-rating system?&lt;/strong&gt; Slap a sticker on there that says PG-13 and we're good to go. Rated R? May have to look into why it's rated R.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Why can't consumers have easier means to figure out if a book is for them or not?&lt;/strong&gt; I'm an avid reader myself and have spent countless hours over the years on Goodreads, Amazon reviews, and Reddit trying to decipher if a book will speak to me in ways I appreciate. For instance, I'm a big Fantasy fan, but Grim Dark is not my cup of tea. Give me the cheesy 90's fantasy books like Dragonlance any day of the week over Game of Thrones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What if I could have an infinite source that gives me just pertinent info on themes in books?&lt;/strong&gt; I'd like to know what positive/interesting themes are in books, as well as questionable themes (like trauma, dark content, etc...). Furthermore, it'd be nice to know if a book hangs its hat on using common tropes that I'd like to avoid. Wouldn't it be nice to know ahead of time if a book has something in it that puts it on the Did Not Finish List for me? Especially before I get halfway through it?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Light bulb moment
&lt;/h3&gt;

&lt;p&gt;That is where I had the idea for &lt;a href="https://bookscoutapp.com"&gt;Book Scout&lt;/a&gt;. I wanted to build this tool that could answer these questions for me and my family. If others benefit from it, then fantastic! If not, at least I have a project to work on and find some fulfillment in.&lt;/p&gt;

&lt;p&gt;And so now you're reading about this moment in my life. I think it may help us both to learn from one another how this app was built, what the process was, and the challenges I found along the way. I suppose you could call this a built-in-public type of post, but the app is already built and available to take for a spin. &lt;a href="https://apps.apple.com/us/app/book-scout/id6466491163"&gt;You can download it now at the Apple App Store.&lt;/a&gt; I'd be interested to hear your feedback on the app. It's not perfect, but it's usable. It's a start.&lt;/p&gt;

&lt;p&gt;So if you're interested in reading about process and mistakes made and victories end, read on friend!&lt;/p&gt;

&lt;p&gt;Have you built anything that solved a problem for you, your family or friends? Let me know in the comments below, please. :D&lt;/p&gt;

&lt;h3&gt;
  
  
  First things first: can the core feature work?
&lt;/h3&gt;

&lt;p&gt;Before I did a stitch of coding or a lick of design I knew I had to find out if I could get AI to do what I needed it to do: give me positive and negative insights on a book. I spent a few nights after work crafting up a prompt with &lt;a href="https://chat.openai.com/"&gt;ChatGPT&lt;/a&gt;. I checked out &lt;a href="https://bard.google.com/"&gt;Bard&lt;/a&gt;, but after comparing the results, I was happier with the ChatGPT experience. Not to mention, I couldn't get access to the Bard API.&lt;/p&gt;

&lt;p&gt;After getting my prompt, I had a hook. It worked. I was pretty impressed with what ChatGPT was able to give me in the data returned. This hook would be the thing that would make a user come back for more.&lt;/p&gt;

&lt;p&gt;As an avid reader, I threw a lot of books that I've read to see how reliable the insights given were. And as it turned out it was very reliable. The themes it highlighted were found in the books that I read. Wow, so this could work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proof of concept
&lt;/h3&gt;

&lt;p&gt;Pardon my brief sidebar into &lt;a href="https://docs.expo.dev/tutorial/create-your-first-app/"&gt;React Native Expo&lt;/a&gt;: I've built React Native apps before, but never with Expo. Expo has come a long way since I first started working with React Native, which was back in early 2019. After reading up on Expo I found that it still handles a lot of the binary native stuff related to mobile app development. And ejecting out of Expo was a big topic back in 2019/2020 but now you don't have to eject out of it since it has the prebuild feature. This essentially builds the rest of the project out as if it were a full-on React Native project. Expo isn't without it's limitations, but I liked that I could focus more on the app and less on the scaffolding of it. So far it hasn't presented a lot of limitations for this project. Expo has a ton of libraries available to help tap into the native features of devices.&lt;/p&gt;

&lt;p&gt;Projects that rely heavily on native device features and work with the native code will have a harder time with Expo.&lt;/p&gt;

&lt;p&gt;So I spun up a React Native Expo project. I started making API calls to ChatGPT to see if I could give it a book title and author. And I got the insights that I wanted. Everything then started flowing into prototyping the UI for an app idea. I chose React Native Paper since it's a React Native component library powered by the MUI component library (a favorite of mine). Now I could begin building a core version of Book Scout.&lt;/p&gt;

&lt;h3&gt;
  
  
  API
&lt;/h3&gt;

&lt;p&gt;I wanted to display metadata for the book you would search for. I started using both Google Books API and a web scraping method I found using Cheerio and Axios on Amazon product pages. &lt;a href="https://www.freecodecamp.org/news/how-to-scrape-websites-with-node-js-and-cheerio/"&gt;You can read more about web scraping here at FreeCodeCamp.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I gotta say, hats off to those who web scrape regularly because it sometimes can feel like a needle in a haystack finding the right class selector for DOM elements - PLUS making it consistently selected. I started drafting in my React Native app this page of book details and insights. It was a combination of ChatGPT, web scraper and Google Books API call. It was messy. The web scraping factor produced very inconsistent results.&lt;/p&gt;

&lt;p&gt;After a few days of trying to make this setup work, I decided to focus on Google Books API and ChatGPT API calls. Amazon offered cool data like related books, popular highlights (quotes people often highlight in their Kindle app), author bios, recommended books, etc... Looking back it was a good call to start small and have a sturdy foundation. An app should do the thing it advertises well every time the user uses it. If not, trust erodes and usage is hurt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taking advantage of mobile device features
&lt;/h3&gt;

&lt;p&gt;After some time crafting a page to capture insights and metadata about a book I began to wonder, what about this app makes it worthy to be an app? Naturally being available on a mobile device is one advantage. But that was all I had at the time. That led me to think well, this could just be a website. And that's true, it could be. But thought back to that day with my daughter in the bookstore. What if I could use my device to capture the book I wanted insights about quickly? Of course, we'll use barcode scanning in the app. &lt;a href="https://docs.expo.dev/versions/latest/sdk/bar-code-scanner/"&gt;Fortunately, Expo had a library just for that&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now I was able to make a modal in my app, scan a barcode and use the ISBN to search Google Books API for the metadata. Sweet! I was scanning newly published books, but then I realized older books I was getting two types of errors from Google Books API. The first would be an error where the ISBN given returned a different book. The second error was nothing was returned from the API to Google Books, period.&lt;/p&gt;

&lt;p&gt;After some research, I realized the ISBN and the UPC don't always match up. A lot of newly released books seem to match the two, but in older books, especially, you'll find the ISBN and the UPC are different. So where I thought I was sending Google Books API my ISBN, I was sending my UPC. Oof.&lt;/p&gt;

&lt;p&gt;So now, I have to capture this use case in my bar code scanning feature. Otherwise, users won't have a seamless experience. So I thought, OK, we could show a modal that explains the ISBN didn't validate (meaning it was a UPC scanned). This modal could give the user the option to input the ISBN themselves or redirect the user to the Search feature. That worked well I thought and it's in the app today.&lt;/p&gt;

&lt;p&gt;It was a good exercise in moving beyond happy paths in app design. Because what's true for you won't always be true for every user and use case. My goal for v1 of Book Scout was to make sure there was at least a consistent experience despite all the use cases of searching or scanning books. I'm positive I have more use cases to capture, but they, to me, feel like very fringe use cases that won't impact the average user.&lt;/p&gt;

&lt;p&gt;That's why it's good to ship and iterate. Let your users help surface problems to you so you can address and fix them. Also, you won't sink a ton of time and resources into problems that aren't problems to your users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cache money, baby
&lt;/h3&gt;

&lt;p&gt;Speaking of moving beyond the happy path, I was also thinking about scaling this app at the foundations. That's why I chose to use &lt;a href="https://firebase.google.com/"&gt;Firebase&lt;/a&gt; to cache data created by API calls to return to users instead of making API calls to ChatGPT or Google Books API on every request. Caching data not only returns data faster for your users but can save on the cost of operating the project.&lt;/p&gt;

&lt;p&gt;So using Axios, I made an instance for each type of vendor I was using with initial headers set up. Then I created methods that checked Firebase for data before actually making the call to the vendor. This proved to be fruitful to begin with.&lt;/p&gt;

&lt;p&gt;The only gotcha I've seen is if you change the shape of your data, you'll need to wipe your old cache or adjust it to fit the shape you land on. It does not have a major impact on users if you wipe your database cache data, but could be expensive at scale.&lt;/p&gt;

&lt;p&gt;Do you have any advice on caching data or stories to share with your app? Please let me know in the comments below!&lt;/p&gt;

&lt;h3&gt;
  
  
  Bookshelves
&lt;/h3&gt;

&lt;p&gt;So to review, I've got an app that can search or scan for books and render book insights and metadata. This was an acceptable POC, in my opinion. I wanted to set my focus on delivering version 1. Something I can ask you to look at and you feel this is a whole product and not just a POC. I needed a minimal viable product.&lt;/p&gt;

&lt;p&gt;The app felt fleeting though. Like you scanned something, but that's it. What if users want to keep track of what they've scanned/searched for or even categorize those books into traditional reading buckets like 'Reading' and 'DNF' (Did Not Finish)?&lt;/p&gt;

&lt;p&gt;Throughout this project, I wanted to make sure I was studying book apps. I wanted to make sure I wasn't reinventing the wheel or solving problems that I don't need do if I just shifted left a little on approach. GoodReads lets you shelve books. Why couldn't Book Scout users do the same?&lt;/p&gt;

&lt;p&gt;So I created a history of books viewed and a book shelving system. The shelving system has 4 categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reading&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Completed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Want to Read&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Did Not Finish&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the future, I'm going to allow users to share their shelves with others, back them up into a cloud account of theirs and create custom shelves.&lt;/p&gt;

&lt;p&gt;Customer reviews for books&lt;/p&gt;

&lt;p&gt;Another feature I wanted to add was to grab the Amazon customer reviews and display them in the app. And after I did it, it didn't feel special or unique enough of a feature. Sure, it could help inform a user, in addition to the insights, what others were saying about the book, but what I wanted was to create keywords to track in the customer reviews. If the customer review had a keyword in it that I was tracking, highlight it for me.&lt;/p&gt;

&lt;p&gt;For instance, if I set the following keywords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;violence&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;gore&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;murder&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then any customer reviews that came in for a book that had those words in them would be easily identifiable in the app. The app itself doesn't care what your sentiment is around those keywords. I think this is a nice service for those who have experienced some sort of trauma in their life and may not want to read about it in their books.&lt;/p&gt;

&lt;h3&gt;
  
  
  Content moderation
&lt;/h3&gt;

&lt;p&gt;One thing that popped up in the beta phase was user-generated content. As a solo founder and developer I don't want to be responsible for moderating reviews my users create. At least not yet. I'm happy to pass that off to Amazon and their team to moderate the customer reviews.&lt;/p&gt;

&lt;p&gt;I'm keeping an eye on comments though and making sure I'm not seeing anything that would be unfit for a public app.&lt;/p&gt;

&lt;p&gt;Are you a solo developer with an app that has user-generated content? If so, how do you manage it? Let me know in the comments below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Theme and Presentation
&lt;/h3&gt;

&lt;p&gt;A lot of the visual notes were created with MidJourney. I never really got into generative AI, but working with MidJourney has been fun. I learned how to create prompts and tweak images to use in the app. I wanted to create the ambiance of discovering something new for the first time. To me, the works of Studio Ghibli and fantasy literature evoke that feeling. And that's what this help, I hope, can help be a part of with the experience the users are looking for: the feeling of finding something new and wanted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beta phase
&lt;/h3&gt;

&lt;p&gt;So I had a working app that I was now ready to get feedback from someone. I focused on the iOS platform first since a lot of people I know have it. Ironically, I'm an Android user, but I own and prefer my Macbook. There are probably, literally 10's of us out there.&lt;/p&gt;

&lt;p&gt;So I set up my App Store Connect with Apple. &lt;a href="https://developer.apple.com/app-store-connect/"&gt;You can read more on what that is here.&lt;/a&gt; Then I used 'eas build' from Expo to bundle my app for me. Then I used Transporter to send the bundled file (.ipa) to App Store Connect. After that, I made a beta group and invited a lot of my close friends and family to test the app out on their iPhones. I got some good feedback from that and added much-needed polish like loading states and further optimizations to API calls.&lt;/p&gt;

&lt;p&gt;Eventually, I got to the point where a strong version 1 was there. After 2 months of lots of late nights, I was ready to submit to Apple for approval.&lt;/p&gt;

&lt;p&gt;And I got denied on my first submission, haha.&lt;/p&gt;

&lt;p&gt;What happened was there was a button on the book page that found the book on Amazon and linked it directly with a tag in the URL related to my Amazon Associates account. Apple isn't keen on allowing their users to purchase things outside of their in-app payment system. So I removed the direct link button to the book you were viewing button and it was approved! Huzzah!&lt;/p&gt;

&lt;h3&gt;
  
  
  Social marketing for this app
&lt;/h3&gt;

&lt;p&gt;I'm not a strong social media user. I've tried in the past, but I think, like many people of my generation (elder millennials), I want to exist in a small, trusted niche community. I don't have a TikTok, I used to post on Twitter a lot, but it was Tech Twitter and just an attempt to learn, develop clout and build community. I deleted my Facebook about 5 years ago and haven't missed it. Facebook groups were nice though. I digress.&lt;/p&gt;

&lt;p&gt;So how does a non-social media person tell others about their product? I'm in the middle of that process right now, but I plan to focus on Instagram right now. Bookstagram is a big thing there. I haven't had the opportunity to put the gas on posting content, but there are posts there. &lt;a href="https://www.instagram.com/getbookscout/"&gt;You can see the Book Scout Instagram here.&lt;/a&gt; Give me a follow if you'd like!&lt;/p&gt;

&lt;p&gt;My plan for social content is a few things&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Post sample insights from the app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Post things about the app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Post bookish things (have yet to do)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Post generative art about made-up short stories (filler content)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't have much to say about this part of the process other than consistency wins and it's hard to do that solo, lol. Eventually, I'll wise up and consider hiring someone to talk about Book Scout, but for now, I'm making due.&lt;/p&gt;

&lt;p&gt;What I do feel though is nobody is going to know about your product if you don't talk about it. So I'm finding out what that looks like now. Future posts on this, there will be, I'm sure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Thanks for reading this recap of my day 1 to day 62 with version 1 of Book Scout. I have a lot of interesting optimizations and features in the works for the app. I hope that it can be a service to those readers who are curious about what's in the next book they want to read.&lt;/p&gt;

&lt;p&gt;The next phase is to start to understand a target audience to help the app grow. The target audience will not only help refine the app but also inform me about where to go and what to do next (aside from my itinerary).&lt;/p&gt;

&lt;p&gt;I hope that sharing my journey so far can help inspire or encourage you to go and build that thing you've always wanted to build. The projects we make will not be loved by all and may not make it to superstardom, but there is a sense of accomplishment and fulfillment I get with working on Book Scout that I haven't found elsewhere as a serial entrepreneur.&lt;/p&gt;

&lt;p&gt;And speaking of entrepreneurship, depending on the market fit of this app, I'll need to think of how to make this profitable beyond mobile ads. But that is a tomorrow problem that I'll address another day.&lt;/p&gt;

&lt;p&gt;If I could do it differently, I would have focused on the core feature first and worked with the minimum amount of API vendors possible. There was a stretch there where I didn't know what I wanted to get out of the API calls. I think when you limit yourself, it's easier to prove a concept instead of juggling a lot of balls to get the vision established.&lt;/p&gt;

&lt;p&gt;Thanks for reading again and I'm looking forward to posting more about the process in the future.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>ai</category>
      <category>learning</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Prevent Acid Redux with Redux Toolkit</title>
      <dc:creator>Brett Thurston</dc:creator>
      <pubDate>Tue, 14 Jun 2022 21:23:35 +0000</pubDate>
      <link>https://dev.to/brettthurs10/prevent-acid-redux-with-redux-toolkit-p7g</link>
      <guid>https://dev.to/brettthurs10/prevent-acid-redux-with-redux-toolkit-p7g</guid>
      <description>&lt;p&gt;Want to learn how to manage a single source of truth for your application? &lt;/p&gt;

&lt;p&gt;This post is going to help you get rid of the acid Redux associated with trying to use vanilla &lt;a href="https://redux.js.org/"&gt;Redux&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Acid Redux, for those who have never suffered it, is when you attempt to learn vanilla Redux and you start drowning in indigestion, trying to figure out the complexity and boilerplate. Maybe that's not exactly how it happened to me, but I prefer Redux Toolkit (RTK). &lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://redux-toolkit.js.org/"&gt;Redux Toolkit&lt;/a&gt; is a tool that abstracts a lot of the heavy lifting associated with Redux. &lt;/p&gt;

&lt;p&gt;Before that let's dig into what Redux is and who gave it to us. &lt;/p&gt;

&lt;p&gt;Redux is an immutable way to manage state across an application and to keep track of what happened and when. &lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/gifs/arthur-dw-read-8vFgV67ip5bkk" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--2ZeaS7ax--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media1.giphy.com/media/8vFgV67ip5bkk/giphy.gif%3Fcid%3D790b76118d297338b0594d2919f0d3f45b939fe20bbb3fd4%26rid%3Dgiphy.gif%26ct%3Dg" height="245" class="m-0" width="245"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/gifs/arthur-dw-read-8vFgV67ip5bkk" rel="noopener noreferrer" class="c-link"&gt;
          Arthur Dw Read GIF - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Arthur GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnkhlOxW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://giphy.com/static/img/favicon.png" width="16" height="16"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;This means any change to your app's state has to be intentional. And with each response of each action, we can keep track of when and where these responses to action happened.&lt;/p&gt;

&lt;p&gt;For the time travel part, check out the bottom of this article to see a video of Dan Ambramov himself talking about it. We'll be looking at how to use Redux via Redux Toolkit later in this article.&lt;/p&gt;

&lt;p&gt;When people ask me what Redux is, this is my response - a one-way circuit for users to affect data within an application in a clean, predictable manner.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5yCuOtkG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s1kkf99yieplrs2j8141.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5yCuOtkG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s1kkf99yieplrs2j8141.png" alt="Redux workflow" width="880" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Who gave us Redux?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://twitter.com/dan_abramov"&gt;Dan Abramov&lt;/a&gt; and &lt;a href="https://twitter.com/acdlite"&gt;Andrew Clark&lt;/a&gt; brought Redux to the world in 2015 and since 2016 the primary maintainers are &lt;a href="https://github.com/markerikson"&gt;Mark Erikson&lt;/a&gt; and &lt;a href="https://github.com/timdorr"&gt;Tim Dorr&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Abramov was working on a talk about hot reloading for a conference at React Europe. He's quoted on how the thought of Redux came to be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I was trying to make a proof of concept of &lt;a href="https://medium.com/@grover.vinayak0611/what-is-flux-architecture-why-facebook-used-it-and-the-comparison-with-mvc-architecture-49c01ed5d2e1"&gt;Flux&lt;/a&gt; where I could change the logic. And it would let me time travel. And it would let me reapply the future actions on the code change. I was thinking about Flux as a reduce operation over time... your stores, they accumulate state in response to these actions. I was thinking of taking this further. What if your Flux store was not a store but a reducer function?"" - Dan Abramov&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, Abramov was taking lessons learned with Flux, which is a way to build a single page application Facebook developed, and apply it to a data store. But going beyond that, instead of being a data store, how could it be a reducer function?&lt;/p&gt;

&lt;p&gt;Before Redux we would have to prop drill which one layer deep is fine, but passing props to 5-6 layers deep to components is a chore.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why state management?
&lt;/h2&gt;

&lt;p&gt;It's no surprise for anyone new to React that state can slip away from you after each render. React components work in harmony with one another with previous and next state and unique keys to keep state in check with each other. React, or any other JS library is great about only rendering what needs to be rendered. What if you could hook your app up to a brain and that was the source of truth and knowledge for your app? State management libraries like Redux are great for that. Before state management libraries were a thing we would have to prop drill. Meaning going down many layers of components to pass information to a great, great, great-grandchild component. You can see how much of a chore that becomes, not to mention some other state can slip away in that scenario.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reducers are the future
&lt;/h2&gt;

&lt;p&gt;Some of you have seen the word reducer in programming or even used it with a Redux application. Conceptually speaking a reducer looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const reducer = (currentState, action) =&amp;gt; newState;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A reducer takes in the current state and an action as two arguments. Then it gives you a brand new state based on those two things. In other words, we are dictating through the &lt;strong&gt;action ** how we are going to affect the **state&lt;/strong&gt;. And then we are given a brand new state to use. This becomes our source of truth for other functions, actions, components for the rest entire app, etc...&lt;/p&gt;

&lt;p&gt;For a deeper dive into reducers in JS, I recommend this stellar &lt;a href="https://dev.to/reedbarger/what-is-a-reducer-in-javascript-a-complete-introduction-with-examples-ip1"&gt;article&lt;/a&gt; by Reed Barger.&lt;/p&gt;
&lt;h2&gt;
  
  
  Mutate safely
&lt;/h2&gt;

&lt;p&gt;Before RTK we would want to spread state and our modified value like this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Reducing the old way&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const subtractCountBy = (state, action) =&amp;gt; {
    const newNumber = state.value - action.payload
    return {
        ..state,
        ... {
            value: newNumber
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Thanks to RTK when we create a slice via &lt;a href="https://redux-toolkit.js.org/api/createslice/"&gt;createSlice&lt;/a&gt;, it handles merging our changes into state for us via useReducer. So we can mutate state safely without a care in the world like so:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Reduce RTK the new way&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const subtractCountBy = (state, action) =&amp;gt; {
    state.value -= action.payload;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Enough of the brief history lesson, now let's go over how we use Redux Toolkit to be the brain of our app.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/gifs/startrek-star-trek-voyager-seven-of-nine-VhpuNI1KejNbBGXCxS" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--jMF4ed2L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media2.giphy.com/media/VhpuNI1KejNbBGXCxS/giphy.gif%3Fcid%3D790b7611a769c7bde5a36a268c1a33ac987bf05319933a1f%26rid%3Dgiphy.gif%26ct%3Dg" height="363" class="m-0" width="480"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/gifs/startrek-star-trek-voyager-seven-of-nine-VhpuNI1KejNbBGXCxS" rel="noopener noreferrer" class="c-link"&gt;
          Shall We Begin Star Trek Voyager GIF by Star Trek - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Star Trek GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnkhlOxW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://giphy.com/static/img/favicon.png" width="16" height="16"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Using Redux Toolkit
&lt;/h2&gt;

&lt;p&gt;First, install redux toolkit into your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @reduxjs/toolkit react-redux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note I'll be copying and pasting from the official docs, but adding flavor where I can. Also, you can use TypeScript, but to present the process to a larger collective, I'll be using JS.&lt;/p&gt;

&lt;p&gt;Then we need to create the store for our app to use. Name it store.js:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;app/store.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { configureStore } from '@reduxjs/toolkit'

export const store = configureStore({
  reducer: {},
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This creates a Redux store and allows to view what's in the store via the &lt;a href="https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd"&gt;Chrome Redux  Dev Tools&lt;/a&gt; extension.&lt;/p&gt;

&lt;p&gt;Now we will connect our components to the Redux store by wrapping a provider around it with the store as a prop.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;index.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { store } from './app/store'
import { Provider } from 'react-redux'

ReactDOM.render(
  &amp;lt;Provider store={store}&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/Provider&amp;gt;,
  document.getElementById('root')
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we are ready to create a slice. Not a pizza slice, but a slice of data that will be an ambassador to our data store. This slice will have its JS file dedicated to the initial state and the actions to do transactions with that slice.&lt;/p&gt;

&lt;p&gt;I like to co-locate my slice with the main component that will be utilizing its actions. In this case, we are putting the counterSlice.js file into the counter folder, within the features folder.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/counterSlice.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSlice } from '@reduxjs/toolkit'

const initialState = {
  value: 0,
}

export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) =&amp;gt; {
      // Redux Toolkit allows us to write "mutating" logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a "draft state" and produces a brand new
      // immutable state based off those changes
      state.value += 1
    },
    decrement: (state) =&amp;gt; {
      state.value -= 1
    },
    incrementByAmount: (state, action) =&amp;gt; {
      state.value += action.payload
    },
  },
})

// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions

export default counterSlice.reducer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's break this file down a bit before moving forward:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/counterSlice.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSlice } from '@reduxjs/toolkit'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We are importing the createSlice function provided by Redux Toolkit. According to the docs, this function accepts the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an initial state&lt;/li&gt;
&lt;li&gt;an object of reducer functions&lt;/li&gt;
&lt;li&gt;a "slice name"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it automatically generates action creators and action types that correspond to the reducers and state. In other words does a lot of the wiring up for us to make transactions with our store via the slice.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/counterSlice.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const initialState = {
  value: 0,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We make a const called initialState whose value is an object that stores key/value pairs for us.&lt;/p&gt;

&lt;p&gt;The initial state is set when the user first interacts with the app. Only when an action is dispatched will this value change.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/counterSlice.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const counterSlice = createSlice({
**  name**: 'counter',
**  initialState**,
**  reducers**: {
    increment: (state) =&amp;gt; {
      // Redux Toolkit allows us to write "mutating" logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a "draft state" and produces a brand new
      // immutable state based off those changes
      state.value += 1
    },
    decrement: (state) =&amp;gt; {
      state.value -= 1
    },
    incrementByAmount: (state, action) =&amp;gt; {
      state.value += action.payload
    },
  },
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here we are using the createSlice method we imported higher up in the slice file. We are then passing 3 arguments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the name of what the slice should be referred to in or app&lt;/li&gt;
&lt;li&gt;the initialState object we made earlier&lt;/li&gt;
&lt;li&gt;the reducer(s) (or action(s)) we want to create and later affect change to our data store&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see we are preparing 3 reducers named increment, decrement, and incrementByAmount. &lt;/p&gt;

&lt;p&gt;The first two reducers are simple actions that take no value from the user. We are just simply passing in the current state and changing that state directly by either adding or subtracting by 1 increment.&lt;/p&gt;

&lt;p&gt;The 3rd reducer incrementByAmount takes in the current state, and an action we want to do. The payload (or result) of that action is then assigned to the value property in our state.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/counterSlice.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const { increment, decrement, incrementByAmount } = counterSlice.actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then we are make the 3 reducers we created higher up in the file available to the entire app by destructing the actions property on the counterSlice const we made.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/counterSlice.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default counterSlice.reducer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And finally, the piece of the slice we want to automatically make available by default when importing this file is the reducer property RTK made for us.&lt;/p&gt;

&lt;p&gt;Checking in on you: are you good? Need some water? It's not complicated, stick with me :D&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/gifs/Bermemes-sips-tea-bermuda-david-burt-4Z4S2tSxp0nYSJeQis" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Kd26k00s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media0.giphy.com/media/4Z4S2tSxp0nYSJeQis/giphy.gif%3Fcid%3D790b7611a6e3f8d414535daffbd6618a4788ec25ad432b27%26rid%3Dgiphy.gif%26ct%3Dg" height="340" class="m-0" width="480"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/gifs/Bermemes-sips-tea-bermuda-david-burt-4Z4S2tSxp0nYSJeQis" rel="noopener noreferrer" class="c-link"&gt;
          Drink Water Drinking GIF by Bermemes - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Bermemes GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnkhlOxW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://giphy.com/static/img/favicon.png" width="16" height="16"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Let's bounce back to our store and let it know we have some reducers it can expect:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;app/store.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'

export const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now here is where we read from our store and change the data to our store. The grand finale to this not-so-complex workflow.&lt;/p&gt;

&lt;p&gt;Create a Counter.js file that will host an increment button, a decrement button, and something to render the value of the counter.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/Counter.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'

export function Counter() {
  const count = useSelector((state) =&amp;gt; state.counter.value)
  const dispatch = useDispatch()

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button
          aria-label="Increment value"
          onClick={() =&amp;gt; dispatch(increment())}
        &amp;gt;
          Increment
        &amp;lt;/button&amp;gt;
        &amp;lt;span&amp;gt;{count}&amp;lt;/span&amp;gt;
        &amp;lt;button
          aria-label="Decrement value"
          onClick={() =&amp;gt; dispatch(decrement())}
        &amp;gt;
          Decrement
        &amp;lt;/button&amp;gt;
&amp;lt;span&amp;gt;
 &amp;lt;input
          value={incrementAmount}
          onChange={e =&amp;gt; setIncrementAmount(e.target.value)}
        /&amp;gt;
        &amp;lt;button
          onClick={() =&amp;gt;
            dispatch(incrementByAmount(Number(incrementAmount) || 0))
          }
        &amp;gt;
          Add Amount
        &amp;lt;/button&amp;gt;
&amp;lt;/span&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's go over this line by line, and then we'll be wrapping up.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/Counter.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here we are importing two hooks and two actions. The first pair of imports comes from 'react-redux' and the second pair comes from our counterSlice slice file.&lt;/p&gt;

&lt;p&gt;useSelector is a nice hook that lets the component monitor the value we assign to our const.&lt;/p&gt;

&lt;p&gt;Let's look a bit further down and see how we use it in the component:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/Counter.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const count = useSelector((state) =&amp;gt; state.counter.value)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We invoke the useSelector which is equivalent to the mapStateToProps to connect our component to the data store. If you don't know the mapStateToProps process, it's the vanilla equivalent of using this hook, but more complex and lengthier to do. Thanks to RTK we have useSelector.&lt;/p&gt;

&lt;p&gt;So the const count now fetches the state from the store and returns the value of &lt;strong&gt;value&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's get back to our imports and look at useDispatch. useDispatch is what we use to call the reducer(s) that we've made in our counterSlice. Since we've exported them, we are importing them here.&lt;/p&gt;

&lt;p&gt;Jumping further into the component code check this out:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/Counter.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dispatch = useDispatch()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here we are just saying the const dispatch is the useDispatch hook.&lt;/p&gt;

&lt;p&gt;This is how we will change our app's state so all components can be made aware.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/Counter.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button
          aria-label="Increment value"
          onClick={() =&amp;gt; dispatch(increment())}
        &amp;gt;
...
&amp;lt;button
          aria-label="Decrement value"
          onClick={() =&amp;gt; dispatch(decrement())}
        &amp;gt;
          Decrement
        &amp;lt;/button&amp;gt;
...
 &amp;lt;button
          onClick={() =&amp;gt;
            dispatch(incrementByAmount(Number(incrementAmount) || 0))
          }
        &amp;gt;
          Add Amount
        &amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We assign the onClick attributes to an anonymous function that fires the dispatch hook and takes the action function we designate along for the ride.&lt;/p&gt;

&lt;p&gt;Notice how we are passing the state variable incrementAmount to the incrementByAmount reducer? This is where our reducer is seeing a specified action, making the action happen, and returning the payload so we can make a new state object for our store to use.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/gifs/darth-vader-disney-star-wars-K9yzeKyvvva9i" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--kDlrUYnV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media2.giphy.com/media/K9yzeKyvvva9i/giphy.gif%3Fcid%3D790b7611680259430bbf7f837f543be3ed5bdcb42a65db59%26rid%3Dgiphy.gif%26ct%3Dg" height="267" class="m-0" width="500"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/gifs/darth-vader-disney-star-wars-K9yzeKyvvva9i" rel="noopener noreferrer" class="c-link"&gt;
          Star Wars Disney GIF - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Darth Vader GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnkhlOxW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://giphy.com/static/img/favicon.png" width="16" height="16"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Then finally in our span element, we are using the count const to show the real-time value of the property **value **in our store.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;features/counter/Counter.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span&amp;gt;{count}&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For a full working app of what we've covered in this article, check out the sandbox from RTK &lt;a href="https://codesandbox.io/s/github/reduxjs/redux-essentials-counter-example/tree/master/?from-embed"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hot dang, you read this far? Congrats
&lt;/h2&gt;

&lt;p&gt;In summary, you've learned about what Redux is, where it started and how it's been made even easier to use thanks to Redux Toolkit. I know it was a long read, but thought it would be helpful to cover line by line. &lt;/p&gt;

&lt;p&gt;I hope you try using RTK in your next application and discover what it's like to have a source of truth for all your components in your app. It makes development much faster once you get used to using it.&lt;/p&gt;

&lt;p&gt;For bonus points, I recommend reading up on the &lt;a href="https://immerjs.github.io/immer/produce/"&gt;produce&lt;/a&gt; method from &lt;a href="https://immerjs.github.io/immer/"&gt;immer&lt;/a&gt;, with RTK, to analyze/change/replace state before it even hits the data store. Thankfully immer, an immutable library, is already included with your RTK install.&lt;/p&gt;

&lt;p&gt;Other items to check out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=xsSnOQynTHs"&gt;Dan Abramov - Live React: Hot Reloading with Time Travel at react-europe 2015&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/_shA5Xwe8_4"&gt;Redux in 100 Seconds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/reedbarger/what-is-a-reducer-in-javascript-a-complete-introduction-with-examples-ip1"&gt;What Is a Reducer in JavaScript? A Complete Introduction with Examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://redux-toolkit.js.org/introduction/getting-started"&gt;Redux Toolkit Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Redux_(JavaScript_library)"&gt;Redux Wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading! Please let me know if I've presented any information incorrectly in the comments below (or kudos are appreciated too). &lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/gifs/bear-hello-waving-IThjAlJnD9WNO" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--RPV71zKA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media2.giphy.com/media/IThjAlJnD9WNO/200.gif%3Fcid%3D790b76119b422b33baba20afdda5ca3f70deea5f08ce3894%26rid%3D200.gif%26ct%3Dg" height="200" class="m-0" width="266"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/gifs/bear-hello-waving-IThjAlJnD9WNO" rel="noopener noreferrer" class="c-link"&gt;
          Bom Dia Hello GIF - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Hello GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnkhlOxW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://giphy.com/static/img/favicon.png" width="16" height="16"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>react</category>
      <category>redux</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Prevent re-renders with useRef</title>
      <dc:creator>Brett Thurston</dc:creator>
      <pubDate>Wed, 25 May 2022 21:15:48 +0000</pubDate>
      <link>https://dev.to/brettthurs10/prevent-re-renders-with-useref-1fgf</link>
      <guid>https://dev.to/brettthurs10/prevent-re-renders-with-useref-1fgf</guid>
      <description>&lt;p&gt;There may be times when you don't want to trigger renders when capturing data from the user. useState, by now, is a well known and handy hook since it was implemented in React 16.8. When setting our state variable with useState, it causes a render of your component. When we use  &lt;a href="https://reactjs.org/docs/hooks-reference.html#useref" rel="noopener noreferrer"&gt;useRef&lt;/a&gt; to persistently store information, it doesn't cause a render.&lt;/p&gt;

&lt;p&gt;If you want to see the source code: &lt;a href="https://github.com/BrettThurs10/useRefVersuseState" rel="noopener noreferrer"&gt;https://github.com/BrettThurs10/useRefVersuseState&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to follow along in your browser:&lt;br&gt;
&lt;a href="https://brettthurs10.github.io/useRef-vs-useState/" rel="noopener noreferrer"&gt;https://brettthurs10.github.io/useRef-vs-useState/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dev note: The app is written in TypeScript, but only lightly so. If you're not use to TypeScript just ignore the parts that are unfamiliar, the business logic is the same. Having said that, now is a great time to learn &lt;a href="https://www.youtube.com/watch?v=d56mG7DezGs" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Dev note: As of React 18 components render twice by default if your  is wrapped with . For this demo I've removed  from the code base.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Jump to the &lt;a href="https://github.com/BrettThurs10/useRefVersuseState/blob/main/src/RefComponent/RefComponent.tsx" rel="noopener noreferrer"&gt;RefComponent.tsx&lt;/a&gt; file and follow along:&lt;/p&gt;
&lt;h2&gt;
  
  
  Set the &lt;del&gt;stage&lt;/del&gt; state
&lt;/h2&gt;

&lt;p&gt;To make the a ref simply import it and declare it as a variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {useRef} from React;
...
  const dataRef = useRef("🥧");
  const inputRef = useRef&amp;lt;HTMLInputElement&amp;gt;(null);
  const timesRendered = useRef(0);
  const [inputString, setInputString] = useState("🍕");
...
}
export default RefComponent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I'm setting the pie emoji as the initial value for the dataRef constant.&lt;br&gt;
I'm also making a state variable called inputString and setting that to the pizza emoji.&lt;/p&gt;
&lt;h2&gt;
  
  
  Update your ref
&lt;/h2&gt;

&lt;p&gt;Once you've declared the dataRef you can update it by assigning a value to it's property 'current'. This could be any &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Primitive" rel="noopener noreferrer"&gt;primitive&lt;/a&gt; type, object or function.&lt;/p&gt;

&lt;p&gt;In my method updateDataRef() this is where I'm doing just that.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const updateDataRef = (e: ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
    dataRef.current = e.target.value;
    console.log(dataRef.current);
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I then take the first input element and set the onChange attribute to that &lt;strong&gt;updateDataRef&lt;/strong&gt;. Now whenever we type in it will take the value and update the ref for us.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/embed/ry16t3EfWpD3O" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2Fry16t3EfWpD3O%2F200.gif%3Fcid%3Ddda24d506plmszwm75d2hjs2pyvaevatoy2ui208jpxch42s%26ep%3Dv1_internal_gif_by_id%26rid%3D200.gif%26ct%3Dg" height="200" class="m-0" width="302"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/embed/ry16t3EfWpD3O" rel="noopener noreferrer" class="c-link"&gt;
          Macho Man Hulk Hogam GIF - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Animated GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;I also make a handleOnChange() method to update the state variable stringInput for us, too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const handleOnChange = (e: ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
    setInputString(e.target.value);
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Likewise, I attach that to the 2nd input handling the inputString state variable. Whenever we type into that input element it WILL cause a re-render.&lt;/p&gt;
&lt;h2&gt;
  
  
  Monitor for changes to state
&lt;/h2&gt;

&lt;p&gt;I've made the method whereFromMsg() to monitor from which useEffect code block the render is coming from. I put it into two useEffects that are listening to the dataRef and inputString variables to change.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  useEffect(() =&amp;gt; {
    updateTimesRendered();
    renderMsg("dataRef useEffect");
    whereFromMsg("dataRef", dataRef.current);
  }, [dataRef]);

  useEffect(() =&amp;gt; {
    updateTimesRendered();
    renderMsg("inputString useEffect");
    whereFromMsg("inputString", inputString);
    // uncomment to see how useRef can capture the previous state, but not current. i.e. typing in dog in the useState input you will see 'dog' and in the useRef value you will see 'do'
    // dataRef.current = inputString;
  }, [inputString]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When they do, it will invoke 3 methods for me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;updateTimesRendered&lt;/li&gt;
&lt;li&gt;renderMsg&lt;/li&gt;
&lt;li&gt;whereFrom
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const updateTimesRendered = () =&amp;gt;
    (timesRendered.current = timesRendered.current + 1);

  const renderMsg = (fromWhere: string) =&amp;gt; {
    console.log(
      `✨ Component has rendered ${timesRendered.current} times and most recently from ${fromWhere}`
    );
  };

  const whereFromMsg = (type: string, value: string) =&amp;gt; {
    console.log(`${type} === ${value}`);
  };

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

&lt;/div&gt;


&lt;p&gt;Now we can see what is happening in the console.&lt;/p&gt;

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

&lt;p&gt;Whenever we type into either input we are seeing some message in console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhz5x3upqlq4sejnexqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhz5x3upqlq4sejnexqg.png" alt="Typing into inputs shows console log messages" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice when you type into the dataRef input, it only shows the value of dataRef.current. There is no message saying it's caused a render. Also notice how in the above screenshot the dataRef value in the UI is still set to the pizza emoji. That's because the component hasn't rendered yet. On any future render, it will update from pizza emoji to 'skateboard'.&lt;/p&gt;

&lt;p&gt;Go ahead and type in the 2nd input and you'll see that transaction happen.&lt;/p&gt;

&lt;p&gt;When we type into the inputString input we see a message it has rendered and the render counter increases in value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2zou9sopah6wmago85e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2zou9sopah6wmago85e.png" alt="InputString input shows console log" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Keep things in sync
&lt;/h2&gt;

&lt;p&gt;It's important to note that whenever we update a useRef variable our component UI won't know about it under another render happens.&lt;/p&gt;

&lt;p&gt;You can see what the previous state for dataRef by uncommenting the &lt;code&gt;dataRef.current = inputString&lt;/code&gt; line as shown below:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
    updateTimesRendered();
    renderMsg("inputString useEffect");
    whereFromMsg("inputString", inputString);
    // uncomment to see how useRef can capture the previous state, but not current. i.e. typing in dog in the useState input you will see 'dog' and in the useRef value you will see 'do'
    // dataRef.current = inputString;
  }, [inputString]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, when we type into the 2nd input we see both values change, but the dataRef value is not current. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajyqbwtf2punydj0hkag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajyqbwtf2punydj0hkag.png" alt="Screenshot showing values are not equal" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is because the ref will become current on a future render. But of course it may not be current with the inputString variable, should that update. Just to illustrate the point and help you keep things in sync. Use at your discretion.&lt;/p&gt;

&lt;p&gt;Bonus points:&lt;/p&gt;

&lt;p&gt;Clicking on the focus inputRef button will indeed set the 2nd input element to focus (drawing an outline around it). This is just shows how you can use the useRef hook and attach it to a DOM element to gain access to it directly.&lt;/p&gt;

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

&lt;p&gt;So next time you need to record some data without causing a re-render consider using useRef to help you out.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/embed/8vc2rMUDjhy6Y" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2F8vc2rMUDjhy6Y%2F200.gif%3Fcid%3Ddda24d50pdjlvxzq97i2w1wvydj8os9cvijq4ozkdbzxkwev%26ep%3Dv1_internal_gif_by_id%26rid%3D200.gif%26ct%3Dg" height="200" class="m-0" width="360"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/embed/8vc2rMUDjhy6Y" rel="noopener noreferrer" class="c-link"&gt;
          Goofy Movie Hello GIF - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Animated GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>react</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>✨ Conditional rendering in React with finesse</title>
      <dc:creator>Brett Thurston</dc:creator>
      <pubDate>Thu, 12 May 2022 13:44:37 +0000</pubDate>
      <link>https://dev.to/brettthurs10/conditional-rendering-in-react-with-finesse-5eod</link>
      <guid>https://dev.to/brettthurs10/conditional-rendering-in-react-with-finesse-5eod</guid>
      <description>&lt;p&gt;So if you've spent a measure of time with React you'll come across the scenario of needing to render an element based on a condition.&lt;/p&gt;

&lt;p&gt;For example, what if you had a component that counted something. And you wanted to show the actual count in a component. However, if it ever dropped below 1, you might want show a message in its place. Informing the user something or presenting a new call to action to do something else.&lt;/p&gt;

&lt;p&gt;You could write it in a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator"&gt;ternary operator&lt;/a&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from "react";
import RenderIf from "components/RenderIf";

export const Sample = () =&amp;gt; {
  const [count, setCount] = useState(2);
  const increment = () =&amp;gt; {
    let newCount = count;
    setCount((newCount += 1));
  };
  const decrement = () =&amp;gt; {
    if (count === 0) return;
    let newCount = count;
    setCount((newCount -= 1));
  };
  return (
    &amp;lt;&amp;gt;
      &amp;lt;button onClick={increment}&amp;gt;Add&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={decrement}&amp;gt;Subtract&amp;lt;/button&amp;gt;
       {count &amp;gt; 0 
           ? &amp;lt;p&amp;gt;I have {count}, and that's pretty cool.&amp;lt;/p&amp;gt;
           : &amp;lt;p&amp;gt;Sorry, I'm all out.&amp;lt;/p&amp;gt;
        }
    &amp;lt;/&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This works OK, but in my opinion doesn't read as easy as another option. What could a component look like to handle this use case?&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Proposal&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We can build a component that renders the content it wraps based on a condition we feed it. If that condition isn't true then we'll render something else. This will handle this use case with a little more finesse, IMO. 😎&lt;/p&gt;

&lt;p&gt;First let's make a component called RenderIf. Below are the JSX and TypeScript version. Pick your poison.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSX:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ReactNode } from "react";

const RenderIf = ({ children, isTrue, fallback }) =&amp;gt; {
  return isTrue ? children : fallback;
};

export default RenderIf;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;TypeScript:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ReactNode } from "react";

type Props = {
  children: ReactNode;
  isTrue: boolean;
  fallback?: any;
};

const RenderIf = ({ children, isTrue, fallback }: Props) =&amp;gt; {
  return isTrue ? children : fallback;
};

export default RenderIf;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Esplaining what's happenin'&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This component that we've made has 3 props being passed in: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;children&lt;/li&gt;
&lt;li&gt;isTrue&lt;/li&gt;
&lt;li&gt;fallback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment"&gt;destructure&lt;/a&gt; those props and pass them into the component. Children is whatever element this ** **component is wrapping. Then we pass the condition  of when to render the wrapped element with the isTrue prop. &lt;/p&gt;

&lt;p&gt;Whenever this condition is true (or &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Truthy"&gt;truthy&lt;/a&gt;) it will render the wrapped element. If the condition is NOT true, then it renders whatever we pass in the fallback argument. &lt;/p&gt;

&lt;p&gt;In TypeScript I've set this to be an &lt;a href="https://www.typescripttutorial.net/typescript-tutorial/typescript-optional-parameters/"&gt;optional argument&lt;/a&gt;in the type of Props. Why? I may not want to always pass a fallback element. So if I pass no fallback argument prop then &lt;strong&gt;&lt;/strong&gt; will return undefined and a blank component will render. &lt;/p&gt;

&lt;p&gt;In the JSX version of , this happens naturally.&lt;/p&gt;

&lt;p&gt;So your fallback argument can be a message saying, 'Hey you're out of counts' or it could be a button to buy more counts. You get the idea.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/gifs/jerology-tom-cruise-jerry-maguire-show-me-the-money-3oEdv22bKDUluFKkxi" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--jCmH_T1X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media0.giphy.com/media/3oEdv22bKDUluFKkxi/giphy.gif%3Fcid%3D790b76119e69f69dcc07e9d38be14afdce09a46786cf4b18%26rid%3Dgiphy.gif%26ct%3Dg" height="210" class="m-0" width="480"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/gifs/jerology-tom-cruise-jerry-maguire-show-me-the-money-3oEdv22bKDUluFKkxi" rel="noopener noreferrer" class="c-link"&gt;
          Jerry Maguire GIF by Jerology - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Jerology GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnkhlOxW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://giphy.com/static/img/favicon.png" width="16" height="16"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Example use in an app:&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from "react";
import RenderIf from "components/RenderIf";

export const Sample = () =&amp;gt; {
  const [count, setCount] = useState(2);
  const increment = () =&amp;gt; {
    let newCount = count;
    setCount((newCount += 1));
  };
  const decrement = () =&amp;gt; {
    if (count === 0) return;
    let newCount = count;
    setCount((newCount -= 1));
  };
  return (
    &amp;lt;&amp;gt;
      &amp;lt;button onClick={increment}&amp;gt;Add&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={decrement}&amp;gt;Subtract&amp;lt;/button&amp;gt;
      &amp;lt;RenderIf isTrue={count &amp;gt; 0} fallback={&amp;lt;p&amp;gt;Sorry, I'm all out.&amp;lt;/p&amp;gt;}&amp;gt;
        &amp;lt;p&amp;gt;I have {count}, and that's pretty cool.&amp;lt;/p&amp;gt;
      &amp;lt;/RenderIf&amp;gt;
    &amp;lt;/&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Go build some stuff&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;So now you've got a handy component you can use over and over again to render conditional elements in React. Maybe you want to extend this component to do other things too. What else could you see it do? Let me know what you think and if you'd take a different approach. &lt;/p&gt;

&lt;p&gt;Good luck and happy building. 🔨&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/gifs/hello-hi-wave-xT9IgG50Fb7Mi0prBC" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--SL_cGg5k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media1.giphy.com/media/xT9IgG50Fb7Mi0prBC/giphy.gif%3Fcid%3D790b7611ef8e26338d5028d5e556cee4a3de4449c92aa837%26rid%3Dgiphy.gif%26ct%3Dg" height="200" class="m-0" width="400"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/gifs/hello-hi-wave-xT9IgG50Fb7Mi0prBC" rel="noopener noreferrer" class="c-link"&gt;
          Tom Hanks Hello GIF - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Hello GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnkhlOxW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://giphy.com/static/img/favicon.png" width="16" height="16"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A snippy JS function to trim those long strings</title>
      <dc:creator>Brett Thurston</dc:creator>
      <pubDate>Fri, 05 Feb 2021 16:23:04 +0000</pubDate>
      <link>https://dev.to/brettthurs10/a-snippy-js-function-to-trim-those-long-strings-116h</link>
      <guid>https://dev.to/brettthurs10/a-snippy-js-function-to-trim-those-long-strings-116h</guid>
      <description>&lt;p&gt;In this article you'll find a method to use whenever you have a long string that may funk up your UI components. &lt;/p&gt;

&lt;p&gt;I was working on a list item component for a project and found a problem we run into a lot. What I have is a list of cards that bring in a title, publish date, and an episode description. Instead of manually trimming the string in the component itself, what if we could trim the string on the fly? This is especially useful when working with JS frameworks like React JS and Vue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa38faqhp502ort0lg0zr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa38faqhp502ort0lg0zr.png" alt="Screen Shot 2021-02-05 at 9.27.07 AM"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The description length of each episode will vary from each publication. I'm positive the descriptions will run past the limit I want them to in these card components. Then my list of cards will all have different heights. I like symmetry so I needed to trim these description strings on the fly. Here's how I did it and one of many different ways to do it.&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function truncate(string, characterLimit) {
/* first argument, pass in a string */
/* optional second argument: pass in a character 
      limit for this string. */
/* reminder: ?? is a nullish coalescing operator. 
      if we find that the 2nd argument passed in is 
      null or undefined, we default the character limit 
      to 160 characters */
  let limit = characterLimit ?? 160;
/* set up a variable called finalString to return at the end.  */
  let finalString;
/* if condition that asks if the string character count is 
       greater than or equal to the limit variable. if it is then 
       we want to remove everything after the number of the 
       limit set and append ellipse ("...") */
  if (string.length &amp;gt;= limit) {
    finalString = string.substring(0, limit);
    finalString = finalString + "...";
  } else {
/* if the string is less than or equal to the limit, let's go 
       ahead and pass the string by assigning it to our 
       finalString variable */
    finalString = string;
  }
  return finalString;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see what happens when we use this method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const shortDescription = "If a parsley farmer gets sued, can they garnish his wages?"

const longDescription = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ex ante, molestie eu nisl non, tempor rutrum tortor. Suspendisse ultricies odio ac turpis porta volutpat. Vestibulum rhoncus laoreet elit ut dictum. Ut id lorem ut ipsum cursus eleifend sed vitae dui. Mauris commodo elit at leo consectetur, ut blandit lacus laoreet. Vivamus placerat congue consectetur. Vivamus non nisi a tortor aliquet dictum. Sed ut condimentum nunc. In hac habitasse platea dictumst. Praesent id egestas libero. Vivamus sed tellus orci. Ut luctus mauris nunc, pulvinar bibendum urna dictum non. Duis bibendum commodo arcu, ut elementum diam vulputate vitae."

truncate(longDescription)
/* "Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
Etiam ex ante, molestie eu nisl non, tempor rutrum tortor. 
Suspendisse ultricies odio ac turpis porta v..." */

truncate(longDescription, 250)
/* "Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
Etiam ex ante, molestie eu nisl non, tempor rutrum tortor. 
Suspendisse ultricies odio ac turpis porta volutpat. Vestibulum 
rhoncus laoreet elit ut dictum. Ut id lorem ut ipsum cursus 
eleifend s..." */

truncate(shortDescription)
/* "If a parsley farmer gets sued, can they garnish his wages?" */

shortDescription.length
/* 58
58 is less than the default 160 limit, so the string is passed 
through unmodified */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So this function not only trims your long copy descriptions, but it also allows you to pass in a limit to override whatever default limit you set. This is super handy because now, you've written a function that becomes super nimble. For instance, I used the same truncate function in this fixed audio player bar I'm working on. Notice it's trimming the episode title.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhiwxd57ms9oizuy6ig9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhiwxd57ms9oizuy6ig9i.png" alt="Screen Shot 2021-02-05 at 10.02.55 AM"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Whenever you're writing your functions make sure they have one responsibility, but allow for customization as needed. &lt;/p&gt;

&lt;p&gt;So now you've got one way to trim a long description in the UI. You've seen how to write a function that considers future use in other areas of your program too.&lt;/p&gt;

&lt;p&gt;How would you handle this equation? Share your solutions below. &lt;/p&gt;

&lt;p&gt;Thanks for reading and happy snipping!&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@triconautes?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Les Triconautes&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/scissors-thread?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>react</category>
    </item>
    <item>
      <title>How to filter() your school lunch because nobody wants meatloaf</title>
      <dc:creator>Brett Thurston</dc:creator>
      <pubDate>Tue, 02 Feb 2021 05:30:42 +0000</pubDate>
      <link>https://dev.to/brettthurs10/how-to-filter-your-school-lunch-because-nobody-wants-meatloaf-57hb</link>
      <guid>https://dev.to/brettthurs10/how-to-filter-your-school-lunch-because-nobody-wants-meatloaf-57hb</guid>
      <description>&lt;p&gt;The filter array method creates a new array with all the items that pass the test given by the function you gave it. By the end of reading this article, you'll get a deeper understanding of how to filter arrays of numbers, strings and an array of objects. You'll be on the A/B honor roll, for sure.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's elementary my dear Watson...
&lt;/h2&gt;

&lt;p&gt;Let's take a look at some numbers I have in an array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const scores = [85, 50, 22, 64, 100, 93]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's say our 5th grade math teacher is letting us remove all grades lower than a 60 from our recent test scores. Great! But we have to prove we 5th graders know how to filter an array. Fear not, here's how.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const oldScores = [85, 50, 22, 64, 100, 93]
const newScores = oldScores.filter( item =&amp;gt; item &amp;gt; 60 )
console.log(newScores)
// Array(4) [ 85, 64, 100, 93 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Success! Let's see what we did though, not time for recess yet.&lt;/p&gt;

&lt;p&gt;So in our variable oldScores we have our old test scores in that array. That array had two scores that had a value less than 60. &lt;/p&gt;

&lt;p&gt;In newScores we are using the filter() array method on the variable oldScores. Look inside the parentheses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; item =&amp;gt; item &amp;gt; 60
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The filter() array method accepts a callback function (the bold function inside our parentheses). That callback function wants to coerce each item in the array to be truthy. We are testing each item in the variable oldScores to be greater than 60. &lt;/p&gt;

&lt;p&gt;A note to realize is the filter method not only creates a new array for you to use, but it traverses (or moves on down the line) over the array given to the method (in this case oldScores).&lt;/p&gt;

&lt;p&gt;When the filter() method traverses over the item in oldScores it will test each item's index against that function. Anything that returns 'true' gets put into the new array that's created. Anything that tests false is not used in the new array. And you guessed it, it's assigned to newScores after the traversing of the array is complete. Take not also, we are not modifying the oldScores array at all. &lt;/p&gt;

&lt;h2&gt;
  
  
  Extra credit
&lt;/h2&gt;

&lt;p&gt;Ok kids, grab your juice boxes, we're going to kick it up a notch. &lt;/p&gt;

&lt;p&gt;What if you wanted to filter an array of objects based on the property's value? For instance, the teacher has some records of a few students. This record is an object that has their name and average score.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const students = [
{
name: 'Tommy',
avgScore: 89
},
{
name: 'Angelica',
avgScore: 93
},
{
name: 'Chuckie',
avgScore: 98
},
{
name: 'Phil',
avgScore: 83
},
{
name: 'Lil',
avgScore: 83
}
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say our teacher needs to give awards to those who have an average score of 85 and above. How would we filter this array? Like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const awards = students.filter( item =&amp;gt; item.avgScore &amp;gt;= 85 )
console.log(awards)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you would have awards equaling this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--StnPsr4m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vih3yrl62ubvull2nz54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--StnPsr4m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vih3yrl62ubvull2nz54.png" alt="Screen Shot 2021-02-01 at 10.53.33 PM" width="716" height="192"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Phil and Lil unfortunately just missed the mark, but better luck next time. &lt;/p&gt;

&lt;p&gt;The first argument the callback function we've named item. We could have used the word 'student' or 'x' or whatever. So long as what's right of the fat arrow correlates with the word of the argument we are passing in. In this case we are wanting to specifically test the &lt;strong&gt;avgScore&lt;/strong&gt; property value of the object we are traversing over. And we want all &lt;strong&gt;avgScore&lt;/strong&gt; values to be equal to or greater than 85. So we use the equal to or greater than comparison operator in between &lt;strong&gt;item.avgScore&lt;/strong&gt; and the number &lt;strong&gt;85&lt;/strong&gt;. And bingo, we have a new array with just 3 of the 5 students who's average score is 85 or higher. &lt;/p&gt;

&lt;p&gt;If you want to learn more about comparison operators check out MDN's docs on it at   &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Comparison_operators"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Comparison_operators&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  I would do anything for lunch, but I won't do that...
&lt;/h2&gt;

&lt;p&gt;We've been working numbers, but you can also filter arrays based on string values like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const lunch = ['pizza', 'meat loaf', 'milk', 'corn dog']
const filteredLunch = lunch.filter( item =&amp;gt; item !== 'meat loaf' )
console.log(filteredLunch)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JSTKPfYD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e07vhalb83xz0qamgxl9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JSTKPfYD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e07vhalb83xz0qamgxl9.png" alt="Screen Shot 2021-02-01 at 11.03.45 PM" width="588" height="54"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;So since the school meat loaf looks like road kill, we're going to filter it our of our lunch array. Once again, the original lunch array is left untouched in our program, but the variable &lt;strong&gt;filteredLunch&lt;/strong&gt; has what we want, so let's dig in!&lt;/p&gt;

&lt;h2&gt;
  
  
  School's out!
&lt;/h2&gt;

&lt;p&gt;In summary, the filter method is a great way to create a new array with only the items you want in it. Just pass a function that tests each item in the array. Whatever is truthy is put into a new array for you to use. Now if you'll excuse me, I'm going to trade my Fruit Roll Ups for some Gushers. Peace!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es6</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Go Build This Stuff: A community list of ideas</title>
      <dc:creator>Brett Thurston</dc:creator>
      <pubDate>Mon, 01 Feb 2021 04:21:24 +0000</pubDate>
      <link>https://dev.to/brettthurs10/go-build-this-stuff-a-community-list-of-ideas-3lcp</link>
      <guid>https://dev.to/brettthurs10/go-build-this-stuff-a-community-list-of-ideas-3lcp</guid>
      <description>&lt;p&gt;Hey, if you're reading this, you're invited to help others break free from creative blocks. How? Just push a branch up to this repo. Easy. :D&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/BrettThurs10/GoBuildThisStuff"&gt;https://github.com/BrettThurs10/GoBuildThisStuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This list is great inspiration for developers needing to update their portfolio or for devs who want a fresh challenge.&lt;/p&gt;

&lt;p&gt;Below is the list in it's current entirety. For the latest and greatest, see the github repo linked above.&lt;/p&gt;

&lt;p&gt;Now, go forth and create! If you do, leave a comment here and share your work. :D&lt;/p&gt;




&lt;h1&gt;
  
  
  Go Build This Stuff
&lt;/h1&gt;

&lt;h3&gt;
  
  
  A massive list of web apps (or apps) to kick that creative block to the curb.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Suggested APIs are just that, suggested. Feel free to find others.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;International weather app with language selector and translation.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Bonus points for using geolocation for detect my location.&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://openweathermap.org/api"&gt;https://openweathermap.org/api&lt;/a&gt;, &lt;a href="https://darksky.net/dev"&gt;https://darksky.net/dev&lt;/a&gt;, &lt;a href="https://www.i18next.com/"&gt;https://www.i18next.com/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Jeopardy trivia app&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Create a simple Jeopardy style website with categories of topics&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="http://jservice.io/"&gt;http://jservice.io/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  DnD card generator
&lt;/h3&gt;

&lt;p&gt;Create a searchable card generator with categories for spells, monsters, loot, weapons, etc...&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="http://www.dnd5eapi.co/"&gt;http://www.dnd5eapi.co/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pokemon card generator
&lt;/h3&gt;

&lt;p&gt;Create a searchable card generator with for all the Pokemans&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://pokeapi.co/"&gt;https://pokeapi.co/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cocktail database
&lt;/h3&gt;

&lt;p&gt;Create a searchable cocktail database&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://www.thecocktaildb.com/api.php"&gt;https://www.thecocktaildb.com/api.php&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bitcoin Price Index
&lt;/h3&gt;

&lt;p&gt;Create a bitcoin dashboard showing the current price index of Bitcoin and other crypto currencies&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://www.coindesk.com/coindesk-api"&gt;https://www.coindesk.com/coindesk-api&lt;/a&gt;, &lt;a href="https://api.coinpaprika.com/v1/coins/btc-bitcoin"&gt;https://api.coinpaprika.com/v1/coins/btc-bitcoin&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Available Jobs Board
&lt;/h3&gt;

&lt;p&gt;Create a searchable job postings website&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://jobs.github.com/positions.json?description=api"&gt;https://jobs.github.com/positions.json?description=api&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  IP info grabber
&lt;/h3&gt;

&lt;p&gt;Create a website that fetches data about the IP address you give it&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://ipinfo.io/161.185.160.93/geo"&gt;https://ipinfo.io/161.185.160.93/geo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Makeup database OR a fake makeup e-commerce website
&lt;/h3&gt;

&lt;p&gt;Resources: &lt;a href="http://makeup-api.herokuapp.com/"&gt;http://makeup-api.herokuapp.com/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Find breweries near me
&lt;/h3&gt;

&lt;p&gt;Use geolocation to detect the closest breweries near me.&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://api.openbrewerydb.org/breweries"&gt;https://api.openbrewerydb.org/breweries&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fake staff directory for a company
&lt;/h3&gt;

&lt;p&gt;Resources: &lt;a href="https://randomuser.me/api/"&gt;https://randomuser.me/api/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Super hero database
&lt;/h3&gt;

&lt;p&gt;Create a searchable super hero database and link related heroes/villains&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://superheroapi.com/"&gt;https://superheroapi.com/&lt;/a&gt;, &lt;a href="https://developer.marvel.com/"&gt;https://developer.marvel.com/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hearthstone database
&lt;/h3&gt;

&lt;p&gt;Create a searchable Hearthstone database&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://hearthstoneapi.com/"&gt;https://hearthstoneapi.com/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a chat app
&lt;/h3&gt;

&lt;p&gt;Resources: &lt;a href="https://www.djamware.com/post/5f2a1d9d9c794f177fd7b527/react-js-tutorial-building-firebase-chat-app-react-hooks"&gt;https://www.djamware.com/post/5f2a1d9d9c794f177fd7b527/react-js-tutorial-building-firebase-chat-app-react-hooks&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  News app
&lt;/h3&gt;

&lt;p&gt;Resources: &lt;a href="https://dev.npr.org/api/"&gt;https://dev.npr.org/api/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  NASA app
&lt;/h3&gt;

&lt;p&gt;Create a ton of cool things with the NASA API&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://api.nasa.gov/"&gt;https://api.nasa.gov/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a crime near me app
&lt;/h3&gt;

&lt;p&gt;Bust the bad guys&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://github.com/fbi-cde/crime-data-frontend"&gt;https://github.com/fbi-cde/crime-data-frontend&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Flight data app
&lt;/h3&gt;

&lt;p&gt;Resources: &lt;a href="https://geekflare.com/flight-data-api/"&gt;https://geekflare.com/flight-data-api/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Food near me
&lt;/h3&gt;

&lt;p&gt;Resources: &lt;a href="https://www.yelp.com/developers/"&gt;https://www.yelp.com/developers/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sports app
&lt;/h3&gt;

&lt;p&gt;Do sports stuff&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://rapidapi.com/blog/best-sports-apis-ranked/"&gt;https://rapidapi.com/blog/best-sports-apis-ranked/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Streaming website
&lt;/h3&gt;

&lt;p&gt;Create a Netflix or Hulu clone&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://www.themoviedb.org/documentation/api"&gt;https://www.themoviedb.org/documentation/api&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  COVID tracker
&lt;/h3&gt;

&lt;p&gt;Resources: &lt;a href="https://covid-api.com/"&gt;https://covid-api.com/&lt;/a&gt;, &lt;a href="https://leafletjs.com/"&gt;https://leafletjs.com/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Dice roller
&lt;/h3&gt;

&lt;p&gt;Make a dice roller app where the user can select all manner of dice to roll (and multiples of, too).&lt;/p&gt;

&lt;h3&gt;
  
  
  Spotify clone
&lt;/h3&gt;

&lt;p&gt;Resources: &lt;a href="https://developer.spotify.com/documentation/web-api/"&gt;https://developer.spotify.com/documentation/web-api/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  SpaceX dashboard
&lt;/h3&gt;

&lt;p&gt;Create a dashboard showing launch pad data and upcoming events&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://github.com/r-spacex/SpaceX-API"&gt;https://github.com/r-spacex/SpaceX-API&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Video game deals website
&lt;/h3&gt;

&lt;p&gt;Resources: &lt;a href="https://apidocs.cheapshark.com/"&gt;https://apidocs.cheapshark.com/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Find a city bike near me
&lt;/h3&gt;

&lt;p&gt;Resources: &lt;a href="http://api.citybik.es/v2/"&gt;http://api.citybik.es/v2/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@mbaumi?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Mika Baumeister&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/idea?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>vue</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Grab your map(); adventure is out there!</title>
      <dc:creator>Brett Thurston</dc:creator>
      <pubDate>Fri, 29 Jan 2021 04:17:59 +0000</pubDate>
      <link>https://dev.to/brettthurs10/grab-your-map-adventure-is-out-there-jjo</link>
      <guid>https://dev.to/brettthurs10/grab-your-map-adventure-is-out-there-jjo</guid>
      <description>&lt;p&gt;Let's explore the majestic map array method and all it's glory.&lt;/p&gt;




&lt;p&gt;Keywords used in this article: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;array&lt;/strong&gt;: a list-like object that one can traverse or modify (mutate)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;integer&lt;/strong&gt;: a real number, not a string (text)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index&lt;/strong&gt;: the numerical position of an item in an array&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;string&lt;/strong&gt;: actual text that cannot be used in mathematical equations&lt;/p&gt;




&lt;p&gt;I have no reason why map() is my favorite array method, but it is. Map powers through the indexes of your array, and creates a new array based on whatever function you told it to do, at each index. By the end of this article, you'll be able to accurately and confidently use the map() array method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Array of sunshine...
&lt;/h2&gt;

&lt;p&gt;So let's make an array of numbers, fill it with actual integers, and map over it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z2ekYFAB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863433299/HI6SYUnvg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z2ekYFAB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863433299/HI6SYUnvg.png" alt="image.png" width="774" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What happened here in console?&lt;/p&gt;

&lt;p&gt;First, the very bottom of the console is simply saying this map method created an array, and each index it rolled over is &lt;strong&gt;undefined.&lt;/strong&gt; So it's an array with 5 indexes that have &lt;strong&gt;undefined&lt;/strong&gt; values. This is to be expected since we're not actually doing any assignment in the callback function, yet.&lt;/p&gt;

&lt;p&gt;Second, line 2 of our program is console logging each index it's found in the array. It's important to refer to each item in an array as either the index or the item. Referring to a number in an array may get confusing here's why:&lt;/p&gt;

&lt;p&gt;The first number in the array is &lt;strong&gt;1&lt;/strong&gt; and it's the first item in the array. However, it's index value is 0. That's because an array's index starts at 0, then 1, then 2 and so on.&lt;/p&gt;

&lt;p&gt;So there are 5 items in the array of numbers, but there first item in the array is an index of 0 and the 5 in the array is at an index of 4.&lt;/p&gt;

&lt;p&gt;Let's take another look at an array of string values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pets&lt;/span&gt; &lt;span class="o"&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;dog&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;cat&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;bird&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;ape&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 index value of dog is 0.&lt;/p&gt;

&lt;p&gt;The index value of ape is 4.&lt;/p&gt;

&lt;h2&gt;
  
  
  You are here
&lt;/h2&gt;

&lt;p&gt;You don't have to take my word for it though. You can pass a 2nd parameter in your argument in the callback function to identify the index it's currently on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;pets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; has an index of &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IwPYtJRQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863499786/63jX3CIDu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IwPYtJRQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863499786/63jX3CIDu.png" alt="image.png" width="740" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we see the index of each item in the array.&lt;/p&gt;

&lt;p&gt;Now let's go back to our numbers array and see map in action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QdzK-VT6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863628258/yokc1FmEg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QdzK-VT6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863628258/yokc1FmEg.png" alt="image.png" width="760" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look at the array that was created from this map method. It increases each number by one as directed in our callback method of 'item ⇒ item = item + 1'. So it effectively looked at each index, saw that it was a number type, so it added the integer we instructed to add, 1.&lt;/p&gt;

&lt;p&gt;FYI a leaner way of writing the same method is this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h7BckQLU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863649451/EhF3Pm09I.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h7BckQLU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863649451/EhF3Pm09I.png" alt="image.png" width="761" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Important note: the index value of an item in an array is indeed an &lt;strong&gt;integer&lt;/strong&gt; and not a string.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another day, a new array
&lt;/h2&gt;

&lt;p&gt;Something else to note is that using the map method actually creates a brand new array. So when you run a map method by itself, you are creating an array where it is in the program. Having said that, you aren't mutating (modifying) the original array you're mapping. Take a look below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;points&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;80&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="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;points&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;points&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QBBlyWgy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863671131/uftUy4fPL.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QBBlyWgy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863671131/uftUy4fPL.png" alt="image.png" width="783" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See what happened? The items in the array points haven't increased by 10. That's because an array was made, but isn't referenced anywhere because it's created a new array, with the items increased by 10, but they haven't been assigned to a new variable.&lt;/p&gt;

&lt;p&gt;Remember, whenever you use the map method, you're creating a NEW array, not modifying the one you're mapping.&lt;/p&gt;

&lt;p&gt;Here's how to rewrite this program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;points&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;80&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="mi"&gt;75&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;bonusPoints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;points&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// our new array logged&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bonusPoints&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// the array we mapped over still equals the same as when it was first declared&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;points&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ptw4HmTl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863693081/8MvOY1N62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ptw4HmTl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611863693081/8MvOY1N62.png" alt="image.png" width="748" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take a look, &lt;strong&gt;bonusPoints&lt;/strong&gt; is a new variable that's been assigned the brand new array the map method made to the right of the equal sign, on line 2. And then we console log it and see the numbers have been increased by 10.&lt;/p&gt;

&lt;p&gt;For reference, we logged the &lt;strong&gt;points&lt;/strong&gt; array we used to map in &lt;strong&gt;bonusPoints.&lt;/strong&gt; We see the numbers are unchanged from when they were first declared in line 1. That's because, they were never modified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another take
&lt;/h2&gt;

&lt;p&gt;Let's say you had an array of numbers, and you want to create a new variable that stores a check on each item that is less than 10. Let's take a look at how you do that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const someNumbers = [4,7,8,11,14]
const lessThanTen = someNumbers.map( item =&amp;gt; item &amp;lt; 10 )
console.log(lessThanTen)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mIMpGPIw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611871994985/gbq_oLGZv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mIMpGPIw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611871994985/gbq_oLGZv.png" alt="image.png" width="624" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we see that the first 3 numbers are less than 10 because they have the boolean of true, but the last two numbers are greater than 10. &lt;/p&gt;

&lt;h2&gt;
  
  
  The lay of the land
&lt;/h2&gt;

&lt;p&gt;Here are some rules to think about while using the map() method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only use the map method when you want to create a new array&lt;/li&gt;
&lt;li&gt;Only use it when you're returning a value from the callback method&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So in other words, it's not advised to use map if you're not using the array it returns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Map() can also be a little factory
&lt;/h2&gt;

&lt;p&gt;Let's say you have an ID component that looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function userCard(data) {
  return `&amp;lt;div class="card"&amp;gt;
  &amp;lt;img src="${data.picture.large}" alt="Avatar" class="image"&amp;gt;
  &amp;lt;div class="container"&amp;gt;
    &amp;lt;h4&amp;gt;&amp;lt;b&amp;gt;${data.name.first} ${data.name.last}&amp;lt;/b&amp;gt;&amp;lt;/h4&amp;gt;
    &amp;lt;p&amp;gt;${data.email}&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;`;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say we had an array of objects that stored 7 people's information. We need to render 7 ID cards to the screen. If we copy and paste 7 ID card components to our HTML page, that's a lot of management to be responsible for. Wouldn't it be nice to have one component dictate what they all look like? &lt;/p&gt;

&lt;p&gt;Enter map to the rescue!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let cards = people.map((item) =&amp;gt; userCard(item));
div.innerHTML = cards.join(" ");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t9fBfNni--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611892380099/U1aiMvKeC.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t9fBfNni--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1611892380099/U1aiMvKeC.png" alt="Screen Shot 2021-01-28 at 9.50.30 PM.png" width="880" height="972"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By allowing our map method to traverse over our array, we are creating a new array. That array is then rendered to the DOM via innerHtml.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/BrettThurs10/MapMethodSample"&gt;Check out the GitHub for this example.&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And for those React users, you can easily to the same, just returning your component instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back to base camp
&lt;/h2&gt;

&lt;p&gt;To sum up the map method, you're creating a new array and filling it with items based on the callback function you passed to it. You should feel comfortable using the map method. I hope this map field guide has helped you in your journey as developer. &lt;/p&gt;

&lt;p&gt;Please let me know if this has been as clear as mud. I'd be happy to clear things up for you. :D&lt;/p&gt;

&lt;p&gt;Remember, adventure is out there!&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@itsallhazey?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Matilda Vistbacka&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/map?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>es6</category>
    </item>
    <item>
      <title>Var vs let and const; easy as pie</title>
      <dc:creator>Brett Thurston</dc:creator>
      <pubDate>Wed, 27 Jan 2021 22:00:29 +0000</pubDate>
      <link>https://dev.to/brettthurs10/var-vs-let-and-const-easy-as-pie-iai</link>
      <guid>https://dev.to/brettthurs10/var-vs-let-and-const-easy-as-pie-iai</guid>
      <description>&lt;p&gt;If you've spent any time learning Javascript you've probably seen three ways to declare a variable. This guide will show you an in depth look at the behaviors of 'var', 'let' and 'const'. Afterwards, you'll be setting variables appropriately and confidently.&lt;/p&gt;

&lt;h2&gt;
  
  
  For starters...
&lt;/h2&gt;

&lt;p&gt;'Let' and 'const' are apart of ES6 (ECMA script 6). This is the latest approved standardization for Javascript that was released in 2015. ES5 was released in 2011. Modern Javascript frameworks like React and Vue utilize ES6. So it's a great time to jump on board the ES6 bus.&lt;/p&gt;

&lt;p&gt;Using 'var', 'let' and 'const' is as easy as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var pie = 'apple'
let pie = 'apple'
const pie = 'apple'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Var-y funny
&lt;/h2&gt;

&lt;p&gt;Let's take a look and see how a 'var' behaves. Var is scoped to the entire function it's in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function count() {
  for (var i = 0; i &amp;lt; 3; i++) {
    if (true) {
      console.log(i);
    }
  }
  console.log(i);
}
count();

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611780396253%2FbJaTXmFfR.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611780396253%2FbJaTXmFfR.png" alt="Screen Shot 2021-01-27 at 2.46.22 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Can you see what's wrong in our console?&lt;/p&gt;

&lt;p&gt;On line 7, the 2nd console.log(i) is saying i is equal to 3. This is a problem since our for loop should stop when it hit the 3rd loop. Instead of doing that, our 'var' is scoped to the entire count function.&lt;/p&gt;

&lt;p&gt;Watch happens when we change our 'var' in our for loop to let:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function count() {
  for (let i = 0; i &amp;lt; 3; i++) {
    if (true) {
      console.log(i);
    }
  }
  console.log(i);
}
count();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611780560213%2F9FFFaqYIP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611780560213%2F9FFFaqYIP.png" alt="Screen Shot 2021-01-27 at 2.49.01 PM.png"&gt;&lt;/a&gt;&lt;br&gt;
We now get a ReferenceError on the 2nd console.log(i). This is actually what we want. Outside of the for loop, the parent function shouldn't care that we declared a function named i. That's because 'let' is scoped to the code block it lives in. 'Const' is the same way. 'Var' can get tricky since it's scoped to it's function AND it can also collide with variables set in the window. In other words, two variables named the same thing will cause errors in your program.&lt;/p&gt;

&lt;p&gt;If you don't know, there is a window object that hosts a ton of behind the scenes stuff. Open up your console on your web browser and type in window to see it all.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611780799036%2FaR1TtmbjE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611780799036%2FaR1TtmbjE.png" alt="Screen Shot 2021-01-27 at 2.53.10 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can imagine we'd get some errors working with larger applications that utilize window if we're using vars everywhere.&lt;/p&gt;

&lt;p&gt;So hopefully you can begin to see why it's best practice to stick to setting variables with 'let' and 'const'.&lt;/p&gt;
&lt;h2&gt;
  
  
  Let's dig in
&lt;/h2&gt;

&lt;p&gt;As you may have guessed 'let' allows the program to update it's value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let pie = 'apple'
//...
pie = 'pecan'
console.log(pie)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611781016847%2FHGIpvn-GS.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611781016847%2FHGIpvn-GS.png" alt="Screen Shot 2021-01-27 at 2.56.45 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we declared a variable called pie and set it's value to the string apple. Later on in our app, we updated the pie variable to pecan with no issue. Console logging pie shows us we're set to have pecan pie. Yum!&lt;/p&gt;

&lt;h2&gt;
  
  
  I const stop eating...
&lt;/h2&gt;

&lt;p&gt;Let's try the same thing in console with 'const', instead of let.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const pie = "apple";
pie = "pecan";
console.log(pie);

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611781100053%2FquK0qlPnf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611781100053%2FquK0qlPnf.png" alt="Screen Shot 2021-01-27 at 2.57.51 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well no pie for us. That's because we said pie should never update it's value of 'apple' by declaring it with 'const'. And this is a good thing! Our variable is protecting itself against future modification. We all know apple pie is the best pie and should never be replaced. :D&lt;/p&gt;

&lt;p&gt;'Const' safe guards your variables by throwing an Uncaught TypeError. &lt;/p&gt;

&lt;h2&gt;
  
  
  Can we scrape 'var' in the trash can?
&lt;/h2&gt;

&lt;p&gt;Why doesn't Javascript just take 'var' out and replace it with 'let'? That's a good question, but the answer is that it would be absolute chaos. Imagine all the websites and apps utilizing 'var' in legacy code. Removing 'var' support would just be such a nightmare for everyone. So, just like mom's giant papier-mâché turkey centerpiece, it stays for the full course meal.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR (doggie bag version)
&lt;/h2&gt;

&lt;p&gt;Let is great to use when you say it's OK for the variable to be updated.&lt;/p&gt;

&lt;p&gt;'Const' is great to use when the variable should never update.&lt;/p&gt;

&lt;p&gt;'Let' and 'const' are scoped to the code block that they live in.&lt;/p&gt;

&lt;p&gt;Using 'var' is like taking a bite out of pie that's been left out for a week. It is scoped to the entire function, regardless of whatever code blocks are in it. So you're probably going to have issues using it and eating old pie.&lt;/p&gt;

&lt;p&gt;Get in the habit of using 'let' and 'const'. It will save you some headache in your career as a Javascript developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  More dessert please...
&lt;/h2&gt;

&lt;p&gt;What if you wanted to update a variable in a loop (or a code block further into the function)? Piece of cake, just declare the variable at the beginning of the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function chowDown() {
  let capacity = "empty";
  let inches = 42;
  for (let i = 0; i &amp;lt;= inches; i++) {
    if (i == inches) {
      capacity = "full";
    }
  }
  console.log("my belly is now " + capacity);
}
chowDown();

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611781832796%2FS4BDXwn6G.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1611781832796%2FS4BDXwn6G.png" alt="Screen Shot 2021-01-27 at 3.10.28 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@priscilladupreez?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Priscilla Du Preez&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/apple-pie?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es6</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Listen up: it's not rejection</title>
      <dc:creator>Brett Thurston</dc:creator>
      <pubDate>Fri, 21 Aug 2020 07:05:53 +0000</pubDate>
      <link>https://dev.to/brettthurs10/listen-up-it-s-not-rejection-2e2c</link>
      <guid>https://dev.to/brettthurs10/listen-up-it-s-not-rejection-2e2c</guid>
      <description>&lt;p&gt;So you've applied to that one job you really are excited about. Maybe you knew it was kind of a crapshoot, but perhaps they'll set up an interview for you. Later that day you get that email. The one that says, 'Thanks, but no thanks'. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2FU7rz8Q1ues8hDbDydS%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2FU7rz8Q1ues8hDbDydS%2Fgiphy.gif" alt="Well, crap."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oy vey, that feeling in your stomach. I know it.&lt;/p&gt;

&lt;p&gt;If you're like me you've thought, 'My website isn't good enough. My portfolio isn't strong enough. My code isn't smart enough. Etc...'. I've totally have been there, many times. The fact is, it's all probably fine. You're beating yourself up. Don't.&lt;/p&gt;

&lt;p&gt;I've been active on tech Twitter lately. It pains me to see techies use the word rejection. I strongly oppose the notion anyone has been 'rejected'. This isn't getting dumped because you're not special or wanted. You are unique and you are wanted, but to another company...just not this one. And that's OK! &lt;/p&gt;

&lt;p&gt;I want to encourage you with some thoughts. And if you'll humor me, an analogy I tell myself after getting those emails.&lt;/p&gt;

&lt;p&gt;First off, you must care about yourself, your career and what you can bring to the table. Know that you do matter. Your thoughts, your feelings, your time - all of it matters. It should be respected by a company and in return you should respect yourself. &lt;/p&gt;

&lt;p&gt;Second, you aren't a charlatan. So kick that that imposter syndrome to the curb. You've put the hours in. You've worked from the bottom and are on your way up. You've earned the right to apply to this gig. (Just a note to beginners out there: more often than not you will likely have to take the grunt work, to get to where you want to be. Have patience, you'll get there. Keep side hustles going if your day job isn't fulfilling. They're both rewarding and good to discuss in interviews. Showing passion goes a long way.)&lt;/p&gt;

&lt;p&gt;Third, applying to jobs is a numbers game. You must apply to a lot of them, so you can get a small percentage of interviews lined up with those companies that would be a good fit for you. It's like speed dating. Talk to the whole room, and hopefully you've got 2-3 prospects to follow up with. &lt;/p&gt;

&lt;p&gt;So &lt;em&gt;you&lt;/em&gt; have not been rejected. &lt;/p&gt;

&lt;p&gt;Say it with gusto now, 'I haven't been rejected'.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia2.giphy.com%2Fmedia%2F3krrjoL0vHRaWqwU3k%2Fgiphy.gif%3Fcid%3Decf05e47dpjnjtmz51d13utbvv47620uuqkfcuyidghbzzd4%26rid%3Dgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia2.giphy.com%2Fmedia%2F3krrjoL0vHRaWqwU3k%2Fgiphy.gif%3Fcid%3Decf05e47dpjnjtmz51d13utbvv47620uuqkfcuyidghbzzd4%26rid%3Dgiphy.gif" alt="You feel better already, don't you?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feels good, yeah?&lt;/p&gt;

&lt;p&gt;And now for that analogy:&lt;/p&gt;

&lt;p&gt;The company you applied for/interviewed with is a jigsaw puzzle. They are missing a much needed puzzle piece. Puzzle pieces come in all shapes. Some have two pegs, others three. Heck, some have four (show offs). The piece they need, unfortunately, isn't the piece that you are. But that's ok, as of right now, you now know it's time to sally forth and move on to greener pastures. Because, guess what? There is a company out there that needs the exact piece that you happen to be. It's just that, as of right now, you two just don't know it yet. &lt;/p&gt;

&lt;p&gt;So what do you do? &lt;/p&gt;

&lt;p&gt;Keep you head up high and go apply to another job. And please, don't feel rejected.&lt;/p&gt;

&lt;p&gt;Sometimes, we apply to things that are just outside our ability. No sweat, you can teach yourself how to add that tool to your tool box. &lt;/p&gt;

&lt;p&gt;For now, continue the journey in finding that company that wants you just as much as you want it. Be eager for that kind of business relationship to happen and don't settle for less. Let that fuel your rebound.&lt;/p&gt;

&lt;p&gt;I realize this article may come across too optimistic for some of you, but I hope that you realize the situation for what it is. A company is need of a certain individual, and that individual isn't you. There is a indeed a company that needs you. Now go find it.&lt;/p&gt;

&lt;p&gt;You got this!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia0.giphy.com%2Fmedia%2Fj5QcmXoFWl4Q0%2Fgiphy.gif%3Fcid%3Decf05e47whtt31os8188sqekpwbim4xcj77sdycktfs68rxm%26rid%3Dgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia0.giphy.com%2Fmedia%2Fj5QcmXoFWl4Q0%2Fgiphy.gif%3Fcid%3Decf05e47whtt31os8188sqekpwbim4xcj77sdycktfs68rxm%26rid%3Dgiphy.gif" alt="You got this"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rejection</category>
      <category>hiring</category>
      <category>career</category>
      <category>interview</category>
    </item>
  </channel>
</rss>
