<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Corina Udrescu</title>
    <description>The latest articles on DEV Community by Corina Udrescu (@ucorina).</description>
    <link>https://dev.to/ucorina</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%2F19518%2F6e36a6e3-b616-4640-a93a-67f209438a9a.jpeg</url>
      <title>DEV Community: Corina Udrescu</title>
      <link>https://dev.to/ucorina</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ucorina"/>
    <language>en</language>
    <item>
      <title>Authentication with Nodejs and JWTs - a simple example</title>
      <dc:creator>Corina Udrescu</dc:creator>
      <pubDate>Wed, 26 Jan 2022 08:35:40 +0000</pubDate>
      <link>https://dev.to/ucorina/authentication-with-nodejs-and-jwts-a-simple-example-4oia</link>
      <guid>https://dev.to/ucorina/authentication-with-nodejs-and-jwts-a-simple-example-4oia</guid>
      <description>&lt;p&gt;When it comes to JWTs, most tutorials help you build a full implementation in Node. However, they rarely stop to show just the basics - just the esssential parts that need to be there for JWT authentication to work, and nothing more.&lt;/p&gt;

&lt;p&gt;This article aims to give a simple, straightforward overview of the steps needed to add JWT auth to a Node app.&lt;/p&gt;

&lt;p&gt;We'll start from an unprotected API with a super secret resource and go towards securing it with JSON Web Tokens (JWTs).&lt;/p&gt;

&lt;h3&gt;
  
  
  What we'll build
&lt;/h3&gt;

&lt;p&gt;Our API will only contain two endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/login&lt;/code&gt; - will return the token&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/super-secret-resource&lt;/code&gt; - the information that only logged in users should access&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Creating a Node API with Express
&lt;/h3&gt;

&lt;p&gt;Let's start from the barebones - just an API that returns a very important resource, that should only be accessed by logged in users. This endpoint should return &lt;code&gt;401 Unauthorized&lt;/code&gt; if the user is not logged in. Since we don't have the &lt;code&gt;/login&lt;/code&gt; endpoint yet, it will just always return 401 for now.&lt;/p&gt;

&lt;p&gt;Create a new folder for the project, run &lt;code&gt;npm init -y&lt;/code&gt; to initialize the project and run &lt;code&gt;npm install express&lt;/code&gt; to install &lt;code&gt;express&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, create a &lt;code&gt;server.js&lt;/code&gt; file for the node app. In its simplest form, this is how the API would look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// server.js
const express = require("express");
const app = express();

app.get("/super-secure-resource", (req, res) =&amp;gt; {
  res
    .status(401)
    .json({ message: "You need to be logged in to access this resource" });
});

app.listen(3001, () =&amp;gt; {
  console.log("API running on localhost:3001");
});

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

&lt;/div&gt;



&lt;p&gt;To start the API,  run &lt;code&gt;node server.js&lt;/code&gt; in the console.&lt;/p&gt;

&lt;p&gt;To check that the endpoint cannot be accessed, run &lt;code&gt;curl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -i localhost:3001/super-secure-resource

// Will output:
// 
// HTTP/1.1 401 Unauthorized
// X-Powered-By: Express
// Content-Type: application/json; charset=utf-8
// Content-Length: 62
// ETag: W/"3e-eJQzoUv1nk6AKpsmnnXBmFvKrI4"
// Date: Sat, 22 Jan 2022 09:05:53 GMT
// Connection: keep-alive
// Keep-Alive: timeout=5
// 
// {"message":"You need to be logged in to access this resource"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-i&lt;/code&gt; flag tells &lt;code&gt;curl&lt;/code&gt; to also return the headers, so we can see the HTTP status code.&lt;/p&gt;

&lt;p&gt;Notice the &lt;code&gt;401&lt;/code&gt; HTTP status code - which stands for "Unauthorized" - and the message we returned from the endpoint.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Return a JWT token on successful login
&lt;/h3&gt;

&lt;p&gt;Next, we want to allow users to login and send back a verified token if their user and password are correct.&lt;/p&gt;

&lt;p&gt;Since setting up a full database of users and password is out of the scope of this article, we'll just hardcode an &lt;code&gt;admin/admin&lt;/code&gt; user and check for that as an example.&lt;/p&gt;

&lt;p&gt;The first step is to install the npm &lt;a href="https://www.npmjs.com/package/jsonwebtoken"&gt;jsonwebtoken&lt;/a&gt; module. This package will help us sign and verify JWT tokens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install jsonwebtoken
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, the endpoint will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require("express");
const jsonwebtoken = require("jsonwebtoken");

// The secret should be an unguessable long string (you can use a password generator for this!)
const JWT_SECRET =
  "goK!pusp6ThEdURUtRenOwUhAsWUCLheBazl!uJLPlS8EbreWLdrupIwabRAsiBu";

const app = express();
app.use(express.json());

app.post("/login", (req, res) =&amp;gt; {
  const { username, password } = req.body;
  console.log(`${username} is trying to login ..`);

  if (username === "admin" &amp;amp;&amp;amp; password === "admin") {
    return res.json({
      token: jsonwebtoken.sign({ user: "admin" }, JWT_SECRET),
    });
  }

  return res
    .status(401)
    .json({ message: "The username and password your provided are invalid" });
});

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

&lt;/div&gt;



&lt;p&gt;Some things to note here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;JWT_SECRET&lt;/code&gt; should be an unguessable long string&lt;/li&gt;
&lt;li&gt;the part that actually does the signing is: &lt;code&gt;jsonwebtoken.sign({ user: "admin" }, JWT_SECRET)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can check a token is returned with curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST http://localhost:3001/login --header "Content-Type: application/json" --data '{ "username": "admin", "password": "admin" }'

// {"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJpYXQiOjE2NDI4NDQ0NTR9.O_710gS-6t9nmqvW0_E1GlP7MdoLMFR85GXUUeskNi8"}

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

&lt;/div&gt;



&lt;p&gt;You can decode the token and see what it contains on jwt.io&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n5fO9GlC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jsramblings.com/content/images/2022/01/jwt-io-decoded-token.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n5fO9GlC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jsramblings.com/content/images/2022/01/jwt-io-decoded-token.png" alt="" width="880" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some things to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The "Header" of the token contains the algorithm used - in our case, the algorithm for signing the token is HS256&lt;/li&gt;
&lt;li&gt;You can input your secret in the bottom right to have jwt.io verify the token signature (if the signature is verified, it means the token hasn't been tampered with)&lt;/li&gt;
&lt;li&gt;Besides the &lt;code&gt;{ user: admin }&lt;/code&gt; which we encoded, there's also another property there - &lt;code&gt;iat&lt;/code&gt;, added by the &lt;code&gt;jsonwebtoken&lt;/code&gt; library; this stands for "Issued at" - i.e. when the server created the token (as Unix timestamp)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Send the token to the /super-secure-resource and verify it to allow access
&lt;/h3&gt;

&lt;p&gt;Now let's use that token to allow the logged in user to access the restricted resource!&lt;/p&gt;

&lt;p&gt;In order to do that, we will need to send the token to the API (as an &lt;code&gt;Authorization&lt;/code&gt; header) and then verify the token on the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -i localhost:3001/super-secure-resource --Header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJpYXQiOjE2NDI4NDYzMzV9.gQj-qjoQwtvyU2XzER6yiT-T4DwYphjMft-kogW978c'

// Will return:
//
// HTTP/1.1 200 OK
// X-Powered-By: Express
// Content-Type: application/json; charset=utf-8
// Content-Length: 69
// ETag: W/"45-9rvFFDk8vkfruRd3Ok0vQNGIdMk"
// Date: Sat, 22 Jan 2022 10:15:03 GMT
// Connection: keep-alive
// Keep-Alive: timeout=5
//
// {"message":"Congrats! You can now accesss the super secret resource"}

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

&lt;/div&gt;



&lt;p&gt;Why this works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;By signing the token, you ensure that the server can check that whatever token it receives, was created by itself&lt;/li&gt;
&lt;li&gt;If you try to tamper with the token, you'll invalidate it! The server will tell it's been tampered, so it will not authorise you!&lt;/li&gt;
&lt;li&gt;Try it out: take the token, change it in jwt.io and try again -&amp;gt; it will fail!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Make it yours!
&lt;/h3&gt;

&lt;p&gt;I specifically kept the source code for this article very barebones. Go ahead and improve it!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;nodemon&lt;/code&gt; to automatically reload the server when you change the API&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;nodeenv&lt;/code&gt; and move the JWT_SECRET to as an environment variable&lt;/li&gt;
&lt;li&gt;Setup an &lt;em&gt;actual&lt;/em&gt; database with users and passwords&lt;/li&gt;
&lt;li&gt;Add more endpoints and move the code that verifies the token in an express middleware&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>authentication</category>
    </item>
    <item>
      <title>How to check if your component rerendered - and why!</title>
      <dc:creator>Corina Udrescu</dc:creator>
      <pubDate>Mon, 11 Oct 2021 18:00:55 +0000</pubDate>
      <link>https://dev.to/ucorina/how-to-check-if-your-component-rerendered-and-why-2a96</link>
      <guid>https://dev.to/ucorina/how-to-check-if-your-component-rerendered-and-why-2a96</guid>
      <description>&lt;p&gt;If you're like me, you're probably using &lt;code&gt;console.log&lt;/code&gt; a lot to check the React rendering lifecycle of your components 😅 When it rerendered, why - was it a &lt;code&gt;setState&lt;/code&gt; or something else ?! - or even just to get a better handle of React fundamentals.&lt;/p&gt;

&lt;p&gt;This &lt;em&gt;can&lt;/em&gt; work fine at the beginning - but what if you want to answer bigger questions about your app - like whether using Context has an impact on the performance of your app? Or simply, what if you're tired of scrolling through tens of &lt;code&gt;console.log&lt;/code&gt;s figuring out what executed when?&lt;/p&gt;

&lt;p&gt;Then it's time to use the React DevTools! Not only do they allow you to visually see what components rerender, but you can also investigate &lt;em&gt;what&lt;/em&gt; caused each rerender and easily spot what components are taking longest to render.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using React DevTools to highlight what components rerendered
&lt;/h2&gt;

&lt;p&gt;There's a checkbox well hidden in the React DevTools settings that allows you to visually highlight the components that rerendered.&lt;/p&gt;

&lt;p&gt;To enable it, go to "Profiler" &amp;gt;&amp;gt; click the "Cog wheel" on the right side of the top bar &amp;gt;&amp;gt; "General" tab &amp;gt;&amp;gt; Check the "Highlight updates when components render." checkbox.&lt;/p&gt;

&lt;p&gt;Then just interact with your app as usual and watch it all light up ✨&lt;/p&gt;


        
    

&lt;h2&gt;
  
  
  Using React DevTools to find out the cause of a rerender
&lt;/h2&gt;

&lt;p&gt;Now that you can &lt;em&gt;see&lt;/em&gt; your component rerendered, the next question is .. why?&lt;/p&gt;

&lt;p&gt;There's a very handy tooltip that shows up when hovering over a component in the "Flamegraph", that shows the reason for a render under the "Why did this render?" heading.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k3dSU8ln--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jsramblings.com/content/images/2021/10/why-did-this-render-tooltip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k3dSU8ln--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jsramblings.com/content/images/2021/10/why-did-this-render-tooltip.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see this, you need to record a "Profiler" session.&lt;/p&gt;

&lt;p&gt;For example, if you your component re-renders after you click a button, you can click record to start profiling, click the button in question, then stop profiling and see the details of what happened when the button was clicked.&lt;/p&gt;


        
    

&lt;p&gt;Here's how to read the profiler output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the top right you have the number of React commits - each bar represents a moment when the React component tree changed and a change was commited to the DOM&lt;/li&gt;
&lt;li&gt;The "Flamegraph" shows the component tree and what changed - "grey" means the component did not rerender&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hovering over each component will reveal why it rendered in the "Why did this render?" subheading.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/facebook/react/blob/033efe7312cdf73118922b279d9b1ae29a2f693d/packages/react-devtools-shared/src/devtools/views/Profiler/WhatChanged.js#L40"&gt;Possible values&lt;/a&gt; you can expect to see as reasons for a component rerendering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"This is the first time the component rendered."&lt;/li&gt;
&lt;li&gt;"Context changed"&lt;/li&gt;
&lt;li&gt;"Hooks changed"&lt;/li&gt;
&lt;li&gt;"Props changed"&lt;/li&gt;
&lt;li&gt;"State changed"&lt;/li&gt;
&lt;li&gt;"The parent component rendered."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll notice that sometimes the reason is not very detailed - simply saying "hook changed" instead of the details of &lt;em&gt;what&lt;/em&gt; hooked changed. This is expected and it happens because sometimes the DevTools simply does not have access to that information or because it would be too slow to retrieve.&lt;/p&gt;

&lt;p&gt;When you click a component in the "Flamegraph", the right sidebar will update to show all renders of that component instance and why they happened:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9Cj1nEBC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jsramblings.com/content/images/2021/10/why-did-this-render-sidebar-devtools.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9Cj1nEBC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jsramblings.com/content/images/2021/10/why-did-this-render-sidebar-devtools.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus tip: See at a glance what components took longest to render
&lt;/h2&gt;

&lt;p&gt;It took me a while to figure this one out, but the colors in the "Flamegraph" actually have a meaning: "cool" colors - like shades of blue - signify the component took little time to render compared with everything else and "warm" colors - like orange and red - signify the component took a longer time to render 😀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m-Fi4MC4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jsramblings.com/content/images/2021/10/render-duration.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m-Fi4MC4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jsramblings.com/content/images/2021/10/render-duration.png" alt=""&gt;&lt;/a&gt;flamechart color - yellow took longest&lt;/p&gt;

&lt;p&gt;Notice how I just said "more time" or "less time" to render - that's because what is slow or fast is relative to your specific app and total render time. So it could be that a "yellow" component rerendered very fast if it's part of a simple component tree, or for a "blue" component to actually take a very long time to render if the whole app is very slow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus tip: See what DOM changes actually happened
&lt;/h2&gt;

&lt;p&gt;Even if a component rerendered, it doesn't mean that any changes were actually applied to the DOM - it could be that the output of &lt;code&gt;render&lt;/code&gt; was the same as before, in which case React does nothing. But how can you check? How can you visually see what DOM parts were rerendered?&lt;/p&gt;

&lt;p&gt;The Chrome DevTools have a very useful setting for this - "Paint flashing". This will highlight all elements of a page that were "repainted". To enable it, you need to click the "Settings" menu, then "More settings" and then "Rendering" and check the "Enable paint flashing" checkbox.&lt;/p&gt;


        
    

&lt;h2&gt;
  
  
  Try it out for yourself!
&lt;/h2&gt;

&lt;p&gt;You can find the sample app used for this blog post at &lt;a href="https://stackblitz.com/edit/react-3cmy6b"&gt;https://stackblitz.com/edit/react-3cmy6b&lt;/a&gt;. (Make sure to click "Open in New Window" in the top bar in order to see the app outside of the StackBlitz environment, which makes it easier to profile. )&lt;/p&gt;

&lt;p&gt;Can you figure out why all "cards" render when just one is clicked? And moreover, can you fix it? 😀&lt;/p&gt;

&lt;p&gt;Fork the code and share your solution in the comments below!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Should you switch to useReducer or is useState enough for your needs?</title>
      <dc:creator>Corina Udrescu</dc:creator>
      <pubDate>Mon, 13 Sep 2021 07:40:47 +0000</pubDate>
      <link>https://dev.to/ucorina/should-you-switch-to-usereducer-or-is-usestate-enough-for-your-needs-epp</link>
      <guid>https://dev.to/ucorina/should-you-switch-to-usereducer-or-is-usestate-enough-for-your-needs-epp</guid>
      <description>&lt;p&gt;The &lt;code&gt;useReducer&lt;/code&gt; hook is usually recommended when the state becomes complex, with state values depending on each other or when the next state depends on the previous one. However, many times you can simply bundle your separate &lt;code&gt;useState&lt;/code&gt; statements into one object and continue to use &lt;code&gt;useState&lt;/code&gt;. So when is the extra boilerplate required for &lt;code&gt;useReducer&lt;/code&gt; justified after all?&lt;/p&gt;

&lt;h3&gt;
  
  
  When there is complex business logic
&lt;/h3&gt;

&lt;p&gt;Structuring your code with actions allows for better encapsulation of business logic.&lt;/p&gt;

&lt;p&gt;Also, it allows you to separate the description of the action (WHAT happened) from how the state should update because of it (HOW it should be handled).&lt;/p&gt;

&lt;p&gt;A simple example to showcase this is updating the state when the user navigates to the next page on a paginated list view.&lt;/p&gt;

&lt;p&gt;With the hook, this could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setState(state =&amp;gt; { ...state, page + 1})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, with actions, you can add more semantics to this event and encapsulate the logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// action
dispatch({ type: 'GO_TO_NEXT_PAGE' })
// reducer
case 'GO_TO_NEXT_PAGE':
  return { ...state, page: state.page + 1}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the future, if you decide something else needs to happen when the user clicks the "Next page" button, you only need to update one place: the reducer.&lt;/p&gt;

&lt;p&gt;While this is a simple example, for deep nested values or arrays of objects, abstracting away the state update logic can be very valuable.&lt;/p&gt;

&lt;h3&gt;
  
  
  When there are many ways the state can be updated
&lt;/h3&gt;

&lt;p&gt;In most situations, there are only a couple events that update the state - take for an example a simple login flow, where you only need to track loading, success and error states. In this case,  &lt;code&gt;useReducer&lt;/code&gt; does not add that much value.&lt;/p&gt;

&lt;p&gt;However, imagine a more complex login process, like multi-factor authentication, where the user needs to be guided over several screens - to enter his password, to enter the one time token - and you need to handle all sorts of edge cases like the QR code expiring, the password being incorrect etc.&lt;/p&gt;

&lt;p&gt;In these situations reducers can really make it easier to follow the different component states and how they change.&lt;/p&gt;

&lt;h3&gt;
  
  
  When you need better debugging
&lt;/h3&gt;

&lt;p&gt;Tracking how the component state changes after each &lt;code&gt;setState&lt;/code&gt;  is generally harder to do than just having all changes go through a reducer.&lt;/p&gt;

&lt;p&gt;Regardless if you prefer using &lt;code&gt;console.log&lt;/code&gt;  or breakpoints, it's easier to add just one log/breakpoint in the reducer as opposed to one for each  call sprinkled across the component.&lt;/p&gt;

&lt;p&gt;And if you ever decide to switch to Redux, the Redux DevTools make for a great debugging experience.&lt;/p&gt;

&lt;p&gt;To wrap up, you don't need to jump to &lt;code&gt;useReducer&lt;/code&gt; as soon as you have multiple &lt;code&gt;useState&lt;/code&gt; hooks in your component. Many times, it's enough to just bundle all the state values in one object. However, if it becomes hard to figure out what's going on, &lt;code&gt;useReducer&lt;/code&gt; can be a very helpful tool!&lt;/p&gt;

&lt;p&gt;If you're interested to read more, I've found these articles helpful in my research:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/hooks-reference.html#usereducer"&gt;https://reactjs.org/docs/hooks-reference.html#usereducer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down"&gt;https://reactjs.org/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://overreacted.io/a-complete-guide-to-useeffect/#why-usereducer-is-the-cheat-mode-of-hooks"&gt;https://overreacted.io/a-complete-guide-to-useeffect/#why-usereducer-is-the-cheat-mode-of-hooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kentcdodds.com/blog/should-i-usestate-or-usereducer"&gt;https://kentcdodds.com/blog/should-i-usestate-or-usereducer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.robinwieruch.de/react-usereducer-vs-usestate"&gt;https://www.robinwieruch.de/react-usereducer-vs-usestate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>What options do you have for deploying a frontend-only React app to production?</title>
      <dc:creator>Corina Udrescu</dc:creator>
      <pubDate>Sat, 12 May 2018 03:53:00 +0000</pubDate>
      <link>https://dev.to/ucorina/what-options-do-you-have-for-deploying-a-frontend-only-react-app-to-production-20bo</link>
      <guid>https://dev.to/ucorina/what-options-do-you-have-for-deploying-a-frontend-only-react-app-to-production-20bo</guid>
      <description>&lt;p&gt;If you’ve ever wondered &lt;strong&gt;how to deploy&lt;/strong&gt; your React app once it’s ready, you probably know that figuring this out can become &lt;strong&gt;confusing really fast&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Most articles go over detailed instructions on how to configure nginx, how to configure reverse proxies. But do you really need any of these if you just have a &lt;strong&gt;frontend-only React app&lt;/strong&gt; and are looking for the easiest way to deploy?&lt;/p&gt;

&lt;p&gt;If you think about it, once you build a React app for production, you’re basically left with a bunch of &lt;code&gt;html&lt;/code&gt;, &lt;code&gt;js&lt;/code&gt; and maybe image files. This means you can deploy it to &lt;strong&gt;any hosting that supports static file hosting&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let’s go over some of the options!&lt;/p&gt;

&lt;h2&gt;
  
  
  Firebase
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://firebase.google.com/docs/hosting/"&gt;Website&lt;/a&gt; | &lt;a href="https://dev.to/sathish/deploying-my-first-react-web-app-to-firebase---36bd"&gt;How to&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Firebase is a Google service that also offers static site hosting. It comes with a free tier you can start with, deployments are done with their CLI and they support SSL, CDN &amp;amp; custom domains out of the box.&lt;/p&gt;

&lt;h2&gt;
  
  
  Netlify
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.netlify.com/"&gt;Website&lt;/a&gt; | &lt;a href="https://www.slightedgecoder.com/2017/12/09/deploying-existing-create-react-app-github-netlify/"&gt;How to&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gained a lot of traction recently. It’s a point and click interface that is very powerful, allowing you to configure automatic deployments based on a specific branch, to have ‘test’ deploys for feature branches and even do A/B testing of your website all from their UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Surge.sh
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://surge.sh/"&gt;Website&lt;/a&gt; | &lt;a href="https://dev.to/dceddia/deploy-create-react-app-with-surge-coc-temp-slug-7041928"&gt;How to&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Surge is also a static site hosting service specifically targeteted at frontend developers. Supports custom domains, even with the free plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zeit Now
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://zeit.co/now"&gt;Website&lt;/a&gt; | &lt;a href="https://zeit.co/docs/examples/create-react-app"&gt;How to&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deploy your website made as easy as running &lt;code&gt;now&lt;/code&gt; in a folder. Supports a lot of options through their CLI. Also a great choice for deploying &lt;code&gt;node&lt;/code&gt; apps or  or server-side rendered React apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Github Pages
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pages.github.com/"&gt;Website&lt;/a&gt; | &lt;a href="https://itnext.io/so-you-want-to-host-your-single-age-react-app-on-github-pages-a826ab01e48"&gt;How to&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a classic and probably the first choice if you just want a hosting for your library’s main page. Can be used for other stuff as well though since it has great integration with git and more.&lt;/p&gt;

&lt;p&gt;Since it’s not explicitly targeting SPAs, you might run into issues when setting up the routes.&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS S3 buckets
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/s3/"&gt;Website&lt;/a&gt;  | &lt;a href="https://www.fullstackreact.com/articles/deploying-a-react-app-to-s3/"&gt;How to&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the most complex of the options described so far, however comes with greater flexibility and might come in handy if you already use AWS for other things. Use it together with AWS CloudFront and AWS Route 53 for a full Amazon solution (&lt;a href="https://aws.amazon.com/blogs/mobile/deploy-a-react-app-to-s3-and-cloudfront-with-aws-mobile-hub/"&gt;described here&lt;/a&gt;). &lt;/p&gt;

&lt;h2&gt;
  
  
  Heroku, Digital Ocean, Azure or Amazon EC2
&lt;/h2&gt;

&lt;p&gt;You can always deploy your app to a custom server instance. This requires tweaking with the server, but gives you more control. You will need to install and configure a web server on the machine - either nginx, apache, IIS or whatever you’re more comfortable with - and point it to serve your static files.&lt;/p&gt;

&lt;p&gt;Though it’s tempting to use a custom setup if you already have a machine available that you’ve used for other projects, I highly recommend you try one of the options above to take your workflow to the next level :)&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
