<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Zac Haluza</title>
    <description>The latest articles on Forem by Zac Haluza (@zhaluza).</description>
    <link>https://forem.com/zhaluza</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%2F185728%2Fc95ac6b3-fbfe-4ea4-9496-54fd18175176.jpg</url>
      <title>Forem: Zac Haluza</title>
      <link>https://forem.com/zhaluza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/zhaluza"/>
    <language>en</language>
    <item>
      <title>An Intro to Redux</title>
      <dc:creator>Zac Haluza</dc:creator>
      <pubDate>Wed, 10 Mar 2021 02:30:08 +0000</pubDate>
      <link>https://forem.com/zhaluza/an-intro-to-redux-1heg</link>
      <guid>https://forem.com/zhaluza/an-intro-to-redux-1heg</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published at &lt;a href="https://haluza.dev/blog/an-introduction-to-redux" rel="noopener noreferrer"&gt;haluza.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you'll get out of this article:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn why developers use external libraries to manage state in React&lt;/li&gt;
&lt;li&gt;Understand the fundamentals of Redux&lt;/li&gt;
&lt;li&gt;Apply Redux concepts to a simple counter app&lt;/li&gt;
&lt;li&gt;Learn how Redux Toolkit simplifies Redux setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This article is for you if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're familiar with the basics of React&lt;/li&gt;
&lt;li&gt;You know how to manage React state with hooks and/or state objects&lt;/li&gt;
&lt;li&gt;You're new to state management libaries like Redux and MobX&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you're wondering why this article discusses vanilla Redux and not Redux Toolkit, please read my explanation in the afterword.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Why Do We Need Redux?&lt;/li&gt;
&lt;li&gt;How Does Redux Work?&lt;/li&gt;
&lt;li&gt;
Understanding Redux in an App

&lt;ul&gt;
&lt;li&gt;Actions &amp;amp; Action Creators&lt;/li&gt;
&lt;li&gt;Reducers&lt;/li&gt;
&lt;li&gt;Store&lt;/li&gt;
&lt;li&gt;Connecting the App to the Store&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;li&gt;
Next Steps

&lt;ul&gt;
&lt;li&gt;Read "You Might Not Need Redux"&lt;/li&gt;
&lt;li&gt;Build an App With Redux&lt;/li&gt;
&lt;li&gt;Explore Redux Toolkit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Afterword: Why This Article Uses Vanilla Redux&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introduction &lt;span id="introduction"&gt;&lt;/span&gt;
&lt;/h2&gt;

&lt;p&gt;State management is one of the core concepts of React. It's also one of the most complicated. This isn't necessarily because managing state in React is tricky; rather, there are so many different ways to do it!&lt;/p&gt;

&lt;p&gt;In this article I'm going to assume that you're comfortable managing state within a component, but are relatively new to Redux.&lt;/p&gt;

&lt;p&gt;At the simplest level, Redux lets you do two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manage state from a single location in your app&lt;/li&gt;
&lt;li&gt;Access this state anywhere in your app, without passing it from component to component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To understand why this is so important, let's take a moment to imagine we've been hired to create a new hit app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Do We Need Redux? &lt;span id="why-do-we-need-redux"&gt;&lt;/span&gt;
&lt;/h2&gt;

&lt;p&gt;Our product manager wants us to build an app called Counter. It's fast, sleek, and consists of a single component. (Think of how small the bundle size is!)&lt;br&gt;
Check out the code below, or click &lt;a href="https://codesandbox.io/s/usestate-counter-example-djq6s?file=/src/App.js" rel="noopener noreferrer"&gt;here&lt;/a&gt; to view this as an app on CodeSandbox.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prevCount&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;prevCount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decrement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prevCount&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;prevCount&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;Redux&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;-&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;+&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;reset&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;Reset&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;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;Inside this tiny &lt;code&gt;App&lt;/code&gt; component, we're creating a single &lt;code&gt;count&lt;/code&gt; state for our counter, initializing it to &lt;code&gt;0&lt;/code&gt;, and defining methods to &lt;code&gt;increment&lt;/code&gt;, &lt;code&gt;decrement&lt;/code&gt;, and &lt;code&gt;reset&lt;/code&gt; it.&lt;/p&gt;

&lt;p&gt;Then we're implementing the counter inside the same component.&lt;/p&gt;

&lt;p&gt;If your React apps are all as simple as this one, you'll never need to use a state management solution like Redux. However, I can all but guarantee that you'll work on an app in which &lt;code&gt;useState&lt;/code&gt; or &lt;code&gt;setState&lt;/code&gt; alone won't cut it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 2: Complex Counter
&lt;/h3&gt;

&lt;p&gt;Turns out our counter app was massively popular — it's time to introduce the&lt;br&gt;
world to Counter 2.0!&lt;/p&gt;

&lt;p&gt;Here's the mockup our product manager just gave us. Note that it's a &lt;em&gt;little&lt;/em&gt; more complicated than what we were working with before:&lt;/p&gt;

&lt;p&gt;&lt;a href=""&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdbvsstxde%2Fimage%2Fupload%2Fv1614696165%2Fhaluza.dev%2FRedux%2520Post%2Fcomplicated-app_g62nrb.png" alt="Mockup-for-a-complicated-app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To save you some stress, we aren't going to code this app out. Instead, I want you to think of the different types of state that we would need to manage inside this app. Off the top of my head, here are the key types of state we would need to manage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All of the counters in the app, as well as their current values. We could store the counter values inside an array to keep track of the counters more easily.&lt;/li&gt;
&lt;li&gt;Login-related info, such as the user's name, so we could display it in the
UI.&lt;/li&gt;
&lt;li&gt;The current color theme (light mode or dark mode)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Previously, we stored all of our state logic inside our &lt;code&gt;App.js&lt;/code&gt; file. Now, however, our state is a little bigger. Below you'll see our current state represented as an object. Why did I use an object? Keep that question in mind as you read on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;counters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;colorTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, that doesn't seem so bad. But hold on — don't we also need to include methods to trigger state changes?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setUsername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// logic to set the username when someone logs in&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;addCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// logic to add a counter&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;removeCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// logic to remove a counter at a certain index&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;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// logic to increment a specific counter&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;decrement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// logic to decrement a specific counter&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;reset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// logic to reset a specific counter&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've just defined the basic business logic for our application. We already have some problems.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Our &lt;code&gt;App.js&lt;/code&gt; component is going to get crowded if we move it all there.&lt;/li&gt;
&lt;li&gt;It's going to get even more crowded if we start adding more state and logic
to our app.&lt;/li&gt;
&lt;li&gt;We'll also need to pass our state and methods down to our components. And if
we nest components inside other components (for example, &lt;code&gt;App&lt;/code&gt; -&amp;gt;
&lt;code&gt;CounterContainer&lt;/code&gt; -&amp;gt; &lt;code&gt;Counter&lt;/code&gt;), we run the risk of introducing
&lt;a href="https://kentcdodds.com/blog/prop-drilling" rel="noopener noreferrer"&gt;prop drilling&lt;/a&gt; into our app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Wouldn't it be easier if we had one central place to store our state and our state-related methods, like adding counters and changing the color theme? And wouldn't it also be great if we could grab state and methods directly from this central store, instead of passing them through component after component?&lt;/p&gt;

&lt;p&gt;This is where Redux comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Redux Work? &lt;span id="how-does-redux-work"&gt;&lt;/span&gt;
&lt;/h2&gt;

&lt;p&gt;Counter 2.0 shows us some very common state management issues that can occur in&lt;br&gt;
React apps when they grow more complex. Redux helps solve these problems by&lt;br&gt;
handling state management in a very opinionated and clearly defined flow.&lt;/p&gt;

&lt;p&gt;Here's how Redux's "one-way data flow" works. Just soak it in — it's OK if it doesn't make sense yet.&lt;/p&gt;

&lt;p&gt;&lt;a href=""&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdbvsstxde%2Fimage%2Fupload%2Fv1614696165%2Fhaluza.dev%2FRedux%2520Post%2Fredux-diagram_un9kun.png" alt="redux-flow-diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's translate this image into a series of written steps. For now, let's imagine that we've implemented Redux inside a simple counter app, like Counter 1.0.&lt;/p&gt;

&lt;p&gt;This is what happens when a user clicks on the button to increment the counter from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The app &lt;strong&gt;dispatches&lt;/strong&gt; an &lt;strong&gt;action&lt;/strong&gt;. The action is a function called &lt;code&gt;increment&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The action is sent to the &lt;strong&gt;store&lt;/strong&gt;, which holds the app's state inside an object.&lt;/li&gt;
&lt;li&gt;The store updates the state using a &lt;strong&gt;reducer function&lt;/strong&gt; (more on that
later).

&lt;ul&gt;
&lt;li&gt;In this case, the &lt;code&gt;count&lt;/code&gt; state is increased to &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The store sends the updated state back to the UI. The counter now displays &lt;code&gt;1&lt;/code&gt; instead of &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Actions, stores, reducers... This is getting extremely abstract. To make these concepts more tangible, let's see an how Redux works inside a React app.&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding Redux in an App &lt;span id="understanding-redux-in-an-app"&gt;&lt;/span&gt;
&lt;/h2&gt;

&lt;p&gt;Remember Counter 2.0? Our product manager decided to scrap it because it was too complicated. Now they want us to build the much simpler and much prettier Counter 3.0. Oh, and they want us to use Redux!&lt;/p&gt;

&lt;p&gt;Here's what the finished app looks like. Before moving on, poke around inside the app and get a feel for its functionality. Inside the &lt;code&gt;redux&lt;/code&gt; directory, you'll find some files with familiar sounding names, like &lt;code&gt;reducer.js&lt;/code&gt;, &lt;code&gt;actionCreators.js&lt;/code&gt;, and &lt;code&gt;store.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/4rpht"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;We're going to explore the following concepts inside the Counter 3.0 app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reducers&lt;/li&gt;
&lt;li&gt;Actions (and action creators)&lt;/li&gt;
&lt;li&gt;Store&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's take a look at that Redux flow diagram again. It's important to keep these concepts in mind as you explore the app.&lt;/p&gt;

&lt;p&gt;&lt;a href=""&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdbvsstxde%2Fimage%2Fupload%2Fv1614696165%2Fhaluza.dev%2FRedux%2520Post%2Fredux-diagram_un9kun.png" alt="redux-flow-diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Actions &amp;amp; Action Creators &lt;span id="actions-&amp;amp;-action-creators"&gt;&lt;/span&gt;
&lt;/h3&gt;

&lt;p&gt;Before I explain what an action or an action creator is, let's look at a simplified version of the &lt;code&gt;actionCreators.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;incrementCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INCREMENT_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decrementCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DECREMENT_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resetCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RESET_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setCustomCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SET_CUSTOM_COUNT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we've created functions to define four events we can trigger with our app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increment the count&lt;/li&gt;
&lt;li&gt;Decrement the count&lt;/li&gt;
&lt;li&gt;Reset the count&lt;/li&gt;
&lt;li&gt;Set the count to a custom number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these events corresponds to a button in the app.&lt;/p&gt;

&lt;p&gt;These functions are called &lt;strong&gt;action creators&lt;/strong&gt;. Each action creators returns an object called an &lt;strong&gt;action&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There are two basic types of actions.&lt;/p&gt;

&lt;p&gt;The first contains only a &lt;code&gt;type&lt;/code&gt; property. Think of it as the action's&lt;br&gt;
&lt;strong&gt;label&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INCREMENT_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second contains a &lt;code&gt;type&lt;/code&gt; property as well as a &lt;code&gt;payload&lt;/code&gt; property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SET_CUSTOM_COUNT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;67&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The name &lt;code&gt;payload&lt;/code&gt; is an apt description. It's the value(s) we want to use when we update the state. In the case of our &lt;code&gt;SET_CUSTOM_COUNT&lt;/code&gt; action, we're updating the &lt;code&gt;count&lt;/code&gt; state to &lt;code&gt;67&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why don't any of our other actions contain payloads? Simple: they don't need them. We'll see why when we learn about reducers next.&lt;/p&gt;

&lt;p&gt;Where do we trigger our reducers? Right inside the app. Here's the code for our "increment" button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;incrementCounter&lt;/span&gt;&lt;span class="p"&gt;())}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;+&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll discuss the &lt;code&gt;dispatch&lt;/code&gt; method later. But in a nutshell, here's what happens when a user clicks the &lt;code&gt;+&lt;/code&gt; button to increment the counter.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;incrementCounter&lt;/code&gt; function (action creator) is executed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;incrementCounter&lt;/code&gt; returns an object with a &lt;code&gt;type&lt;/code&gt; property of
&lt;code&gt;INCREMENT_COUNTER&lt;/code&gt;. This object is our &lt;strong&gt;action.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The action is sent to the &lt;strong&gt;reducer.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Reducer &lt;span id="reducer"&gt;&lt;/span&gt;
&lt;/h3&gt;

&lt;p&gt;This is where it starts to come together.&lt;/p&gt;

&lt;p&gt;What's the reducer? It's simply a function that controls your app's state.&lt;/p&gt;

&lt;p&gt;It's often written as a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch" rel="noopener noreferrer"&gt;switch statement&lt;/a&gt;, as is the one in this app, but that's simply a common convention, not a requirement.&lt;/p&gt;

&lt;p&gt;Here's what our reducer looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;counterReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INCREMENT_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DECREMENT_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RESET_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SET_CUSTOM_COUNT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a lot to take in. Let's walk through this chunk of code step by step.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, we define our &lt;code&gt;initialState&lt;/code&gt; as an object above the reducer.&lt;/li&gt;
&lt;li&gt;Next, the reducer function accepts two parameters: &lt;code&gt;state&lt;/code&gt; and &lt;code&gt;action&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;state&lt;/code&gt; - the &lt;code&gt;initialState&lt;/code&gt; object is this parameter's default value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;action&lt;/code&gt; - this refers to whatever action that was just returned by the action creator.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;We create a switch statement. Inside this statement, we return an &lt;strong&gt;object&lt;/strong&gt; depending on the action's type property.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;If a user opens the app and chooses to increment the counter, what happens?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The app dispatches the &lt;code&gt;incrementCounter&lt;/code&gt; action creator:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;incrementCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INCREMENT_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;incrementCounter&lt;/code&gt; action creator returns an object (an &lt;strong&gt;action&lt;/strong&gt;) with a &lt;code&gt;type&lt;/code&gt; property of &lt;code&gt;INCREMENT_COUNTER&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INCREMENT_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Our &lt;strong&gt;reducer&lt;/strong&gt; function is invoked, accepting &lt;code&gt;initialState&lt;/code&gt; and the action object as parameters. In pseudocode, it looks something like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;incrementAction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INCREMENT_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;counterReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;incrementAction&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;reducer&lt;/strong&gt; looks at the action's &lt;code&gt;type&lt;/code&gt; property and sees if it matches any of its cases. Bingo - we hit the &lt;code&gt;INCREMENT_COUNTER&lt;/code&gt; case.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INCREMENT_COUNTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// other cases here...&lt;/span&gt;

  &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&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;ul&gt;
&lt;li&gt;The reducer returns an object with a single property, &lt;code&gt;count&lt;/code&gt;. To calculate the value, it grabs the current value of &lt;code&gt;count&lt;/code&gt; from the current state object (which is &lt;code&gt;0&lt;/code&gt; now) and adds &lt;code&gt;1&lt;/code&gt; to it.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hold on — that looks a lot like our &lt;code&gt;initialState&lt;/code&gt; object!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Our initial state object&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// The object returned by the reducer&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's right. The reducer returns the updated state. In more technical terms, it replaces the previous state object with a new state object containing updated values. This is because Redux state is &lt;strong&gt;immutable&lt;/strong&gt; (key interview term!). You should never directly modify your Redux state inside your reducer. Instead, you should return a brand new object, like we do here.&lt;/p&gt;

&lt;p&gt;This updated state object is now available for our app to use. But how does our app have access to the state?&lt;/p&gt;

&lt;p&gt;It's time to learn about the store.&lt;/p&gt;

&lt;h2&gt;
  
  
  Store &lt;span id="store"&gt;&lt;/span&gt;
&lt;/h2&gt;

&lt;p&gt;Here's what Counter 3.0's store looks like. Brace yourself... it's 4 lines of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;counterReducer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./reducer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterReducer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Still, we only need to look at one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterReducer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Redux store is simply an object that holds your app's state. &lt;strong&gt;Your app&lt;br&gt;
should only contain one store.&lt;/strong&gt; This is a &lt;strong&gt;HUGE&lt;/strong&gt; part of what makes Redux an appealing state solution. Your store becomes a &lt;strong&gt;single source of truth&lt;/strong&gt; for your app's state.&lt;/p&gt;

&lt;p&gt;Remember the phrase "single source of truth." It's an easy way to sum up the benefits of Redux. Plus, it's another great phrase to use in interviews.&lt;/p&gt;

&lt;p&gt;In the line of code above, Redux's &lt;code&gt;createStore&lt;/code&gt; function takes in your reducer and uses it to construct the store object.&lt;/p&gt;

&lt;p&gt;As your app grows more complex, you may want to create multiple reducers. If we add a to-do feature to our counter app, creating a separate &lt;code&gt;toDoReducer&lt;/code&gt; where&lt;br&gt;
we store our state and methods for our app's "to-do" functionality.&lt;/p&gt;

&lt;p&gt;Fortunately, the Redux library provides a &lt;a href="https://redux.js.org/api/combinereducers" rel="noopener noreferrer"&gt;&lt;code&gt;combineReducers&lt;/code&gt;&lt;/a&gt; function that lets you feed a multilayered reducer to your store.&lt;/p&gt;

&lt;p&gt;We're almost there! We've built our action creators, reducer, and store. Now we just need to give our app access to the store and the state inside it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Connecting the App to the Store &lt;span id="connecting-the-app-to-the-store"&gt;&lt;/span&gt;
&lt;/h3&gt;

&lt;p&gt;There are only two steps left:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wrap our store around our entire app, using a special wrapper component called &lt;code&gt;Provider&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Hook our components into the store with... Redux hooks!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hang in there. This is the home stretch!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrapping the Store Around Our App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For these last few steps, we're going to use a few features that the &lt;a href="https://react-redux.js.org/" rel="noopener noreferrer"&gt;React Redux&lt;/a&gt; library gives us. The first one is called &lt;code&gt;Provider&lt;/code&gt;, and it's a component that we wrap around our entire app. We use it in the &lt;code&gt;index.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Here's the &lt;code&gt;index.js&lt;/code&gt; file of a typical React app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rootElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what the same file looks like when we implement the &lt;code&gt;Provider&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./redux/store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Provider&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;,
&lt;/span&gt;  &lt;span class="nx"&gt;rootElement&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file suddenly got a lot more busy. The key difference is this chunk of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Provider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're &lt;em&gt;providing&lt;/em&gt; the entire app with access to our Redux store. And this is a big thing. It means that regardless of where we are in our app — even if we're inside a component nested a dozen layers down — we can reach directly into the store without even leaving that component.&lt;/p&gt;

&lt;p&gt;We no longer need to pass down all our state as props.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accessing State From Inside a Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, let's look at two hooks: &lt;code&gt;useSelector&lt;/code&gt; and &lt;code&gt;useDispatch&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;useSelector&lt;/code&gt; lets us access state values inside our store (like our &lt;code&gt;count&lt;/code&gt;
state).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useDispatch&lt;/code&gt; lets us "dispatch" action creators to our reducer. In other
words, it lets us trigger state changes, like incrementing a counter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of &lt;code&gt;useSelector&lt;/code&gt; as a &lt;strong&gt;noun&lt;/strong&gt; (e.g. &lt;code&gt;count&lt;/code&gt;) and &lt;code&gt;useDispatch&lt;/code&gt; as a &lt;strong&gt;verb&lt;/strong&gt; (e.g. &lt;code&gt;incrementCounter&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Inside our app's &lt;code&gt;Counter.js&lt;/code&gt; file, we implement both of these hooks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useDispatch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;incrementCounter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;decrementCounter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;resetCounter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../redux/actionCreators&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDispatch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;counter-top&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;decrementCounter&lt;/span&gt;&lt;span class="p"&gt;())}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;-&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;incrementCounter&lt;/span&gt;&lt;span class="p"&gt;())}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;+&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;resetCounter&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;Reset&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the top of the &lt;code&gt;Counter&lt;/code&gt; component, we do two important things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use the &lt;code&gt;useSelector&lt;/code&gt; hook to access the value of the &lt;code&gt;count&lt;/code&gt; property inside our store's &lt;code&gt;state&lt;/code&gt; object, and then save it inside a constant named &lt;code&gt;count&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Invoke the &lt;code&gt;useDispatch&lt;/code&gt; hook. The result, which we save as the constant &lt;code&gt;dispatch&lt;/code&gt;, is a reference to the &lt;code&gt;dispatch&lt;/code&gt; function in the Redux store.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's all we need to work with our store!&lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;useDispatch&lt;/code&gt; hook, we do need to import any actions we're going to use, so we can invoke it as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;incrementCounter&lt;/span&gt;&lt;span class="p"&gt;())}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;+&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also pass a payload to the action creator if needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setCustomCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;419&lt;/span&gt;&lt;span class="p"&gt;))}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;Set&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;419&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And...that's it! We've hooked our app up to our Redux store.&lt;br&gt;
&lt;a href="https://codesandbox.io/s/redux-counter-4rpht?file=/src/App.js" rel="noopener noreferrer"&gt;Here's the link&lt;/a&gt; to the finished app, in case you don't want to scroll all the way back up to the sandbox.&lt;/p&gt;

&lt;p&gt;And here's the code!&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/4rpht"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For a more detailed look at &lt;code&gt;useSelector&lt;/code&gt; and &lt;code&gt;useDispatch&lt;/code&gt;, please refer to the React Redux documentation:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://react-redux.js.org/next/api/hooks#useselector" rel="noopener noreferrer"&gt;&lt;code&gt;useSelector&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react-redux.js.org/next/api/hooks#usedispatch" rel="noopener noreferrer"&gt;&lt;code&gt;useDispatch&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary &lt;span id="summary"&gt;&lt;/span&gt;
&lt;/h2&gt;

&lt;p&gt;We covered a massive amount of ground in this article.&lt;/p&gt;

&lt;p&gt;Here are the key concepts we covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redux is a state management library that acts as the &lt;strong&gt;single source of truth&lt;/strong&gt; for your app's state-related logic.&lt;/li&gt;
&lt;li&gt;To implement Redux, you should implement the following in your app:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Action creators:&lt;/strong&gt; functions that are dispatched when your app triggers an action.&lt;/li&gt;
&lt;li&gt;Every action creator returns an &lt;strong&gt;action&lt;/strong&gt;, an object with instructions for updating the state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reducers:&lt;/strong&gt; functions that take a state object and action as parameters, and return an object containing the app's updated state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store:&lt;/strong&gt; An object containing the entirety of your app's Redux state.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;To give your app access to the store, wrap it inside a &lt;code&gt;Provider&lt;/code&gt; component.&lt;/li&gt;

&lt;li&gt;Use the &lt;code&gt;useSelector&lt;/code&gt; and &lt;code&gt;useDispatch&lt;/code&gt; hook to access state and dispatch action creators from inside any component inside your app.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;If you're feeling lost, that's normal. It took me at least three separate tries to understand Redux well enough to implement it in a tiny app.&lt;/p&gt;

&lt;p&gt;If you're having trouble with these concepts, take some time to check out the excellent explanations provided in the official &lt;a href="https://redux.js.org/tutorials/essentials/part-1-overview-concepts" rel="noopener noreferrer"&gt;Redux documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps &lt;span id="next-steps"&gt;&lt;/span&gt;
&lt;/h2&gt;

&lt;p&gt;As you're getting more comfortable with Redux, I highly recommend that you do the following:&lt;/p&gt;

&lt;h3&gt;
  
  
  Read "You Might Not Need Redux" &lt;span id="read-you-might-not-need-redux"&gt;&lt;/span&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://twitter.com/dan_abramov" rel="noopener noreferrer"&gt;Dan Abramov&lt;/a&gt; is famous for creating Redux and working on Create React App and React hooks. He also wrote a very insightful article called&lt;br&gt;
&lt;a href="https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367" rel="noopener noreferrer"&gt;&lt;em&gt;You Might Not Need Redux&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Redux is a great tool to have, but it's just that — a tool. You shouldn't use it if you don't need it. For smaller apps, React state may be enough. For larger apps, you may find yourself using a mixture of Redux state for data used globally and React state for more localized state.&lt;/p&gt;
&lt;h3&gt;
  
  
  Build an app with Redux &lt;span id="build-an-app-with-redux"&gt;&lt;/span&gt;
&lt;/h3&gt;

&lt;p&gt;I want you to implement Redux in a React app. I recommend keeping the app as simple as possible; this will let you focus more on the implementation of Redux, as opposed to React itself.&lt;/p&gt;

&lt;p&gt;Some ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a score counter for a sports game (any sport of your choice). Give users the option to add points for either team. You can even include a winning condition (one team wins when they attain a certain number of points).&lt;/li&gt;
&lt;li&gt;Build your own counter, using Counter 3.0 (the one we just finished going
over) as a reference.&lt;/li&gt;
&lt;li&gt;Up for a challenge? Create a simplified ecommerce app with a shopping cart that displays items as you click on them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to use this sandbox as a reference. It's our counter from before, to include some best practices that are explained in the comments.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/bl482"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Explore Redux Toolkit &lt;span id="explore-redux-toolkit"&gt;&lt;/span&gt;
&lt;/h3&gt;

&lt;p&gt;I mentioned Redux Toolkit at the very beginning of this post. Once you're comfortable with how Redux works, you should make an effort to move to Redux Toolkit. It simplifies a lot of the code that we just wrote. After working with vanilla Redux, you'll see the benefits immediately.&lt;/p&gt;

&lt;p&gt;Redux Toolkit was built by the Redux.js team and is described as "the official, opinionated, batteries-included toolset for efficient Redux development" on &lt;a href="https://redux-toolkit.js.org/" rel="noopener noreferrer"&gt;the library's site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As someone who cut their teeth on Redux and then moved to Redux Toolkit, trust me when I say it's the way that any team should work with Redux logic.&lt;/p&gt;

&lt;p&gt;But wait - if Redux Toolkit is the modern Redux implementation you should use, why did we spend an entire article using vanilla Redux?&lt;/p&gt;




&lt;h2&gt;
  
  
  Afterword: Why This Article Uses Vanilla Redux (Instead of Redux Toolkit) &lt;span id="why-this-article-uses-vanilla-redux"&gt;&lt;/span&gt;
&lt;/h2&gt;

&lt;p&gt;I believe that the basic Redux.js library provides the most direct way to learn how Redux works. With Redux Toolkit, you're able to leverage many new APIs that improve on Redux's functionality. However, to really grasp what these improvements are doing, and why they're so important, you need a firm understanding of how Redux works.&lt;/p&gt;

&lt;p&gt;For instance, Redux Toolkit's &lt;a href="https://redux-toolkit.js.org/api/createSlice" rel="noopener noreferrer"&gt;&lt;code&gt;createSlice&lt;/code&gt;&lt;/a&gt; API is one of my favorite features, as it removes the need to create a separate file for your action creators - it automatically generates them from your reducer. To really understand how powerful this is, you should have a solid understanding of what action creators and actions are.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vanilla Redux lets you learn Redux with the smallest amount of abstractions&lt;/li&gt;
&lt;li&gt;Redux Toolkit builds on the original Redux library with more powerful APIs, and you should use it once you understand how Redux works&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's also worth mentioning that some teams with older codebases may still be using the older version of Redux, just as many React codebases will feature&lt;br&gt;
class-based state instead of hooks (or a mixture of the two). While this shouldn't be your motivation for learning vanilla Redux, it's definitely a side benefit that makes you more versatile.&lt;/p&gt;




&lt;p&gt;We've covered so much knowledge in this post. Take a break and let it sink in before you do anything else!&lt;/p&gt;

</description>
      <category>redux</category>
      <category>react</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>NPM Cheatsheet for React &amp; Express</title>
      <dc:creator>Zac Haluza</dc:creator>
      <pubDate>Sat, 28 Mar 2020 19:57:04 +0000</pubDate>
      <link>https://forem.com/zhaluza/npm-cheatsheet-for-react-express-23af</link>
      <guid>https://forem.com/zhaluza/npm-cheatsheet-for-react-express-23af</guid>
      <description>&lt;p&gt;Whenever I start a new project, I often find myself copying my setup boilerplate from past projects. I'm sure I'm not the only one.&lt;/p&gt;

&lt;p&gt;That's why I put together a quick cheatsheet that includes some of the most essential NPM packages to install for apps built with React and Express. Although this setup is mainly geared towards CRUD apps, you can also reference individual sections (such as the React and Redux parts).&lt;/p&gt;

&lt;p&gt;Your preferred setup may differ from mine, so if you feel I've neglected some of your favorite NPM packages (or if you disagree with some of my choices), feel free to let me know in the comments!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unless otherwise noted, each package can be installed as such: &lt;code&gt;npm install NAME&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;p&gt;Back End&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Express Setup&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OPTIONAL Express Packages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Database Setup&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Front End&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
React Setup

&lt;ul&gt;
&lt;li&gt;Webpack&lt;/li&gt;
&lt;li&gt;OPTIONAL for Webpack&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;OPTIONAL for React&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Redux Setup&lt;/li&gt;
&lt;li&gt;OPTIONAL for Redux&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Back End&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Express Setup&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://expressjs.com/"&gt;&lt;strong&gt;express&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/cookie-parser"&gt;&lt;strong&gt;cookie-parser&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Parses cookie header and populates req.cookies with an object keyed by the cookie names.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/nodemon"&gt;&lt;strong&gt;nodemon&lt;/strong&gt;&lt;/a&gt; &lt;em&gt;(dev dependency)&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Restarts server after any changes are made, unlike the standard &lt;code&gt;node&lt;/code&gt; command, which does not respond to changes made after running.&lt;/li&gt;
&lt;li&gt;Use in your &lt;code&gt;start&lt;/code&gt; script like so: &lt;code&gt;nodemon server.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Not strictly necessary, but will greatly improve your efficiency as a developer.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/bcrypt"&gt;&lt;strong&gt;bcrypt&lt;/strong&gt; &lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Popular authentication tool for hashing and verifying passwords (and other information)&lt;/li&gt;
&lt;li&gt;Feel free to use other authentication solutions like &lt;a href="https://www.npmjs.com/package/passport"&gt;Passport.js&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Note: &lt;a href="https://www.npmjs.com/package/body-parser"&gt;body-parser&lt;/a&gt; is deprecated. The &lt;a href="http://expressjs.com/en/api.html#express.json"&gt;&lt;code&gt;json&lt;/code&gt;&lt;/a&gt; and &lt;a href="http://expressjs.com/en/5x/api.html#express.urlencoded"&gt;&lt;code&gt;url-encoded&lt;/code&gt;&lt;/a&gt; functionality can be performed with native Express methods:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;urlencoded&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  OPTIONAL Express Packages&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/concurrently"&gt;&lt;strong&gt;concurrently&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Used to run multiple npm commands simultaneously.&lt;/li&gt;
&lt;li&gt;Not necessary in UNIX-like environment (e.g. Macs), which can chain commands with &amp;amp; (run all commands in parallel) or &amp;amp;&amp;amp; (waits for the previous command to finish before running)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/dotenv"&gt;&lt;strong&gt;dotenv&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Loads environmental variables from a .env file into process.env&lt;/li&gt;
&lt;li&gt;Useful for keeping private info (e.g. API keys) out of public repos&lt;/li&gt;
&lt;li&gt;Usage example:&lt;/li&gt;
&lt;li&gt;Store an API key as a variable in &lt;code&gt;.env&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;.env&lt;/code&gt; to your &lt;code&gt;.gitignore&lt;/code&gt; file so the file isn’t added to your repo.&lt;/li&gt;
&lt;li&gt;With dotenv installed, you can access that API key variable by referencing &lt;code&gt;process.env&lt;/code&gt;, e.g. &lt;code&gt;process.env.VARIABLE&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Database Setup&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  PostgreSQL&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://node-postgres.com/"&gt;&lt;strong&gt;node-postgres&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Note: install with &lt;code&gt;npm install pg&lt;/code&gt;!&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Lets node.js (and Express) interact with a PostgreSQL database&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  MongoDB&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://mongoosejs.com/"&gt;&lt;strong&gt;mongoose&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Robust wrapper for MongoDB that handles validation, casting, and business logic boilerplate.&lt;/li&gt;
&lt;li&gt;One of Mongoose's central features is its ability to create schemas for MongoDB collections.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Front End&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  React Setup&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You can ignore this section if you're using &lt;code&gt;create-react-app&lt;/code&gt;!&lt;/p&gt;

&lt;h4&gt;
  
  
  Webpack&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Install all webpack-related packages as &lt;em&gt;dev dependencies&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://webpack.js.org/"&gt;&lt;strong&gt;webpack&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/webpack-cli"&gt;&lt;strong&gt;webpack-cli&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Webpack's official CLI (command line interface), providing access to many convenient commands, such as creating a new webpack configuration or migrating a project from one version to another.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/webpack-dev-server"&gt;&lt;strong&gt;webpack-dev-server&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Provides a development server for webpack, complete with live reloading&lt;/li&gt;
&lt;li&gt;Recommended NPM script: &lt;code&gt;"start:dev": "webpack-dev-server"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://babeljs.io/docs/en/next/babel-core.html"&gt;&lt;strong&gt;@babel/core&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Babel compiler core&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://babeljs.io/docs/en/next/babel-preset-env.html"&gt;&lt;strong&gt;@babel/preset-env&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;A smart preset that lets you use the lastest JavaScript features without worrying about which syntax transforms and browser polyfills your target environments require.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://babeljs.io/docs/en/next/babel-preset-react.html"&gt;&lt;strong&gt;@babel/preset-react&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;A Babel preset for all React plugins&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/babel-loader"&gt;&lt;strong&gt;babel-loader&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Lets you transpile files using Babel &amp;amp; Webpack&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/css-loader"&gt;&lt;strong&gt;css-loader&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Interprets &lt;code&gt;@import&lt;/code&gt; and &lt;code&gt;url()&lt;/code&gt; in CSS files&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/style-loader"&gt;&lt;strong&gt;style-loader&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Injects CSS into the DOM&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  OPTIONAL for Webpack&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/sass-loader"&gt;sass-loader&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Loads Sass/SCSS files and compiles them to CSS.&lt;/li&gt;
&lt;li&gt;Only necessary if you're using Sass... which you should probably use.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  React&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/"&gt;&lt;strong&gt;react&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/react-dom"&gt;&lt;strong&gt;react-dom&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Serves as the entry point to the DOM and service renderers for React. Should be paired with the generic &lt;code&gt;react&lt;/code&gt; package above.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  OPTIONAL for React&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/react-router-dom"&gt;&lt;strong&gt;react-router-dom&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Performs client-side routing without the need to contact the server.&lt;/li&gt;
&lt;li&gt;Lets you use React Router in a web setting (&lt;code&gt;react-router-native&lt;/code&gt; is also available for React Native).&lt;/li&gt;
&lt;li&gt;Read more on the &lt;a href="https://reacttraining.com/react-router/"&gt;official site&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/node-sass"&gt;&lt;strong&gt;node-sass&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Natively and automatically compiles .scss files to CSS.&lt;/li&gt;
&lt;li&gt;Lets you directly use .scss files in React, which is awesome.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Redux Setup&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://redux.js.org/"&gt;&lt;strong&gt;redux&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://react-redux.js.org/"&gt;&lt;strong&gt;react-redux&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Note that it's necessary to also install the React-specific version of Redux, since Redux can be used with a variety of frameworks — and even Vanilla JS.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  OPTIONAL for Redux&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; Both Thunk and Saga are used to let Redux perform asynchronous actions. You can choose one or the other, although Thunk is by far the more popular option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Redux Thunk:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/redux-thunk"&gt;&lt;strong&gt;redux-thunk&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/35411423/how-to-dispatch-a-redux-action-with-a-timeout/35415559#35415559"&gt;An in-depth introduction to thunks in Redux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For Redux Saga:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://redux-saga.js.org/"&gt;&lt;strong&gt;redux-saga&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From the &lt;a href="https://redux-saga.js.org/"&gt;official site&lt;/a&gt;: "You might've used &lt;code&gt;redux-thunk&lt;/code&gt; before to handle your data fetching. Contrary to redux thunk, you don't end up in callback hell, you can test your asynchronous flows easily and your actions stay pure."&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;These packages may be required for Redux saga to function properly:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/regenerator-runtime"&gt;&lt;strong&gt;regenerator-runtime&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Standalone runtime for &lt;a href="https://github.com/facebook/regenerator"&gt;Regenerator&lt;/a&gt;-compiled generator and &lt;code&gt;async&lt;/code&gt; functions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/core-js"&gt;&lt;strong&gt;core-js&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Modular standard library for JavaScript&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Did I miss anything? Let me know below!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>express</category>
      <category>tutorial</category>
      <category>npm</category>
    </item>
    <item>
      <title>Global Styling in React Native</title>
      <dc:creator>Zac Haluza</dc:creator>
      <pubDate>Sat, 01 Feb 2020 15:59:03 +0000</pubDate>
      <link>https://forem.com/zhaluza/global-styling-in-react-native-1640</link>
      <guid>https://forem.com/zhaluza/global-styling-in-react-native-1640</guid>
      <description>&lt;p&gt;If you've spent any time with React Native, you've surely noticed that all styling is done with &lt;strong&gt;JavaScript, not CSS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For developers who are experienced with React (or web development in general) but not React Native, the idea of styling your components without the use of CSS classes may be frustrating.&lt;/p&gt;

&lt;p&gt;I know it was for me.&lt;/p&gt;

&lt;p&gt;In this post, I'm going to tackle the issue of &lt;strong&gt;implementing global styling&lt;/strong&gt; in a React Native app.&lt;/p&gt;

&lt;p&gt;Here are three ways to apply global styling to a React Native app:&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Method 1: Custom Components
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Method 2: Global Stylesheet
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Method 3: Combine Both Approaches
&lt;/h4&gt;




&lt;h3&gt;
  
  
  Method 1: Custom Components &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Since React is component-driven, the most intuitive way is to create custom components (e.g. custom text fields, custom buttons, etc.), define the styles within each component, and reuse these components throughout the app. &lt;/p&gt;

&lt;p&gt;For example, to use a specific font color throughout the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BlueText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blueText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;blueText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;BlueText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; By using the spread operator in the style property, we can &lt;strong&gt;overwrite&lt;/strong&gt; any styling in this custom component when we actually implement the component. &lt;/p&gt;

&lt;p&gt;For instance, in the app itself, we could directly overwrite the blue color property by adding some inline styling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BlueText&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Red&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/BlueText&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Method 2: Global Stylesheet &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Create a single stylesheet (e.g. in the &lt;code&gt;constants&lt;/code&gt; folder) and manage all styles from inside there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;blueText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;redText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Method 3: Combine Both Approaches &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Since React is component-driven, it might make more sense to focus on creating custom components to manage global styles. &lt;/p&gt;

&lt;p&gt;However, you can also use a global stylesheet in the same app for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, sometimes it doesn't really make sense to create a brand-new component. Adding a new style to your stylesheet (like a CSS class) and applying it to the component in question can be much more efficient in this case.&lt;/li&gt;
&lt;li&gt;You may want to style a custom component in a slightly different way. You may want to do this multiple times, too, e.g. &lt;strong&gt;applying different font sizes&lt;/strong&gt; (14, 16, 18, etc.) to buttons that are otherwise styled identically.

&lt;ul&gt;
&lt;li&gt; In this case, it might make more sense to create smaller style objects in your &lt;strong&gt;global stylesheet&lt;/strong&gt; (e.g. &lt;code&gt;fontSmall&lt;/code&gt;, &lt;code&gt;fontMed&lt;/code&gt;), handle the different property (or properties) in there, and then reference it in the style property of the custom component like so:
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./constants/GlobalStyles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Custom&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;GlobalStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontSmall&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tap Me&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handlePress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Remember, the styles from the global stylesheet are &lt;strong&gt;overwriting&lt;/strong&gt; the default component styles because of how we used the &lt;strong&gt;spread operator&lt;/strong&gt; when defining the style property in the custom component!)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How do you approach styling in React Native? Share your thoughts below!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>tutorial</category>
      <category>ios</category>
      <category>react</category>
    </item>
    <item>
      <title>JavaScript Unit Testing 101: Mocha &amp; Chai ☕️</title>
      <dc:creator>Zac Haluza</dc:creator>
      <pubDate>Tue, 03 Dec 2019 02:43:35 +0000</pubDate>
      <link>https://forem.com/zhaluza/javascript-unit-testing-101-mocha-chai-56bi</link>
      <guid>https://forem.com/zhaluza/javascript-unit-testing-101-mocha-chai-56bi</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: this entire lesson (with testable files!) is available as a &lt;a href="https://github.com/zhaluza/js-unit-testing-tutorial"&gt;GitHub repo&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;This post is a simple walkthrough and reference for anyone interested in&lt;br&gt;
learning the basics of creating unit tests for JavaScript using Mocha and Chai.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Mocha &amp;amp; Chai?
&lt;/h3&gt;

&lt;p&gt;In terms of technology, successful JS testing requires three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testing environment/test runner&lt;/li&gt;
&lt;li&gt;Testing framework&lt;/li&gt;
&lt;li&gt;Assertion library
Different frameworks assume different combinations of these roles. Possible combinations include…&lt;/li&gt;
&lt;li&gt;Mocha JS (testing environment &amp;amp; framework) + Chai (assertion library)&lt;/li&gt;
&lt;li&gt;Jest (all-in-one)&lt;/li&gt;
&lt;li&gt;Jasmine (all-in-one)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This guide will use a combination of Mocha and Chai. However, these kinds of tests can also be run with other testing solutions like Jest. The approach is identical.&lt;/p&gt;
&lt;h3&gt;
  
  
  What's Test-Driven Development?
&lt;/h3&gt;

&lt;p&gt;Test-driven development (or TDD) is a form of development in which developers write tests for their code before they actually write the code.&lt;/p&gt;

&lt;p&gt;TDD utilizes "red-green testing": you initially write a test that will fail (red), then write and adjust your code so that the test passes (green).&lt;/p&gt;

&lt;p&gt;Here are some of the benefits of TDD:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s more efficient

&lt;ul&gt;
&lt;li&gt;You don’t have to write new tests or rewrite tests after making changes — because you’ve already written tests to anticipate the nature of your code&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You write better code

&lt;ul&gt;
&lt;li&gt;Since you plan everything out beforehand, your code is better organized&lt;/li&gt;
&lt;li&gt;It’s more testable — you don’t have to rewrite or refactor anything for tests&lt;/li&gt;
&lt;li&gt;Fewer bugs — you’ll catch them sooner, and you’ll also have regression testing built in (all the tests you’ve ever run will get re-run when you make a change)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You’ll have great code coverage

&lt;ul&gt;
&lt;li&gt;Your tests are written to cover the general breadth of your code&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Unit Testing Walkthrough
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;In the guide below, you'll conduct some basic unit tests. Unit tests focus on&lt;br&gt;
individual parts of the code, and they're likely the most common types of tests you'll perform as a developer.&lt;/p&gt;

&lt;p&gt;They're different from integration tests, which test whether a program or app functions properly as a whole.&lt;/p&gt;
&lt;h3&gt;
  
  
  Let's Get Started!
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Setting up Mocha &amp;amp; Chai
&lt;/h4&gt;

&lt;p&gt;First, set up a package.json file and import all needed dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="nx"&gt;mocha&lt;/span&gt; &lt;span class="nx"&gt;chai&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, install Babel to make sure all JS is backwards compatible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;babel&lt;/span&gt;&lt;span class="sr"&gt;/core @babel/&lt;/span&gt;&lt;span class="nx"&gt;preset&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;babel&lt;/span&gt;&lt;span class="sr"&gt;/register --save-de&lt;/span&gt;&lt;span class="err"&gt;v
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a Babel file: .babelrc&lt;br&gt;
This will make sure that Babel functions correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;presets&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@babel/preset-env&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Setting Up Our Tests
&lt;/h4&gt;

&lt;p&gt;Create a src folder. Inside it, create two files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.js file: This will contain the JavaScript we want to test&lt;/li&gt;
&lt;li&gt;test.js file: This will contain our tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Following TDD principles, the .js folder will be blank. Create a basic test&lt;br&gt;
inside the test.js folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./letter-count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getLetterCount - basic functionality&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;returns an empty object when passed an empty string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Running Our Tests
&lt;/h4&gt;

&lt;p&gt;Now run the test. First set up the testing script in the package.json file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test&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="s2"&gt;npx mocha &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;src/&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;*_/_.test.js&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; --recursive --require @babel/register&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, run the test.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="c1"&gt;// or "npm run test"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, set up a function in the .js file that will make the test pass.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Refining Our Tests
&lt;/h4&gt;

&lt;p&gt;Now we need to add tests until we see failure again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./letter-count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getLetterCount - basic functionality&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;returns an empty object when passed an empty string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;return correct letter count for a word with only one of each letter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;t&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&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="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s build out our function so it passes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;letters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;letterCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="nx"&gt;letters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letter&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;letterCount&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letterCount&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letterCount&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;letterCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is good, but let’s make sure our test passes when we use more complex words, i.e. words with more than one of a certain letter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./letter-count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getLetterCount - basic functionality&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;returns an empty object when passed an empty string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;return correct letter count for a word with only one of each letter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;t&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&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="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;return correct letter count for words with more than one of a certain letter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;m&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;i&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="na"&gt;s&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="na"&gt;p&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getLetterCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mississippi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  More Practice: isPalindrome
&lt;/h4&gt;

&lt;p&gt;Now test and create a function called isPalindrome. It should take two arguments and return “true” if the arguments are palindromes of one another. As a bonus, have the function return “true” even if…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the arguments contain spaces&lt;/li&gt;
&lt;li&gt;the arguments utilize different types of capitalization (e.g. "listen" &amp;amp; "SILENT")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Practice utilizing the principles described above to build out tests that cover any and all relevant use cases, including edge cases. Reference the repo files if you need a hint — note that your solution and test cases may differ depending on your approach (e.g. a much simpler solution would be to utilize Lodash).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What are your thoughts on unit testing and test-driven development? Do you test your code? Share your thoughts below!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;(Note: Much of the code referenced here has been adapted from the Unit Testing section of Shaun Wassel's &lt;a href="https://www.lynda.com/JavaScript-tutorials/JavaScript-Test-Driven-Development-ES6/5035830-2.html"&gt;JavaScript: Test-Driven Development (ES6)&lt;/a&gt; course on Lynda.)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Time Management for Self-Taught Coders</title>
      <dc:creator>Zac Haluza</dc:creator>
      <pubDate>Thu, 24 Oct 2019 23:14:19 +0000</pubDate>
      <link>https://forem.com/zhaluza/time-management-for-self-taught-coders-1o18</link>
      <guid>https://forem.com/zhaluza/time-management-for-self-taught-coders-1o18</guid>
      <description>&lt;p&gt;&lt;em&gt;In this post, I’ll share a few effective time management strategies I’ve used through my self-taught coding journey. I’d like to hear your thoughts about time management in the comments!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A big part of being a developer is juggling priorities. This is true whether you’re working professionally or are looking for your first job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you’re self-taught, like me, you’ve been doing this since day one, managing your own schedule and your own curriculum.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;As a self-taught (or is it &lt;strong&gt;self-teaching&lt;/strong&gt;?) coder, you have to balance your time along with the new skills you need to learn and the current skills you need to solidify. And it’s really hard to get the balance right.&lt;/p&gt;

&lt;p&gt;It’s even harder if you work a full-time job (like I do), or if you have kids, or if you have any other commitment that requires you to devote chunks of your day to non-coding priorities.&lt;/p&gt;

&lt;p&gt;When I started coding, I tried a few different time management strategies, with varying degrees of success. I believe that each of these methods can be very helpful for up-and-coming coders, especially if you tailor and combine them to fit your personal learning style, daily routine, and skill level.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Feel free to share your own time management strategies in the comments! While this post is geared toward self-taught coders (primarily because of my own self-taught background), any thoughts on time management are welcome!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 1: Journaling
&lt;/h2&gt;

&lt;p&gt;Very early into my coding journey, I started journaling my progress. After learning about the &lt;a href="https://www.100daysofcode.com/"&gt;100 Days of Code&lt;/a&gt; Challenge, I created a private GitHub repo and started recording my daily progress. I would write about what I learned that day, my thoughts about my progress, and anything else related to what I’d done that day.&lt;/p&gt;

&lt;p&gt;As a beginner, I found it extremely helpful. It was really encouraging to look back a week or two and see how far I’d come since then. I’ve been coding for almost a year, and I still do my best to keep a daily journal, although it’s not my primary focus.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 2: Timekeeping
&lt;/h2&gt;

&lt;p&gt;Once I had a decent grasp of the basics of HTML and CSS, I started balancing my time between coding static HTML/CSS layouts and learning the basic syntax of JavaScript. I used an app called &lt;a href="https://toggl.com/"&gt;Toggl&lt;/a&gt; to log my time for each activity. Toggl would tell me how long I had coded that day, and it would also tell me how much time I'd spent on each activity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;However&lt;/strong&gt;, it wasn’t long before I had too many tasks to balance. I was building apps in React, learning Node.js and Ruby, and brushing up on my existing front-end skills. I needed a new system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 3: Scheduling
&lt;/h2&gt;

&lt;p&gt;Scheduling is by far the most effective strategy for me. I started self-scheduling a year or so ago, when I was studying for the FSOT (the Foreign Service Officer Test for entering the US State Department). I ended up passing the FSOT (although I decided against moving further ahead for a whole slew of personal and political reasons that I’ll omit here), so it certainly worked for me.&lt;/p&gt;

&lt;p&gt;Every day, I wake up to a pre-written schedule of what I have to do that day. I don’t have to worry about timing myself. I just have to sit down in a chair and code for each block of time. It takes a lot of the worrying and guesswork out of my earlier strategies and adds a comforting framework to my studies.&lt;/p&gt;

&lt;p&gt;Recently, I’ve split my mornings and evenings into chunks of 35 minutes. In my own variant of the Pomodoro method, I’ll work for 30 minutes and break for 5. Then I’ll switch on to the next task.&lt;/p&gt;

&lt;p&gt;For instance, my schedule after dinner might look like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;5:30-6:00&lt;/b&gt; - Redux practice&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;6:05-6:35&lt;/b&gt; - Dev.to blogging *(hey!)*&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;6:40-7:10&lt;/b&gt; - Leetcode grind&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;7:15-7:45&lt;/b&gt; - Node.js course&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;8:00-9:00&lt;/b&gt; - Exercise &lt;em&gt;(Alotting time to stretch, shower, etc.)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And so on. &lt;em&gt;Yes, I eat dinner way too early.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As someone who’s actively looking for a development job, this strategy helps me make sure I’m balancing my time among all the different skills I’m working on. And as it so happens, I have a lot of skills to work on. &lt;/p&gt;

&lt;p&gt;Your goals are probably different, so you can tweak this last strategy in a few different ways. For instance, you could increase the amount of time for each interval. You could merge time blocks if you’re working on a more intensive project, or if you’re making insane progress on one task. For instance, I had a major burst of inspiration for this post, and instead of devoting a single 30-minute block to writing, I rewrote and finished the whole thing in an hour!&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;These are three time management strategies that have worked for me. Right now, I’m obsessed with scheduling, and I expect to continue refining this particular strategy with practice. I'd also love to hear about the time management strategies that have worked for you on your coding journey.&lt;/p&gt;

&lt;p&gt;In my experience, success as a developer comes down to three main factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Identifying your goals&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Putting in the effort&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Managing your available time&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These factors are symbiotic. Once you’re aware of your goals, you can decide how you want to split your time. If you’re working hard toward your goals, your objectives will adjust, and your personal schedule will also adjust. But in many ways, efficient time management is the hardest to implement properly, and it’s also the most important.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
