<?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: Smilepk</title>
    <description>The latest articles on Forem by Smilepk (@smilepk).</description>
    <link>https://forem.com/smilepk</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%2F804472%2F15bd855c-6eb1-4add-92e4-b79c08374ad6.jpeg</url>
      <title>Forem: Smilepk</title>
      <link>https://forem.com/smilepk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/smilepk"/>
    <language>en</language>
    <item>
      <title>React.js Basics – The DOM, Components, and Declarative Views Explained</title>
      <dc:creator>Smilepk</dc:creator>
      <pubDate>Wed, 30 Mar 2022 03:45:47 +0000</pubDate>
      <link>https://forem.com/smilepk/reactjs-basics-the-dom-components-and-declarative-views-explained-3j85</link>
      <guid>https://forem.com/smilepk/reactjs-basics-the-dom-components-and-declarative-views-explained-3j85</guid>
      <description>&lt;p&gt;React.js is an open source JavaScript library for creating user interfaces. It was created by Facebook back in 2013.&lt;/p&gt;

&lt;p&gt;Demand for React developers is skyrocketing, which means that having knowledge of this library is definitely going to be worth it! Some of the popular websites built using ReactJS include Dropbox, Netflix, and Instacart – and the list goes on.&lt;/p&gt;

&lt;p&gt;Now, the common question that comes to everyone's mind is do we really need a JavaScript library, just for creating user interfaces? We can do the same using just HTML and CSS, right?&lt;/p&gt;

&lt;p&gt;So what makes React so popular rather than just using vanilla HTML, CSS, and JavaScript? For that, let's first look at the 2 main features of React:&lt;/p&gt;

&lt;p&gt;Declarative Views&lt;br&gt;
Component Based Approach&lt;br&gt;
Of course there is more to React than this, but we'll focus on these two features here. Before moving on and learning more about these features, we must clearly understand the browser DOM.&lt;/p&gt;

&lt;p&gt;What is the DOM?&lt;br&gt;
The DOM (Document Object Model) represents the web page as a tree structure. Any piece of HTML that we write is added as a node, to this tree.&lt;/p&gt;

&lt;p&gt;With JavaScript, we can access any of these nodes (HTML elements) and update their styles, attributes, and so on. This means that the DOM enables JavaScript to access and modify the web page easily.&lt;/p&gt;

&lt;p&gt;Now, any tree must have a root node, right? Here, the root node is document. Are you wondering where this document node came from? Well, it's part of the browser. Any HTML tag you write is going to be a direct or indirect child of the root node document.&lt;br&gt;
&lt;code&gt;&lt;br&gt;
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eocedkmthldy7lcedm4n.jpeg)&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
DOM tree with root node as document&lt;br&gt;
The below image shows the equivalent conceptual tree structure of the DOM:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SdmDsCHz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggdfyv8se2jaqmpma2wi.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SdmDsCHz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggdfyv8se2jaqmpma2wi.jpeg" alt="Image description" width="750" height="512"&gt;&lt;/a&gt;&lt;br&gt;
Browser DOM tree&lt;/p&gt;

&lt;p&gt;Now hopefully you have a clear understanding of the browser DOM. So let's dive into the two main features of ReactJS‌ that we're gonna discuss today, namely its component-based approach and declarative views.&lt;/p&gt;

&lt;p&gt;Component-Based Approach&lt;br&gt;
Everything in React is a component. A web page is a collection of components.&lt;/p&gt;

&lt;p&gt;Think of a component like a regular function in any programming language. What are the main advantages of functions? Reusability, abstraction, and avoiding redundant code, right?&lt;/p&gt;

&lt;p&gt;Same with components in React. Don't get confused with the code in the below images, as we are using a mix of HTML and JavaScript. Hang in there, we will come to that in a second.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PRgHwqdS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/og3ou1wrpw8xw6dgzprg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PRgHwqdS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/og3ou1wrpw8xw6dgzprg.jpeg" alt="Image description" width="750" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above image represents a component called Card (since the function name is Card). As mentioned earlier, functions or components can be reused any number of times. That is exactly what we are doing in the below image. We are reusing the Card component () four times. Keep in mind that, writing  is equivalent to . (Stick to the former notation, since it's more common).&lt;/p&gt;

&lt;p&gt;Card Component reused multiple times&lt;br&gt;
Congrats if you thought of this! The four  components are written inside another component called Home (since the function name is Home, ). Congrats again if you thought of this!&lt;/p&gt;

&lt;p&gt;Of course you can reuse the  component, which in turn is a collection of many  components. That is, we can nest any number of components inside other components.&lt;/p&gt;

&lt;p&gt;Now comes a big question: if components are going to be nested like we mentioned, what is the topmost component? It's the  component (provided by React). Any custom component that you write is going to be a direct or indirect child of the App component in React.&lt;/p&gt;

&lt;p&gt;On a high level, the whole component structure looks like a tree with the root node as App.&lt;/p&gt;

&lt;p&gt;Also keep in mind that component names have their first letter capitalized. This convention is used to distinguish between a React component and a regular HTML tag.&lt;/p&gt;

&lt;p&gt;What happens if you don't capitalize the first letter of a component name? There will be an ambiguity, whether it is an HTML tag or a React component.&lt;/p&gt;

&lt;p&gt;In the below image, the Navbar, Carousal, Services and so on are all components. Components altogether form the home page or Home component of a website. Neat, isn't it?&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f2apSzlF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3hedlf3k3zr5kqu522b.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f2apSzlF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3hedlf3k3zr5kqu522b.jpeg" alt="Image description" width="750" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Home page consisting of Navbar, Carousal, Services etc components&lt;br&gt;
Components are laid out in the order in which they should appear in the page. Here, the Navbar comes first, at the top, then the Carousal comes below the Navbar, so on and so forth.&lt;/p&gt;

&lt;p&gt;If you carefully observe the above images, we are using a mix of both JavaScript and HTML. This is known as JSX (Javscript XML). This is just a nice way to &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C1PzhT5_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2krn0byrk4ja5j6b937.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C1PzhT5_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2krn0byrk4ja5j6b937.jpeg" alt="Image description" width="750" height="205"&gt;&lt;/a&gt;&lt;br&gt;
Weird isn't it ? This is JSX&lt;br&gt;
In the above image, we are assigning HTML to a variable named element, just like we assign values to variables in JavaScript. Of course, you can now reuse this variable (element) anywhere in your code like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U4HYbzS5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k8oat0j1qgwci6wrf2cd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U4HYbzS5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k8oat0j1qgwci6wrf2cd.jpeg" alt="Image description" width="750" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Output of the above code &lt;br&gt;
And that's it about components in React. Now let's move onto the next feature.&lt;/p&gt;

&lt;p&gt;Declarative Views in React&lt;br&gt;
In React, we don't actually interact with the browser DOM. Yes, you heard it right! We interact with the virtual DOM, which is an exact copy of the browser DOM, but in memory.&lt;/p&gt;

&lt;p&gt;Yeah! We are dealing with a new DOM, other than the browser DOM. This means that any React component that we write is inserted as a child to the virtual DOM.&lt;/p&gt;

&lt;p&gt;You must be wondering, what why do we need this virtual DOM when we already have the browser DOM? The virtual DOM is the reason React renders so quickly and efficiently.&lt;/p&gt;

&lt;p&gt;When we update the browser DOM (when not using React), it takes a significant amount of time to lay out the elements and repaint the screen for the user to see changes. This involves a huge section of the DOM tree being repainted.&lt;/p&gt;

&lt;p&gt;But, when using React, updates happen in the virtual DOM first. Then, the browser DOM and virtual DOM are diffed or compared to see if there are any updates made to virtual DOM that must be reflected or updated in the browser DOM.&lt;/p&gt;

&lt;p&gt;If there are any, only then are updates made to the browser DOM to match the virtual DOM. And these updates are only made at places where updates are to be carried out. This means that the entire browser DOM is not updated as previously mentioned. This improves speed and efficiency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_aav22v8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zgd97iokcq59ueb6gfi.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_aav22v8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zgd97iokcq59ueb6gfi.jpeg" alt="Image description" width="750" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Only part of the DOM is getting updated, instead of whole&lt;br&gt;
Advantages of React&lt;br&gt;
Now that you know the main features of React, let's understand the advantages of using it.&lt;/p&gt;

&lt;p&gt;Code Maintainability, because we can now reuse components and break complex logic into smaller parts.&lt;br&gt;
Fast and Performant, because only part of the browser DOM is updated instead of the whole thing.&lt;br&gt;
One way Data Flow, which means that data flow is possible only from the parent component to child components. That is, components are nested, with the top most component being App. This keeps everything modular.&lt;br&gt;
Easy to learn and use, development time is less and learning curve is small.&lt;br&gt;
Suppose you want to build a complex web application. You want it to be fast and performant, and you don't have a lot of time to develop it. In this case, React should be on top of your list!&lt;/p&gt;

&lt;p&gt;Now you hopefully understand why React is so popular even though we can build a website with just HTML, CSS, and JavaScript.&lt;/p&gt;

&lt;p&gt;Now let's see, how to set up React on your machine and create a brand new project.&lt;/p&gt;

&lt;p&gt;How to Start a New React Project&lt;br&gt;
Step 1 – Install Node&lt;br&gt;
Before even thinking about React, you must have Node installed properly. This is because by installing Node you also get npm, which is a package manager for JavaScript. Think of it as an application you can use to download additional libraries, which you might need in your project.&lt;/p&gt;

&lt;p&gt;Download and install it from here: &lt;a href="https://nodejs.org/en/download/"&gt;https://nodejs.org/en/download/&lt;/a&gt; (Download the LTS version).&lt;/p&gt;

&lt;p&gt;After installation, open your terminal (Mac or Linux) or command prompt (Windows) and type in npm -v and it should output something like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tVkN9wU5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2bciakp13xpzuqqlx1q.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tVkN9wU5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2bciakp13xpzuqqlx1q.jpeg" alt="Image description" width="750" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 2 – Create your React app&lt;br&gt;
Now, it's time to install a tool which makes it easy to build a React project. Congrats! You may have guessed that I'm talking about create-react-app.&lt;/p&gt;

&lt;p&gt;Type in the command npm install create-react-app and wait for few seconds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_vNb3eQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdr9sfcmx4bmy2nd6ibt.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_vNb3eQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdr9sfcmx4bmy2nd6ibt.jpeg" alt="Image description" width="750" height="381"&gt;&lt;/a&gt;&lt;br&gt;
Step 3 – Set up your React web app&lt;br&gt;
Now let's start setting up our very first React web application. Let's name it myreactapp.&lt;/p&gt;

&lt;p&gt;For starting a new React project, type in the following command: npx create-react-app myreactapp.&lt;/p&gt;

&lt;p&gt;The general syntax is npx create-react-app  (and note that it's npx not npm, don't get confused :) ).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j6IH6hkH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09nn123otexhvlue65qe.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j6IH6hkH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09nn123otexhvlue65qe.jpeg" alt="Image description" width="699" height="438"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uuUfUWQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7q5hxi5ihp1xl2wyoib0.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uuUfUWQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7q5hxi5ihp1xl2wyoib0.jpeg" alt="Image description" width="692" height="432"&gt;&lt;/a&gt;&lt;br&gt;
Continuation of above image&lt;/p&gt;

&lt;p&gt;‌Step 4 – Open your new React app&lt;br&gt;
Now it's time to see our React app in action. For that, move into the created project (myreactapp as we created it in the previous step) by using the command cd myreactapp and type in the following: npm start.&lt;/p&gt;

&lt;p&gt;Now this command opens up a browser with our newly created React App:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xS1nCUMy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tsssxeiydsfqyzlcpr1d.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xS1nCUMy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tsssxeiydsfqyzlcpr1d.jpeg" alt="Image description" width="750" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3JQW_nJf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73zkgi1evwa1so2bhlgy.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3JQW_nJf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73zkgi1evwa1so2bhlgy.jpeg" alt="Image description" width="697" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's it! You have successfully setup React on your machine, and have started a brand new project. &lt;/p&gt;

&lt;p&gt;And now you are ready to grasp bigger concepts in React! Happy hacking&lt;/p&gt;

</description>
    </item>
    <item>
      <title>You don’t always need a CMS</title>
      <dc:creator>Smilepk</dc:creator>
      <pubDate>Tue, 08 Mar 2022 17:00:11 +0000</pubDate>
      <link>https://forem.com/smilepk/you-dont-always-need-a-cms-3cbi</link>
      <guid>https://forem.com/smilepk/you-dont-always-need-a-cms-3cbi</guid>
      <description>&lt;p&gt;When it comes to websites, blogs, and whatnot, we often expect to find a CMS power these systems.&lt;/p&gt;

&lt;p&gt;I get a lot of questions about what CMS powers my blog.&lt;br&gt;
And I'll explain that while telling you why you don't always need a CMS.&lt;/p&gt;

&lt;p&gt;What is a CMS&lt;br&gt;
Let's first take a look at what a CMS is. It stands for "Content Management System", and as the name implies, it can be used to manage the content for a website.&lt;/p&gt;

&lt;p&gt;Some famous CMSs are WordPress, Contentful, Wix, Shopify, etc.&lt;/p&gt;

&lt;p&gt;There is a big rise of "headless" CMS, which means a CMS that serves as an API.&lt;br&gt;
You have this system in place, and your website calls this API to retrieve the content.&lt;/p&gt;

&lt;p&gt;CMSs are great for people who want to edit content and don't particularly know what to do with markdown, uploading files to a server, etc.&lt;/p&gt;

&lt;p&gt;So when building websites for clients, it's often an excellent solution to pick a CMS that works for them.&lt;/p&gt;

&lt;p&gt;What I run my blog on&lt;br&gt;
I run my blog on a low-tech solution.&lt;br&gt;
It has no CMS, but plain markdown files are parsed to plain HTML and uploaded to a server.&lt;/p&gt;

&lt;p&gt;However, this is automated, so I don't have to do that physically, but there is still no content management system to alter the content.&lt;/p&gt;

&lt;p&gt;So how does this work, you ask?&lt;/p&gt;

&lt;p&gt;I open my project in my IDE of choice (Visual Studio Code, or WebStorm) and start changing my markdown files.&lt;br&gt;
Either you edit the existing ones or create new ones for new blog posts.&lt;/p&gt;

&lt;p&gt;Once I'm done, I push the changes to my git branch, which automatically triggers a GitHub action.&lt;/p&gt;

&lt;p&gt;This GitHub action starts the build command on my Eleventy project (soon to be Astro), which converts all these markdown to HTML output.&lt;br&gt;
Once this process is done, the HTML files get placed in a "static" branch.&lt;/p&gt;

&lt;p&gt;Which trigger Cloudflare pages to pull the latest changes from this branch.&lt;br&gt;
Cloudflare will do a git pull on this branch, and voila, the new changes are online!&lt;/p&gt;

&lt;p&gt;This all happens in about a minute or so.&lt;/p&gt;

&lt;p&gt;Why you don't always need a CMS&lt;br&gt;
And for me, that's the main reason I don't need a CMS. It can be such an over-engineered solution.&lt;/p&gt;

&lt;p&gt;I like to write content, markdown is the easiest way to write anyway, so I prefer it.&lt;/p&gt;

&lt;p&gt;And once the content is written, I don't want to hassle with logging in to a system, copy-pasting the content and pressing publish.&lt;/p&gt;

&lt;p&gt;(Although this is roughly the same amount of time)&lt;/p&gt;

&lt;p&gt;Another downside to these systems is that they need upkeep. The CMS gets a new version, and you need to update it.&lt;br&gt;
Something goes wrong, and you won't be able to push new content.&lt;br&gt;
And worse of all, they can get hacked, meaning your website could be at risk.&lt;/p&gt;

&lt;p&gt;Not saying it's impossible, but a static website is harder to hack. You would either need to hack my GitHub repo or my Cloudflare account, which are quite complex challenges.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
I don't want to hate on CMS. They are a fantastic system that should be used.&lt;/p&gt;

&lt;p&gt;But if you are a developer, consider if you need it?&lt;br&gt;
Perhaps you can make your life easier, but going low-tech as well.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and let's connect!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>devops</category>
      <category>cms</category>
    </item>
    <item>
      <title>How to Build and Deploy a Backend App with Express, Postgres, Github, and Heroku</title>
      <dc:creator>Smilepk</dc:creator>
      <pubDate>Sat, 05 Mar 2022 20:55:37 +0000</pubDate>
      <link>https://forem.com/smilepk/how-to-build-and-deploy-a-backend-app-with-express-postgres-github-and-heroku-3jaa</link>
      <guid>https://forem.com/smilepk/how-to-build-and-deploy-a-backend-app-with-express-postgres-github-and-heroku-3jaa</guid>
      <description>&lt;p&gt;In this article , we will be find how to build and deploy an image management application backend.&lt;/p&gt;

&lt;p&gt;It will be able to store a record of an image in the database, get the image's record back from the database, update the record, and even delete the record completely as the case may be.&lt;/p&gt;

&lt;p&gt;To achieve all of this, we will be using Express (a Node.js framework), Postgres (a database), Cloudinary (a cloud based image storage), GitHub (for version control/storage) and Heroku (a hosting platform).&lt;/p&gt;

&lt;p&gt;These tools are all free. So you don’t have to bother about how to go about paying for them. Thanks to these great innovators.&lt;/p&gt;

&lt;p&gt;Prerequisites&lt;br&gt;
If you are new to most of these technologies, I would advise you go through my other tutorial on how to create a server and upload images to Cloudinary.&lt;/p&gt;

&lt;p&gt;If you are totally to Postgres, then check out this tutorial.&lt;/p&gt;

&lt;p&gt;Whenever you are ready, let’s get to work!&lt;/p&gt;

&lt;p&gt;How to Store and Retrieve an Image Record&lt;br&gt;
Create Database and Table&lt;br&gt;
So you'll want to start by cloning this project if you don't already have it.&lt;/p&gt;

&lt;p&gt;In your pgAdmin:&lt;/p&gt;

&lt;p&gt;Create a database and name it tutorial&lt;br&gt;
Create a table and name it tutorial&lt;br&gt;
Create a Login/Group Role and name it tutorial. (Do not forget to give it all privileges.)&lt;br&gt;
Back in your project directory, install the node-postgres (npm i pg) and make-runnnable (npm i make-runnable) packages.&lt;/p&gt;

&lt;p&gt;In your package.json file, replace the contents of the &lt;/p&gt;

&lt;p&gt;"scripts" with "create": "node ./services/dbConnect &lt;br&gt;
createTables". We will use this to execute the dbConnect file we are about to create.&lt;/p&gt;

&lt;p&gt;Create a services/dbConnect file to contain the following code:&lt;br&gt;
&lt;/p&gt;

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

const config = {
  user: "tutorial",
  database: "tutorial",
  password: "tutorial",
  port: 5432,
  max: 10, // max number of clients in the pool
  idleTimeoutMillis: 30000,
};

const pool = new pg.Pool(config);

pool.on("connect", () =&amp;gt; {
  console.log("connected to the Database");
});

const createTables = () =&amp;gt; {
  const imageTable = `CREATE TABLE IF NOT EXISTS
    images(
      id SERIAL PRIMARY KEY,
      title VARCHAR(128) NOT NULL,
      cloudinary_id VARCHAR(128) NOT NULL,
      image_url VARCHAR(128) NOT NULL
    )`;
  pool
    .query(imageTable)
    .then((res) =&amp;gt; {
      console.log(res);
      pool.end();
    })
    .catch((err) =&amp;gt; {
      console.log(err);
      pool.end();
    });
};

pool.on("remove", () =&amp;gt; {
  console.log("client removed");
  process.exit(0);
});

//export pool and createTables to be accessible from anywhere within the application
module.exports = {
  createTables,
  pool,
};

require("make-runnable");

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

&lt;/div&gt;



&lt;p&gt;Now we are all set to create the table in our database. If you are ready, let's rock and roll!&lt;/p&gt;

&lt;p&gt;Execute the following code in your terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run create&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the image below is your result, then you are good to go:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4UY-AMo9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rso2mx612lr2maoyd1xx.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4UY-AMo9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rso2mx612lr2maoyd1xx.jpeg" alt="Image description" width="750" height="798"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check your pgAdmin, and you should have your table seated properly in your database like in the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iokuqD3B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lh80zp2i3sdjaxm1pkev.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iokuqD3B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lh80zp2i3sdjaxm1pkev.jpeg" alt="Image description" width="750" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, it's been a long road. It's time to unite Node, Postgres, and Cloudinary.&lt;/p&gt;

&lt;p&gt;How to Create Endpoints to Store and Retrieve Image Records&lt;br&gt;
Endpoint 1: Persist Image&lt;br&gt;
First, require the dbConnect.js file on the top of the app.js file like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const db = require('services/dbConnect.js');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in the app.js file, make a new endpoint (persist-image) with the following code:&lt;/p&gt;

&lt;p&gt;// persist image&lt;br&gt;
app.post("/persist-image", (request, response) =&amp;gt; {&lt;br&gt;
  // collected image from a user&lt;br&gt;
  const data = {&lt;br&gt;
    title: request.body.title,&lt;br&gt;
    image: request.body.image,&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;// upload image here&lt;br&gt;
  cloudinary.uploader.upload(data.image)&lt;br&gt;
  .then().catch((error) =&amp;gt; {&lt;br&gt;
    response.status(500).send({&lt;br&gt;
      message: "failure",&lt;br&gt;
    error,&lt;br&gt;
    });we&lt;br&gt;
  });&lt;br&gt;
})&lt;/p&gt;

&lt;p&gt;Replace the then block with the following code:&lt;/p&gt;

&lt;p&gt;.then((image) =&amp;gt; {&lt;br&gt;
    db.pool.connect((err, client) =&amp;gt; {&lt;br&gt;
      // inset query to run if the upload to cloudinary is successful&lt;br&gt;
      const insertQuery = 'INSERT INTO images (title, cloudinary_id, image_url) &lt;br&gt;
         VALUES($1,$2,$3) RETURNING *';&lt;br&gt;
      const values = [data.title, image.public_id, image.secure_url];&lt;br&gt;
    })&lt;br&gt;
  })&lt;/p&gt;

&lt;p&gt;The image.public_id and image.secure_url are gotten as part of the details returned for an image after the image has been successfully uploaded to Cloudinary.&lt;/p&gt;

&lt;p&gt;We are now keeping a record of the image.public_id and image.secure_url (as you can see in the code above) in order to use it to retrieve, update, or delete the image record when we see fit.&lt;/p&gt;

&lt;p&gt;Alright, let's move forward!&lt;/p&gt;

&lt;p&gt;Still in the then block, add the following code under the query we created:&lt;/p&gt;

&lt;p&gt;// execute query&lt;br&gt;
client.query(insertQuery, values)&lt;br&gt;
      .then((result) =&amp;gt; {&lt;br&gt;
        result = result.rows[0];&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // send success response
    response.status(201).send({
      status: "success",
      data: {
        message: "Image Uploaded Successfully",
        title: result.title,
        cloudinary_id: result.cloudinary_id,
        image_url: result.image_url,
      },
    })
  }).catch((e) =&amp;gt; {
    response.status(500).send({
      message: "failure",
      e,
    });
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;So our persist-image endpoint now looks like this:&lt;/p&gt;

&lt;p&gt;// persist image&lt;br&gt;
app.post("/persist-image", (request, response) =&amp;gt; {&lt;br&gt;
  // collected image from a user&lt;br&gt;
  const data = {&lt;br&gt;
    title: request.body.title,&lt;br&gt;
    image: request.body.image&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;// upload image here&lt;br&gt;
  cloudinary.uploader.upload(data.image)&lt;br&gt;
  .then((image) =&amp;gt; {&lt;br&gt;
    db.pool.connect((err, client) =&amp;gt; {&lt;br&gt;
      // inset query to run if the upload to cloudinary is successful&lt;br&gt;
      const insertQuery = 'INSERT INTO images (title, cloudinary_id, image_url) &lt;br&gt;
         VALUES($1,$2,$3) RETURNING *';&lt;br&gt;
      const values = [data.title, image.public_id, image.secure_url];&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // execute query
  client.query(insertQuery, values)
  .then((result) =&amp;gt; {
    result = result.rows[0];

    // send success response
    response.status(201).send({
      status: "success",
      data: {
        message: "Image Uploaded Successfully",
        title: result.title,
        cloudinary_id: result.cloudinary_id,
        image_url: result.image_url,
      },
    })
  }).catch((e) =&amp;gt; {
    response.status(500).send({
      message: "failure",
      e,
    });
  })
})  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}).catch((error) =&amp;gt; {&lt;br&gt;
    response.status(500).send({&lt;br&gt;
      message: "failure",&lt;br&gt;
      error,&lt;br&gt;
    });&lt;br&gt;
  });&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;Now let's test out all our hard work:&lt;/p&gt;

&lt;p&gt;Open your postman and test out your endpoint like the image below. Mine was successful. Hope yours had no errors too?&lt;/p&gt;

&lt;p&gt;Alright, it's been a long road. It's time to unite Node, Postgres, and Cloudinary.&lt;/p&gt;

&lt;p&gt;How to Create Endpoints to Store and Retrieve Image Records&lt;br&gt;
Endpoint 1: Persist Image&lt;br&gt;
First, require the dbConnect.js file on the top of the app.js file like so:&lt;/p&gt;

&lt;p&gt;const db = require('services/dbConnect.js');&lt;br&gt;
Then in the app.js file, make a new endpoint (persist-image) with the following code:&lt;/p&gt;

&lt;p&gt;// persist image&lt;br&gt;
app.post("/persist-image", (request, response) =&amp;gt; {&lt;br&gt;
  // collected image from a user&lt;br&gt;
  const data = {&lt;br&gt;
    title: request.body.title,&lt;br&gt;
    image: request.body.image,&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;// upload image here&lt;br&gt;
  cloudinary.uploader.upload(data.image)&lt;br&gt;
  .then().catch((error) =&amp;gt; {&lt;br&gt;
    response.status(500).send({&lt;br&gt;
      message: "failure",&lt;br&gt;
      error,&lt;br&gt;
    });&lt;br&gt;
  });&lt;br&gt;
})&lt;/p&gt;

&lt;p&gt;Replace the then block with the following code:&lt;/p&gt;

&lt;p&gt;.then((image) =&amp;gt; {&lt;br&gt;
    db.pool.connect((err, client) =&amp;gt; {&lt;br&gt;
      // inset query to run if the upload to cloudinary is successful&lt;br&gt;
      const insertQuery = 'INSERT INTO images (title, cloudinary_id, image_url) &lt;br&gt;
         VALUES($1,$2,$3) RETURNING *';&lt;br&gt;
      const values = [data.title, image.public_id, image.secure_url];&lt;br&gt;
    })&lt;br&gt;
  })&lt;/p&gt;

&lt;p&gt;The image.public_id and image.secure_url are gotten as part of the details returned for an image after the image has been successfully uploaded to Cloudinary.&lt;/p&gt;

&lt;p&gt;We are now keeping a record of the image.public_id and image.secure_url (as you can see in the code above) in order to use it to retrieve, update, or delete the image record when we see fit.&lt;/p&gt;

&lt;p&gt;Alright, let's move forward!&lt;/p&gt;

&lt;p&gt;Still in the then block, add the following code under the query we created:&lt;/p&gt;

&lt;p&gt;// execute query&lt;br&gt;
client.query(insertQuery, values)&lt;br&gt;
      .then((result) =&amp;gt; {&lt;br&gt;
        result = result.rows[0];&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // send success response
    response.status(201).send({
      status: "success",
      data: {
        message: "Image Uploaded Successfully",
        title: result.title,
        cloudinary_id: result.cloudinary_id,
        image_url: result.image_url,
      },
    })
  }).catch((e) =&amp;gt; {
    response.status(500).send({
      message: "failure",
      e,
    });
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;So our persist-image endpoint now looks like this:&lt;/p&gt;

&lt;p&gt;// persist image&lt;br&gt;
app.post("/persist-image", (request, response) =&amp;gt; {&lt;br&gt;
  // collected image from a user&lt;br&gt;
  const data = {&lt;br&gt;
    title: request.body.title,&lt;br&gt;
    image: request.body.image&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;// upload image here&lt;br&gt;
  cloudinary.uploader.upload(data.image)&lt;br&gt;
  .then((image) =&amp;gt; {&lt;br&gt;
    db.pool.connect((err, client) =&amp;gt; {&lt;br&gt;
      // inset query to run if the upload to cloudinary is successful&lt;br&gt;
      const insertQuery = 'INSERT INTO images (title, cloudinary_id, image_url) &lt;br&gt;
         VALUES($1,$2,$3) RETURNING *';&lt;br&gt;
      const values = [data.title, image.public_id, image.secure_url];&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // execute query
  client.query(insertQuery, values)
  .then((result) =&amp;gt; {
    result = result.rows[0];

    // send success response
    response.status(201).send({
      status: "success",
      data: {
        message: "Image Uploaded Successfully",
        title: result.title,
        cloudinary_id: result.cloudinary_id,
        image_url: result.image_url,
      },
    })
  }).catch((e) =&amp;gt; {
    response.status(500).send({
      message: "failure",
      e,
    });
  })
})  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}).catch((error) =&amp;gt; {&lt;br&gt;
    response.status(500).send({&lt;br&gt;
      message: "failure",&lt;br&gt;
      error,&lt;br&gt;
    });&lt;br&gt;
  });&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;Now let's test out all our hard work:&lt;/p&gt;

&lt;p&gt;Open your postman and test out your endpoint like the image below. Mine was successful. Hope yours had no errors too?&lt;/p&gt;

&lt;p&gt;Alright, it's been a long road. It's time to unite Node, Postgres, and Cloudinary.&lt;/p&gt;

&lt;p&gt;How to Create Endpoints to Store and Retrieve Image Records&lt;br&gt;
Endpoint 1: Persist Image&lt;br&gt;
First, require the dbConnect.js file on the top of the app.js file like so:&lt;/p&gt;

&lt;p&gt;const db = require('services/dbConnect.js');&lt;br&gt;
Then in the app.js file, make a new endpoint (persist-image) with the following code:&lt;/p&gt;

&lt;p&gt;// persist image&lt;br&gt;
app.post("/persist-image", (request, response) =&amp;gt; {&lt;br&gt;
  // collected image from a user&lt;br&gt;
  const data = {&lt;br&gt;
    title: request.body.title,&lt;br&gt;
    image: request.body.image,&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;// upload image here&lt;br&gt;
  cloudinary.uploader.upload(data.image)&lt;br&gt;
  .then().catch((error) =&amp;gt; {&lt;br&gt;
    response.status(500).send({&lt;br&gt;
      message: "failure",&lt;br&gt;
      error,&lt;br&gt;
    });&lt;br&gt;
  });&lt;br&gt;
})&lt;/p&gt;

&lt;p&gt;Replace the then block with the following code:&lt;/p&gt;

&lt;p&gt;.then((image) =&amp;gt; {&lt;br&gt;
    db.pool.connect((err, client) =&amp;gt; {&lt;br&gt;
      // inset query to run if the upload to cloudinary is successful&lt;br&gt;
      const insertQuery = 'INSERT INTO images (title, cloudinary_id, image_url) &lt;br&gt;
         VALUES($1,$2,$3) RETURNING *';&lt;br&gt;
      const values = [data.title, image.public_id, image.secure_url];&lt;br&gt;
    })&lt;br&gt;
  })&lt;/p&gt;

&lt;p&gt;The image.public_id and image.secure_url are gotten as part of the details returned for an image after the image has been successfully uploaded to Cloudinary.&lt;/p&gt;

&lt;p&gt;We are now keeping a record of the image.public_id and image.secure_url (as you can see in the code above) in order to use it to retrieve, update, or delete the image record when we see fit.&lt;/p&gt;

&lt;p&gt;Alright, let's move forward!&lt;/p&gt;

&lt;p&gt;Still in the then block, add the following code under the query we created:&lt;/p&gt;

&lt;p&gt;// execute query&lt;br&gt;
client.query(insertQuery, values)&lt;br&gt;
      .then((result) =&amp;gt; {&lt;br&gt;
        result = result.rows[0];&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // send success response
    response.status(201).send({
      status: "success",
      data: {
        message: "Image Uploaded Successfully",
        title: result.title,
        cloudinary_id: result.cloudinary_id,
        image_url: result.image_url,
      },
    })
  }).catch((e) =&amp;gt; {
    response.status(500).send({
      message: "failure",
      e,
    });
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;So our persist-image endpoint now looks like this:&lt;/p&gt;

&lt;p&gt;// persist image&lt;br&gt;
app.post("/persist-image", (request, response) =&amp;gt; {&lt;br&gt;
  // collected image from a user&lt;br&gt;
  const data = {&lt;br&gt;
    title: request.body.title,&lt;br&gt;
    image: request.body.image&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;// upload image here&lt;br&gt;
  cloudinary.uploader.upload(data.image)&lt;br&gt;
  .then((image) =&amp;gt; {&lt;br&gt;
    db.pool.connect((err, client) =&amp;gt; {&lt;br&gt;
      // inset query to run if the upload to cloudinary is successful&lt;br&gt;
      const insertQuery = 'INSERT INTO images (title, cloudinary_id, image_url) &lt;br&gt;
         VALUES($1,$2,$3) RETURNING *';&lt;br&gt;
      const values = [data.title, image.public_id, image.secure_url];&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // execute query
  client.query(insertQuery, values)
  .then((result) =&amp;gt; {
    result = result.rows[0];

    // send success response
    response.status(201).send({
      status: "success",
      data: {
        message: "Image Uploaded Successfully",
        title: result.title,
        cloudinary_id: result.cloudinary_id,
        image_url: result.image_url,
      },
    })
  }).catch((e) =&amp;gt; {
    response.status(500).send({
      message: "failure",
      e,
    });
  })
})  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}).catch((error) =&amp;gt; {&lt;br&gt;
    response.status(500).send({&lt;br&gt;
      message: "failure",&lt;br&gt;
      error,&lt;br&gt;
    });&lt;br&gt;
  });&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;Now let's test out all our hard work:&lt;/p&gt;

&lt;p&gt;Open your postman and test out your endpoint like the image below. Mine was successful. Hope yours had no errors too?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mtmC7_m8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z09l948p4s0shtsa7j1c.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mtmC7_m8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z09l948p4s0shtsa7j1c.jpeg" alt="Image description" width="750" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open your Cloudinary console/dashboard and check your media Library. Your new image should be sitting there comfortably like mine below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v6PUf833--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6wvlhp0cllu40oq6n2em.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v6PUf833--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6wvlhp0cllu40oq6n2em.jpeg" alt="Image description" width="880" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now to the main reason why we are here: check the images table in your pgAdmin. Mine is what you see below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5OsDAj_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6rq7pnxwqevujqpoe6d.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5OsDAj_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6rq7pnxwqevujqpoe6d.jpeg" alt="Image description" width="880" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oohlala! We made it this far. Please take a break if you need one. I will be here waiting when you return. :)&lt;/p&gt;

&lt;p&gt;If you are ready, then let's retrieve the image we persisted a moment ago.&lt;/p&gt;

&lt;p&gt;Endpoint 2: Retrieve Image&lt;br&gt;
Start with this code:&lt;/p&gt;

&lt;p&gt;app.get("/retrieve-image/:cloudinary_id", (request, response) =&amp;gt; {&lt;/p&gt;

&lt;p&gt;});&lt;/p&gt;

&lt;p&gt;Next, we will need to collect a unique ID from the user to retrieve a particular image. So add const { id } = request.params; to the code above like so:&lt;/p&gt;

&lt;p&gt;app.get("/retrieve-image/:cloudinary_id", (request, response) =&amp;gt; {&lt;br&gt;
  // data from user&lt;br&gt;
  const { cloudinary_id } = request.params;&lt;/p&gt;

&lt;p&gt;});&lt;/p&gt;

&lt;p&gt;Add the following code just below the code above:&lt;/p&gt;

&lt;p&gt;db.pool.connect((err, client) =&amp;gt; {&lt;br&gt;
      // query to find image&lt;br&gt;
    const query = "SELECT * FROM images WHERE cloudinary_id = $1";&lt;br&gt;
    const value = [cloudinary_id];&lt;br&gt;
    });&lt;/p&gt;

&lt;p&gt;Under the query, execute the query with the following code:&lt;/p&gt;

&lt;p&gt;// execute query&lt;br&gt;
    client&lt;br&gt;
      .query(query, value)&lt;br&gt;
      .then((output) =&amp;gt; {&lt;br&gt;
        response.status(200).send({&lt;br&gt;
          status: "success",&lt;br&gt;
          data: {&lt;br&gt;
            id: output.rows[0].cloudinary_id,&lt;br&gt;
            title: output.rows[0].title,&lt;br&gt;
            url: output.rows[0].image_url,&lt;br&gt;
          },&lt;br&gt;
        });&lt;br&gt;
      })&lt;br&gt;
      .catch((error) =&amp;gt; {&lt;br&gt;
        response.status(401).send({&lt;br&gt;
          status: "failure",&lt;br&gt;
          data: {&lt;br&gt;
            message: "could not retrieve record!",&lt;br&gt;
            error,&lt;br&gt;
          },&lt;br&gt;
        });&lt;br&gt;
      });&lt;/p&gt;

&lt;p&gt;Now our retrieve-image API looks like this:&lt;/p&gt;

&lt;p&gt;app.get("/retrieve-image/:cloudinary_id", (request, response) =&amp;gt; {&lt;br&gt;
  // data from user&lt;br&gt;
  const { cloudinary_id } = request.params;&lt;/p&gt;

&lt;p&gt;db.pool.connect((err, client) =&amp;gt; {&lt;br&gt;
    // query to find image&lt;br&gt;
    const query = "SELECT * FROM images WHERE cloudinary_id = $1";&lt;br&gt;
    const value = [cloudinary_id];&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// execute query
client
  .query(query, value)
  .then((output) =&amp;gt; {
    response.status(200).send({
      status: "success",
      data: {
        id: output.rows[0].cloudinary_id,
        title: output.rows[0].title,
        url: output.rows[0].image_url,
      },
    });
  })
  .catch((error) =&amp;gt; {
    response.status(401).send({
      status: "failure",
      data: {
        message: "could not retrieve record!",
        error,
      },
    });
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;});&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;Let's see how well we did:&lt;/p&gt;

&lt;p&gt;In your postman, copy the cloudinary_id and add it to the URL like in the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ONL1vSP0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yhmgyvmxaw0tw0ccr7or.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ONL1vSP0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yhmgyvmxaw0tw0ccr7or.jpeg" alt="Image description" width="880" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;YEEESSS! We can also retrieve our image.&lt;/p&gt;

&lt;p&gt;If you are here, then you deserve a round of applause and a standing ovation for your industriousness.&lt;/p&gt;

&lt;p&gt;Congratulations! You just reached a great milestone.&lt;/p&gt;

&lt;p&gt;The code for storing and retrieving image records is here.&lt;/p&gt;

&lt;p&gt;How to Update and Delete an Image Record&lt;br&gt;
We will now see how to delete and update an image record as the case maybe. Let's begin with the delete endpoint.&lt;/p&gt;

&lt;p&gt;Delete Endpoint&lt;br&gt;
In the app.js file, start with the following code:&lt;/p&gt;

&lt;p&gt;// delete image&lt;br&gt;
app.delete("delete-image/:cloudinary_id", (request, response) =&amp;gt; {&lt;/p&gt;

&lt;p&gt;});&lt;/p&gt;

&lt;p&gt;Next, we want to get the unique ID of the image we want to delete from the URL, that is cloudinary_id. So inside the code above add:&lt;/p&gt;

&lt;p&gt;const { cloudinary_id } = request.params;&lt;/p&gt;

&lt;p&gt;We now start the deleting process.&lt;/p&gt;

&lt;p&gt;First, we delete from Cloudinary. Add the following code to delete the image from Cloudinary:&lt;/p&gt;

&lt;p&gt;cloudinary.uploader&lt;br&gt;
    .destroy(cloudinary_id)&lt;br&gt;
    .then((result) =&amp;gt; {&lt;br&gt;
      response.status(200).send({&lt;br&gt;
        message: "success",&lt;br&gt;
        result,&lt;br&gt;
      });&lt;br&gt;
    })&lt;br&gt;
    .catch((error) =&amp;gt; {&lt;br&gt;
      response.status(500).send({&lt;br&gt;
        message: "Failure",&lt;br&gt;
        error,&lt;br&gt;
      });&lt;br&gt;
    });&lt;/p&gt;

&lt;p&gt;At this point, our API can delete the image from Cloudinary only (you can check it out in postman). But we also want to get rid of the record we have in our Postgres database.&lt;/p&gt;

&lt;p&gt;Second, we delete from our Postgres database. To do so, replace the code in the then block with the following query:&lt;/p&gt;

&lt;p&gt;db.pool.connect((err, client) =&amp;gt; {&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // delete query
  const deleteQuery = "DELETE FROM images WHERE cloudinary_id = $1";
  const deleteValue = [cloudinary_id];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;})&lt;br&gt;
Execute the query with the following code underneath it:&lt;/p&gt;

&lt;p&gt;// execute delete query&lt;br&gt;
      client.query(deleteQuery, deleteValue)&lt;br&gt;
      .then((deleteResult) =&amp;gt; {&lt;br&gt;
        response.status(200).send({&lt;br&gt;
          message: "Image Deleted Successfully!",&lt;br&gt;
          deleteResult&lt;br&gt;
        });&lt;br&gt;
      }).catch((e) =&amp;gt; {&lt;br&gt;
        response.status(500).send({&lt;br&gt;
          message: "Image Couldn't be Deleted!",&lt;br&gt;
          e&lt;br&gt;
        });&lt;br&gt;
      });&lt;/p&gt;

&lt;p&gt;So our Endpoint should look like this:&lt;/p&gt;

&lt;p&gt;// delete image&lt;br&gt;
app.delete("/delete-image/:cloudinary_id", (request, response) =&amp;gt; {&lt;br&gt;
  // unique ID&lt;br&gt;
  const { cloudinary_id } = request.params;&lt;/p&gt;

&lt;p&gt;// delete image from cloudinary first&lt;br&gt;
  cloudinary.uploader&lt;br&gt;
    .destroy(cloudinary_id)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// delete image record from postgres also
.then(() =&amp;gt; {
  db.pool.connect((err, client) =&amp;gt; {

  // delete query
  const deleteQuery = "DELETE FROM images WHERE cloudinary_id = $1";
  const deleteValue = [cloudinary_id];

  // execute delete query
  client
    .query(deleteQuery, deleteValue)
    .then((deleteResult) =&amp;gt; {
      response.status(200).send({
        message: "Image Deleted Successfully!",
        deleteResult,
      });
    })
    .catch((e) =&amp;gt; {
      response.status(500).send({
        message: "Image Couldn't be Deleted!",
        e,
      });
    });
  })
})
.catch((error) =&amp;gt; {
  response.status(500).send({
    message: "Failure",
    error,
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;});&lt;/p&gt;

&lt;p&gt;The time has arrived for us to put our Endpoint to the test.&lt;/p&gt;

&lt;p&gt;The following is my Cloudinary media library with two images I uploaded already. Take note of their unique ID (public_id).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4h6bjxur--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/brqzk1qjcbm093oxxhqr.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4h6bjxur--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/brqzk1qjcbm093oxxhqr.jpeg" alt="Image description" width="880" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don't already have that, please use the persist-image endpoint to upload some images.&lt;/p&gt;

&lt;p&gt;Now let's proceed to postman:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NIjoLAGh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1rrz2eexluk2jreg4g9g.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NIjoLAGh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1rrz2eexluk2jreg4g9g.jpeg" alt="Image description" width="880" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice, the unique ID as it matches one of the image in my Cloudinary media library.&lt;/p&gt;

&lt;p&gt;From the output, we executed the DELETE command and that deleted one ROW from our image TABLE in our database.&lt;/p&gt;

&lt;p&gt;Now this is my media library with one of the images remaining:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--38NsCwxL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3tizwwbrsdxtqccd4ky.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--38NsCwxL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3tizwwbrsdxtqccd4ky.jpeg" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Walahhhh... We are now able to get rid of an image.&lt;/p&gt;

&lt;p&gt;Do take a break if you need one. ✌🏾&lt;/p&gt;

&lt;p&gt;If you are ready, I am ready to update images.&lt;/p&gt;

&lt;p&gt;Update Image API&lt;br&gt;
Below the delete-image API, let's start creating the update-image API with the following code:&lt;/p&gt;

&lt;p&gt;// update image&lt;br&gt;
app.put("/update-image/:cloudinary_id", (request, response) =&amp;gt; {&lt;/p&gt;

&lt;p&gt;});&lt;/p&gt;

&lt;p&gt;All codes will live in there.&lt;/p&gt;

&lt;p&gt;Collect the unique Cloudinary ID and new image details from the user with the following code:&lt;/p&gt;

&lt;p&gt;// unique ID&lt;br&gt;
  const { cloudinary_id } = request.params;&lt;/p&gt;

&lt;p&gt;// collected image from a user&lt;br&gt;
  const data = {&lt;br&gt;
    title: request.body.title,&lt;br&gt;
    image: request.body.image,&lt;br&gt;
  };&lt;/p&gt;

&lt;p&gt;Delete the image from Cloudinary with the following code:&lt;/p&gt;

&lt;p&gt;// delete image from cloudinary first&lt;br&gt;
  cloudinary.uploader&lt;br&gt;
    .destroy(cloudinary_id)&lt;br&gt;
      // upload image here&lt;br&gt;
    .then()&lt;br&gt;
    .catch((error) =&amp;gt; {&lt;br&gt;
      response.status(500).send({&lt;br&gt;
        message: "failed",&lt;br&gt;
        error,&lt;br&gt;
      });&lt;br&gt;
    });&lt;/p&gt;

&lt;p&gt;Next, upload another image to Cloudinary. To do that, enter the following code into the then block:&lt;/p&gt;

&lt;p&gt;() =&amp;gt; {&lt;br&gt;
      cloudinary.uploader&lt;br&gt;
        .upload(data.image)&lt;br&gt;
        .then()&lt;br&gt;
        .catch((err) =&amp;gt; {&lt;br&gt;
          response.status(500).send({&lt;br&gt;
            message: "failed",&lt;br&gt;
            err,&lt;br&gt;
          });&lt;br&gt;
        });&lt;br&gt;
    }&lt;/p&gt;

&lt;p&gt;Now let's replace our initial record with the new image details. Replace the content of the then block with the following:&lt;/p&gt;

&lt;p&gt;(result) =&amp;gt; {&lt;br&gt;
          db.pool.connect((err, client) =&amp;gt; {&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        // update query
        const updateQuery =
          "UPDATE images SET title = $1, cloudinary_id = $2, image_url = $3 WHERE cloudinary_id = $4";
        const value = [
          data.title,
          result.public_id,
          result.secure_url,
          cloudinary_id,
        ];
      });
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;We execute the query using the following code just beneath the query declaration:&lt;/p&gt;

&lt;p&gt;// execute query&lt;br&gt;
            client&lt;br&gt;
              .query(updateQuery, value)&lt;br&gt;
              .then(() =&amp;gt; {&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            // send success response
            response.status(201).send({
              status: "success",
              data: {
                message: "Image Updated Successfully"
              },
            });
          })
          .catch((e) =&amp;gt; {
            response.status(500).send({
              message: "Update Failed",
              e,
            });
          });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;At this point, this is what I have:&lt;/p&gt;

&lt;p&gt;// update image&lt;br&gt;
app.put("/update-image/:cloudinary_id", (request, response) =&amp;gt; {&lt;br&gt;
  // unique ID&lt;br&gt;
  const { cloudinary_id } = request.params;&lt;/p&gt;

&lt;p&gt;// collected image from a user&lt;br&gt;
  const data = {&lt;br&gt;
    title: request.body.title,&lt;br&gt;
    image: request.body.image,&lt;br&gt;
  };&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// delete image from cloudinary first
cloudinary.uploader
  .destroy(cloudinary_id)

  // upload image here
  .then(() =&amp;gt; {
    cloudinary.uploader
      .upload(data.image)

      // update the database here
      .then((result) =&amp;gt; {
        db.pool.connect((err, client) =&amp;gt; {
        // update query
        const updateQuery =
          "UPDATE images SET title = $1, cloudinary_id = $2, image_url = $3 WHERE cloudinary_id = $4";
        const value = [
          data.title,
          result.public_id,
          result.secure_url,
          cloudinary_id,
        ];

        // execute query
        client
          .query(updateQuery, value)
          .then(() =&amp;gt; {

            // send success response
            response.status(201).send({
              status: "success",
              data: {
                message: "Image Updated Successfully"
              },
            });
          })
          .catch((e) =&amp;gt; {
            response.status(500).send({
              message: "Update Failed",
              e,
            });
          });
        });
      })
      .catch((err) =&amp;gt; {
        response.status(500).send({
          message: "failed",
          err,
        });
      });
  })
  .catch((error) =&amp;gt; {
    response.status(500).send({
      message: "failed",
      error,
    });
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;});&lt;/p&gt;

&lt;p&gt;It's testing time!&lt;/p&gt;

&lt;p&gt;This is my postman in the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wlMTtvlE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mtj78gwoc6xdp18kiu14.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wlMTtvlE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mtj78gwoc6xdp18kiu14.jpeg" alt="&amp;lt;br&amp;gt;
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejue2pbgw0rz3jmtbwne.jpeg)Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take note of the unique cloudinary ID which matches the image left in my Cloudinary media library.&lt;/p&gt;

&lt;p&gt;Now take a look at my Cloudinary media library in the image that follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K_m0l76e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fb7782mcsstt58le7zly.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K_m0l76e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fb7782mcsstt58le7zly.jpeg" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take note of the new image replacing the initial one in my media library above.&lt;/p&gt;

&lt;p&gt;Also, see that the unique Cloudinary ID matches that in my database with the new title. See image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oLFPGkzi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qgbco3f6frcpq3ppw1yf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oLFPGkzi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qgbco3f6frcpq3ppw1yf.jpeg" alt="Image description" width="880" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yayeh! You did awesomely great! 💪&lt;/p&gt;

&lt;p&gt;We just completed an image management application with Node.js, Cloudinary and Postgres.&lt;/p&gt;

&lt;p&gt;Code Optimisation With Express Routing&lt;br&gt;
Express Routing enables us to make our Node.js code more optimized or give it a more modular structure by separating the business logic from the controllers. We want to use that to clean up our code so far.&lt;/p&gt;

&lt;p&gt;We'll begin by creating a new folder with the name routes in the root directory:&lt;/p&gt;

&lt;p&gt;mk dir routes&lt;/p&gt;

&lt;p&gt;In the routes folder, create a file with the name: routes.js.&lt;/p&gt;

&lt;p&gt;For Windows:&lt;/p&gt;

&lt;p&gt;echo . &amp;gt; routes.js&lt;/p&gt;

&lt;p&gt;For Mac:&lt;/p&gt;

&lt;p&gt;touch routes.js&lt;/p&gt;

&lt;p&gt;Empty the routes.js file if anything is there and enter the following code:&lt;/p&gt;

&lt;p&gt;const express = require('express');&lt;/p&gt;

&lt;p&gt;const router = express.Router();&lt;/p&gt;

&lt;p&gt;module.exports = router;&lt;/p&gt;

&lt;p&gt;Add the following code above the last line:&lt;/p&gt;

&lt;p&gt;const cloudinary = require("cloudinary").v2;&lt;br&gt;
require("dotenv").config();&lt;br&gt;
const db = require("../services/dbConnect.js");&lt;/p&gt;

&lt;p&gt;// cloudinary configuration&lt;br&gt;
cloudinary.config({&lt;br&gt;
  cloud_name: process.env.CLOUD_NAME,&lt;br&gt;
  api_key: process.env.API_KEY,&lt;br&gt;
  api_secret: process.env.API_SECRET,&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;Back in the App.js file, delete the following code:&lt;/p&gt;

&lt;p&gt;const cloudinary = require("cloudinary").v2;&lt;br&gt;
require("dotenv").config();&lt;br&gt;
const db = require("./services/dbConnect.js");&lt;/p&gt;

&lt;p&gt;// cloudinary configuration&lt;br&gt;
cloudinary.config({&lt;br&gt;
  cloud_name: process.env.CLOUD_NAME,&lt;br&gt;
  api_key: process.env.API_KEY,&lt;br&gt;
  api_secret: process.env.API_SECRET,&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;Move all the APIs to routes.js.&lt;/p&gt;

&lt;p&gt;Change all occurence of app to router carefully.&lt;/p&gt;

&lt;p&gt;My routes.js file now looks like this.&lt;/p&gt;

&lt;p&gt;Back in the app.js file, import the routes.js file like so:&lt;/p&gt;

&lt;p&gt;// import the routes file&lt;br&gt;
const routes = require("./routes/routes")&lt;/p&gt;

&lt;p&gt;Now register the routes like so:&lt;/p&gt;

&lt;p&gt;// register the routes &lt;br&gt;
app.use('/', routes);&lt;/p&gt;

&lt;p&gt;This is my app.js file at the moment:&lt;/p&gt;

&lt;p&gt;const express = require("express");&lt;br&gt;
const app = express();&lt;/p&gt;

&lt;p&gt;// import the routes file&lt;br&gt;
const routes = require("./routes/routes")&lt;/p&gt;

&lt;p&gt;// body parser configuration&lt;br&gt;
const bodyParser = require("body-parser");&lt;br&gt;
app.use(bodyParser.json());&lt;br&gt;
app.use(bodyParser.urlencoded({ extended: true }));&lt;/p&gt;

&lt;p&gt;// register the routes &lt;br&gt;
app.use('/', routes);&lt;/p&gt;

&lt;p&gt;module.exports = app;&lt;/p&gt;

&lt;p&gt;It's time to test and see if our routes are still working like before.&lt;/p&gt;

&lt;p&gt;Make sure yours are working like mine below:&lt;/p&gt;

&lt;p&gt;persist-image&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jNQK8rYE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9sar85ckrhen1grgkt0z.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jNQK8rYE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9sar85ckrhen1grgkt0z.jpeg" alt="Image description" width="750" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uTNquONE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7f9vdsg1czdah1adx8b3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uTNquONE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7f9vdsg1czdah1adx8b3.jpeg" alt="Image description" width="750" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;update-image&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I_1NIgeA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pz7jld17m3as9zcbuya5.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I_1NIgeA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pz7jld17m3as9zcbuya5.jpeg" alt="Image description" width="750" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;delete-image&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hJxzgEVr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2sc0n05gdx8hc2txlrc0.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hJxzgEVr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2sc0n05gdx8hc2txlrc0.jpeg" alt="Image description" width="750" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wow! We have been able to separate our routes from our app.js file.&lt;/p&gt;

&lt;p&gt;The code for this is here.&lt;/p&gt;

&lt;p&gt;Even though our routes.js file is still lengthy, we have a good basis to separate our business logic from our controllers. The time has arrived to do just that.&lt;/p&gt;

&lt;p&gt;How to Move Each Endpoint to a Different File&lt;br&gt;
Begin by creating a new folder in the routes folder and name it controllers.&lt;/p&gt;

&lt;p&gt;In the controllers folder, create 5 files and name them after the 5 endpoints.&lt;/p&gt;

&lt;p&gt;Our folder and files should be structured as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9IO7KvFV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iafuneos25146b9sqx4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9IO7KvFV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iafuneos25146b9sqx4d.png" alt="Image description" width="750" height="1334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back in the routes.js file, let's work on the image-upload API. Cut the following code:&lt;/p&gt;

&lt;p&gt;(request, response) =&amp;gt; {&lt;br&gt;
  // collected image from a user&lt;br&gt;
  const data = {&lt;br&gt;
    image: request.body.image,&lt;br&gt;
  };&lt;/p&gt;

&lt;p&gt;// upload image here&lt;br&gt;
  cloudinary.uploader&lt;br&gt;
    .upload(data.image)&lt;br&gt;
    .then((result) =&amp;gt; {&lt;br&gt;
      response.status(200).send({&lt;br&gt;
        message: "success",&lt;br&gt;
        result,&lt;br&gt;
      });&lt;br&gt;
    })&lt;br&gt;
    .catch((error) =&amp;gt; {&lt;br&gt;
      response.status(500).send({&lt;br&gt;
        message: "failure",&lt;br&gt;
        error,&lt;br&gt;
      });&lt;br&gt;
    });&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;In the imageUpload file, equate the code you already cut from the image-upload endpoint to exports.imageUpload like so:&lt;/p&gt;

&lt;p&gt;exports.imageUpload = (request, response) =&amp;gt; {&lt;br&gt;
    // collected image from a user&lt;br&gt;
    const data = {&lt;br&gt;
      image: request.body.image,&lt;br&gt;
    };&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// upload image here
cloudinary.uploader
  .upload(data.image)
  .then((result) =&amp;gt; {
    response.status(200).send({
      message: "success",
      result,
    });
  })
  .catch((error) =&amp;gt; {
    response.status(500).send({
      message: "failure",
      error,
    });
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;Now let's import what is necessary for this code to work. So this is my imageUpload file right now:&lt;/p&gt;

&lt;p&gt;const cloudinary = require("cloudinary").v2;&lt;br&gt;
require("dotenv").config();&lt;/p&gt;

&lt;p&gt;// cloudinary configuration&lt;br&gt;
cloudinary.config({&lt;br&gt;
  cloud_name: process.env.CLOUD_NAME,&lt;br&gt;
  api_key: process.env.API_KEY,&lt;br&gt;
  api_secret: process.env.API_SECRET,&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;exports.imageUpload = (request, response) =&amp;gt; {&lt;br&gt;
    // collected image from a user&lt;br&gt;
    const data = {&lt;br&gt;
      image: request.body.image,&lt;br&gt;
    };&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// upload image here
cloudinary.uploader
  .upload(data.image)
  .then((result) =&amp;gt; {
    response.status(200).send({
      message: "success",
      result,
    });
  })
  .catch((error) =&amp;gt; {
    response.status(500).send({
      message: "failure",
      error,
    });
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;Let's import and register the imageUpload API in the routes.js file like so:&lt;/p&gt;

&lt;p&gt;const imageUpload = require("./controllers/imageUpload");&lt;/p&gt;

&lt;p&gt;// image upload API&lt;br&gt;
router.post("image-upload", imageUpload.imageUpload);&lt;/p&gt;

&lt;p&gt;Now we have this line of code pointing to the imageUpload API in the imageUpload.js file from the routes.js file.&lt;/p&gt;

&lt;p&gt;How awesome! Our code is more readable.&lt;/p&gt;

&lt;p&gt;Make sure to test the API to be sure it's working properly. Mine works perfectly. See image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U_V_WRsB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u7qeh228hilxw3zarzik.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U_V_WRsB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u7qeh228hilxw3zarzik.jpeg" alt="Image description" width="750" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, it's your turn!&lt;/p&gt;

&lt;p&gt;Apply what you have learnt to the other APIs. Let's see what you have got.&lt;/p&gt;

&lt;p&gt;I will be waiting on the other side...&lt;/p&gt;

&lt;p&gt;If you are here, then I believe you have done yours and they're working perfectly – or at least, you already gave it your best shot. Kudos!&lt;/p&gt;

&lt;p&gt;Checkout mine here.&lt;/p&gt;

&lt;p&gt;Congratulations. You are awesome :)&lt;/p&gt;

&lt;p&gt;The code optimisation code is here.&lt;/p&gt;

&lt;p&gt;Alright, on to the next step.&lt;/p&gt;

&lt;p&gt;How to Deploy to GitHub And Heroku&lt;br&gt;
Now that we've completed our application, let's deploy it on Heroku so that we can access it even without being on our laptop where the code was written.&lt;/p&gt;

&lt;p&gt;I will be walking you through uploading our application to GitHub and deploying it to Heroku.&lt;/p&gt;

&lt;p&gt;Without further ado, let's get our hands dirty.&lt;/p&gt;

&lt;p&gt;How to Upload the Code to GitHub&lt;br&gt;
Uploading or pushing to GitHub is as easy as eating your favorite meal. Check out this resource to learn how to push your project from you local machine to GitHub.&lt;/p&gt;

&lt;p&gt;How to Deploy to Heroku&lt;br&gt;
Let's begin by creating an account on Heroku.&lt;/p&gt;

&lt;p&gt;If you have created an account, you may have been prompted to create an app (that is a folder where your app will be housed). You can do that, but I will do mine using my terminal since the terminal comes with a few added functionalities that we will need later.&lt;/p&gt;

&lt;p&gt;Open your project in a terminal if you have not done so already. I will be using the VS Code integrated terminal.&lt;/p&gt;

&lt;p&gt;Install Heroku CLI:&lt;/p&gt;

&lt;p&gt;npm install heroku&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E7V6squ1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9agrgtj5bfl61pkk6bqt.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E7V6squ1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9agrgtj5bfl61pkk6bqt.jpeg" alt="Image description" width="750" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Login to Heroku CLI. This will open a browser window, which you can use to log in.&lt;/p&gt;

&lt;p&gt;heroku login&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W9ns5uyy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a72vbe77eu5ftnqd3f61.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W9ns5uyy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a72vbe77eu5ftnqd3f61.jpeg" alt="Image description" width="750" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create an app. It can have any name. I am using node-postgres-cloudinary.&lt;/p&gt;

&lt;p&gt;heroku create node-postgres-cloudinary&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u8JhGJt5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zmlmda86hweuznizgi2k.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u8JhGJt5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zmlmda86hweuznizgi2k.jpeg" alt="Image description" width="750" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to your Heroku dashboard and you will find the newly created app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HAvtOGoa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ffrjz7dg93s1yveyvhxf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HAvtOGoa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ffrjz7dg93s1yveyvhxf.jpeg" alt="Image description" width="750" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Waalaah!&lt;/p&gt;

&lt;p&gt;That is how mine looks in the image above. I have some apps there already but you can see the one I just created.&lt;/p&gt;

&lt;p&gt;Let's now add the PostgreSQL database to the app.&lt;/p&gt;

&lt;p&gt;How to Add Heroku Postgres&lt;br&gt;
Click on the app you just created. It will take you to the app's dashboard.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E1K-GinY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pme7iim3pi444zu3lmq9.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E1K-GinY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pme7iim3pi444zu3lmq9.jpeg" alt="Image description" width="880" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the Resources tab/menu&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8TqSbLO9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/im3xuank190tdxs3g0v3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8TqSbLO9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/im3xuank190tdxs3g0v3.jpeg" alt="Image description" width="745" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the Add-ons Section, search and select Heroku Postgres.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DUEc_tr1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfmtgogyrl412hhknvnn.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DUEc_tr1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfmtgogyrl412hhknvnn.jpeg" alt="Image description" width="750" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure you select the Hobby Dev - Free plan in the pop-up window that follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O_c1XBSS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvchd3kvs4qlsz1i4w6a.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O_c1XBSS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvchd3kvs4qlsz1i4w6a.jpeg" alt="Image description" width="750" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the provision button to add it to the app like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PudScqEV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5bzpdm5s5vx6tq9w6xew.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PudScqEV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5bzpdm5s5vx6tq9w6xew.jpeg" alt="Image description" width="750" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the Heroku Postgres to take you to the Heroku Postgres dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qfniU5WE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dzjpb8ed2xtom01d4f9z.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qfniU5WE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dzjpb8ed2xtom01d4f9z.jpeg" alt="Image description" width="750" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the settings tab:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lzZv0gnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f36ytp61w3wfisnf105c.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lzZv0gnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f36ytp61w3wfisnf105c.jpeg" alt="Image description" width="750" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on View Credentials:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R1JCQqER--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hte8ydcoxeom9uvtng7t.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R1JCQqER--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hte8ydcoxeom9uvtng7t.jpeg" alt="Image description" width="750" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the Credentials, we are interested in the Heroku CLI. We will be using it in a bit&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vbSZT0e_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4dw6fymu6gnjhdy3wjvz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vbSZT0e_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4dw6fymu6gnjhdy3wjvz.jpeg" alt="Image description" width="750" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back to the terminal.&lt;/p&gt;

&lt;p&gt;Let's confirm if the Heroku Postgres was added successfully. Enter the following in the terminal:&lt;/p&gt;

&lt;p&gt;heroku addons&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--al5Ua19t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m48eqnmcg3ee3hdl9hz7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--al5Ua19t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m48eqnmcg3ee3hdl9hz7.jpeg" alt="Image description" width="750" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yeeeeaaaah! It was added successfully.&lt;/p&gt;

&lt;p&gt;Before we proceed, make sure that your PostgreSQL path is set correctly if you are on Windows. Follow this link to learn how to set a path. The path should be like this: C:\Program Files\PostgreSQL&amp;lt;VERSION&amp;gt;\bin.&lt;/p&gt;

&lt;p&gt;The version will depend on the one installed on you machine. Mine is: C:\Program Files\PostgreSQL\12\bin since I am using the version 12.&lt;/p&gt;

&lt;p&gt;The following image might be helpful:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R4x2sgzF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t2iamzp9voozp685yy04.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R4x2sgzF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t2iamzp9voozp685yy04.jpeg" alt="Image description" width="880" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may have to navigate to the folder where PostgreSQL is installed on your machine to find out your own path.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aYYDdppv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ab2m6nhzdjrat6ge8s0e.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aYYDdppv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ab2m6nhzdjrat6ge8s0e.jpeg" alt="Image description" width="880" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Login into the Heroku Postgres using the Heroku CLI from our Heroku Postgres credentials. This is mine – yours will be different:&lt;/p&gt;

&lt;p&gt;heroku pg:psql postgresql-slippery-19135 --app node-postgres-cloudinary&lt;br&gt;
If you got an error, it is most likely because your path is not set properly.&lt;/p&gt;

&lt;p&gt;How to Prepare our Database Connection to Match Heroku's&lt;br&gt;
At the moment, my database looks like this:&lt;/p&gt;

&lt;p&gt;const pg = require("pg");&lt;/p&gt;

&lt;p&gt;const config = {&lt;br&gt;
  user: "tutorial",&lt;br&gt;
  database: "tutorial",&lt;br&gt;
  password: "tutorial",&lt;br&gt;
  port: 5432,&lt;br&gt;
  max: 10, // max number of clients in the pool&lt;br&gt;
  idleTimeoutMillis: 30000,&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;const pool = new pg.Pool(config);&lt;/p&gt;

&lt;p&gt;pool.on("connect", () =&amp;gt; {&lt;br&gt;
  console.log("connected to the Database");&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;If you try connecting Heroku to this, you are going to get an error. This is because Heroku has a connection string setup already. So we have to setup our connection such that Heroku can easily connect.&lt;/p&gt;

&lt;p&gt;I am going to refactor my database connection file (dbConnect.js) and .env file to make this happen.&lt;/p&gt;

&lt;p&gt;dbConnect.js&lt;/p&gt;

&lt;p&gt;const pg = require('pg');&lt;br&gt;
require('dotenv').config();&lt;/p&gt;

&lt;p&gt;// set production variable. This will be called when deployed to a live host&lt;br&gt;
const isProduction = process.env.NODE_ENV === 'production';&lt;/p&gt;

&lt;p&gt;// configuration details&lt;br&gt;
const connectionString = &lt;code&gt;postgresql://${process.env.DB_USER}:${process.env.DB_PASSWORD}@${process.env.DB_HOST}:${process.env.DB_PORT}/${process.env.DB_DATABASE}&lt;/code&gt;;&lt;/p&gt;

&lt;p&gt;// if project has been deployed, connect with the host's DATABASE_URL&lt;br&gt;
// else connect with the local DATABASE_URL&lt;br&gt;
const pool = new pg.Pool({&lt;br&gt;
  connectionString: isProduction ? process.env.DATABASE_URL : connectionString,&lt;br&gt;
  ssl: isProduction,&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// display message on success if successful&lt;br&gt;
pool.on('connect', () =&amp;gt; {&lt;br&gt;
  console.log('Teamwork Database connected successfully!');&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;.env file&lt;/p&gt;

&lt;p&gt;DB_USER="tutorial"&lt;br&gt;
DB_PASSWORD="tutorial"&lt;br&gt;
DB_HOST="localhost"&lt;br&gt;
DB_PORT="5432"&lt;br&gt;
DB_DATABASE="tutorial"&lt;/p&gt;

&lt;p&gt;With the setup of the dbconnect and .env file, we are ready to export our database and tables from our local machine to heroku postgres.&lt;/p&gt;

&lt;p&gt;How to Export Database and Tables&lt;br&gt;
Go to your pgAdmin and locate the database for this tutorial. Mine is tutorial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j7agFJLX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2sxbkqivmhh9fgdcyjc.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j7agFJLX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2sxbkqivmhh9fgdcyjc.jpeg" alt="Image description" width="880" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right-Click on it and select Backup. This will bring up a new window.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--npE7oX-a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lj90aljmo97pw268uq40.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--npE7oX-a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lj90aljmo97pw268uq40.jpeg" alt="Image description" width="880" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter a name for the SQL file like I did. Select the plain format. Then click Backup. This will save the file to your documents folder.&lt;/p&gt;

&lt;p&gt;Locate the file and move it into the project directory. It can be anywhere in the directory but I choose to move mine into the services directory because it holds the database related files.&lt;/p&gt;

&lt;p&gt;Back in the terminal, navigate to the folder containing the SQL file and run the following code to add the tables we just exported to the heroku postgres database:&lt;/p&gt;

&lt;p&gt;cat  | &lt;br&gt;
This is what mine looks like:&lt;/p&gt;

&lt;p&gt;cat tutorial.sql | heroku pg:psql postgresql-slippery-19135 --app node-postgres-cloudinary&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XRPpbUCr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2iqys6p9k4a5f3cnutfu.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XRPpbUCr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2iqys6p9k4a5f3cnutfu.jpeg" alt="Image description" width="738" height="677"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Did you notice that I changed directory to services (cd services)? That is where my sql file is located.&lt;/p&gt;

&lt;p&gt;Wow! We have just successfully exported our database and tables to Heroku.&lt;/p&gt;

&lt;p&gt;It is almost over...&lt;/p&gt;

&lt;p&gt;How to Tell GitHub that We Made Changes&lt;br&gt;
Add the files we have made changes to:&lt;/p&gt;

&lt;p&gt;$ git add .&lt;br&gt;
The period (.) adds all files.&lt;/p&gt;

&lt;p&gt;Commit your latest changes:&lt;/p&gt;

&lt;p&gt;$ git commit -m "refactored the dbConnect and .env file to fit in to heroku; Added the database SQL file"&lt;br&gt;
Push the committed files:&lt;/p&gt;

&lt;p&gt;$ git push origin -u master&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bgZqo6U9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/00rl4i4eizbb0g1zh7yl.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bgZqo6U9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/00rl4i4eizbb0g1zh7yl.jpeg" alt="Image description" width="880" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally deploying our App&lt;br&gt;
Go to you app's dashboard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QLEGvJuv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d4nu5rka1fgi1bikv4nt.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QLEGvJuv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d4nu5rka1fgi1bikv4nt.jpeg" alt="Image description" width="750" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search and select a repo, and click on connect:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k_YdFzE3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i7710wjgvrkapepmy1o7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k_YdFzE3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i7710wjgvrkapepmy1o7.jpeg" alt="Image description" width="745" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the branch you want to deploy (in my own case, it is the master branch):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mte7XQr6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q8nddaxdd02wclz7kka4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mte7XQr6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q8nddaxdd02wclz7kka4.jpeg" alt="Image description" width="750" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enable automatic deployment by clicking the Enable automatic deployment button as in the image above.&lt;/p&gt;

&lt;p&gt;Click on the Deploy button in the manual deploy&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qkmYvUUO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kc3xdm1njfir55egox84.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qkmYvUUO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kc3xdm1njfir55egox84.jpeg" alt="Image description" width="750" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will not have to do all this for subsequent deployments.&lt;/p&gt;

&lt;p&gt;Now you have a button telling you to "view site" after build is completed. Click it. This will open your app in a new tab&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c5uo2Y0o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxmm992brxvgmm40alza.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c5uo2Y0o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxmm992brxvgmm40alza.jpeg" alt="Image description" width="750" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh no! A bug? Application error??&lt;/p&gt;

&lt;p&gt;Don't worry, it just a small issue. Something you should never forget to do while making deployments. Most hosting service will require it.&lt;/p&gt;

&lt;p&gt;How to Fix the Heroku Application Error&lt;br&gt;
Get back to the root directory of your project.&lt;/p&gt;

&lt;p&gt;Create a file and name it Procfile (it has no extension).&lt;/p&gt;

&lt;p&gt;In the file, enter the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web: node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OxCb2Izv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/339pdkwi3pnc9sh09edl.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OxCb2Izv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/339pdkwi3pnc9sh09edl.jpeg" alt="Image description" width="750" height="904"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This directs Heroku to the server file (index.js) which is the entry point of the application. If your server is in a different file, please modify as required.&lt;/p&gt;

&lt;p&gt;Save the file and push the new changes to GitHub.&lt;/p&gt;

&lt;p&gt;Wait 2 to 5 minutes for Heroku to automatically detect changes in your GitHub repo and render the changes on the app.&lt;/p&gt;

&lt;p&gt;You can now refresh that error page and see your hard work paying off:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OVtxehbQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mi68v2bcqwaprhgvwl06.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OVtxehbQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mi68v2bcqwaprhgvwl06.jpeg" alt="Image description" width="750" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also test the retrieve image route and see it working.&lt;/p&gt;

&lt;p&gt;Congratulations! What a feat you have attained.&lt;/p&gt;

&lt;p&gt;Other routes (persist-image, update-image, and delete-image) will not be working because we have not provisioned or added cloudinary add-on. It is as simple as the PostgreSQL one we just did. So you can give it a shot.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
We started this tutorial with the aim of learning how to build a backend application using Express, Postgres, Cloudinary, Github and Heroku.&lt;/p&gt;

&lt;p&gt;We learned how to store, retrieve, delete, and update an image record. We then organised our code with Express Routing, pushed it to GitHub, and deployed it on Heroku. That was a lot.&lt;/p&gt;

&lt;p&gt;I hope you will agree that it was worth it because we learnt a lot. You should try adding the Cloudinary add-on yourself to sharpen your knowledge even more.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>React Context API vs Zustand State Manager</title>
      <dc:creator>Smilepk</dc:creator>
      <pubDate>Sat, 19 Feb 2022 17:37:31 +0000</pubDate>
      <link>https://forem.com/smilepk/react-context-api-vs-zustand-state-manager-72d</link>
      <guid>https://forem.com/smilepk/react-context-api-vs-zustand-state-manager-72d</guid>
      <description>&lt;p&gt;This article will show a practical performance comparison between the usage of React Context API and the Zustand State Manager library by solving one scenario with the above-mentioned approaches.&lt;br&gt;
In the production level frontend application that uses React JS, we may need to manage the state. Indeed that is why we focus on frontend frameworks or libraries most of the time. When it comes to the manage our application state globally, we meet lots of state managers or state management patterns and utilities. As we know React JS is quite statable in the market and because of that we can get multiple approaches to manage our frontend application’s state. In this article, I am going to compare the React Context API and the Zustand State Manager with a practical example.&lt;br&gt;
First of all, let's understand what we are going to build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9gp69pmk8bopcio77kxw.png)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This application contains two main components that show the final winner called the winner component. It will compare the scores achieved by Player A and Player B then show the real-time results. Individual Player' component has their own behavior. By pressing those plus and minus icon buttons scores of each team will be increased or decreased respectively.&lt;br&gt;
I am going to create a Next.js Application for this demo. with that, I will create two routes one for the solution with Context API and the other with the Zustand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
npx create-next-app@latest
# or
yarn create next-app

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

&lt;/div&gt;



&lt;p&gt;yarn create next-app&lt;br&gt;
Create a new Next.js Application using the above command and give it a proper name in the installation process. after completing the installation get your app up and running. Then under the pages directory, I created two files called “context-page” and “zustand-page”&lt;/p&gt;

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

&lt;p&gt;Let's take our first approach using Context API.&lt;br&gt;
This is how we keep the Player scores in the store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
{
     teamA, // Team A's score
     teamB, // Team B's score
     increaseTeamAScore, // Increase Team A's score by one
     decreaseTeamAScore, // Decrease Team A's score by one
     increaseTeamBScore, // Increase Team B's score by one
     decreaseTeamBScore, // Decrease Team B's score by one
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By keeping in mind of above store design, let’s create our context.&lt;/p&gt;

&lt;p&gt;Now we are going to create context-page.js file. This will include the components that we talk earlier with a diagram.&lt;/p&gt;

&lt;p&gt;Easy Peasy..!! We Created our first solution with Context API. Go to the route below and check the functionality. Since we are&lt;br&gt;
&lt;a href="http://localhost:3000/context-page" rel="noopener noreferrer"&gt;http://localhost:3000/context-page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, now you can see our solution's appearance is fine and working as we expected. Let’s have a look at this solution from a performance perspective. To do that first of all I am going to term on the “Highlight updates when components render.” feature that comes with React Dev Tools Profiler. I’ll go to the Profiler tab and then click on the Gear icon placed on the top right side. Then I will check the option.&lt;/p&gt;

&lt;p&gt;Once that option is enabled, you can see that highlighted sections. It is happening because when we wrap the component tree with Context, it will always rerender all components under the Context Prover when the context change happens.&lt;br&gt;
When we increase or decrease the score of Team A, actually we do not need to rerender the Team B components. since the entire components are wrapped with the StoreContextProvider and actions have done to the Team A component will affect to context, the Team B component also going to reprint. That is why the Team B component also going to be highlighted by the Profiler.&lt;br&gt;
Because scores are compared inside the Winner component, it should rerender. But we do not need to rerender the Team B component. That is the issue with the Context API. It is going to rerender the entire scope that is wrapped with the context provider. But in the real world, we are expecting to rerender changed components only.&lt;br&gt;
To overcome such scenarios, We can take different actions. We can use state managers such as Zustand or libraries like “use-context-selector”. In today's post, I am going to use the Zustand state manager library to overcome this issue.&lt;br&gt;
The store design is the same as above and let's have a deep dive in the Zustand library.&lt;br&gt;
Create a Zustand store.&lt;/p&gt;

&lt;p&gt;You can see it is easy to create our store with Zustand and create all action methods to deal with the state. Now we will see how to subscribe a component to the store.&lt;/p&gt;

&lt;p&gt;You can see how easily we can subscribe to the store that we created. That is the power of Zustand. It is a small, fast, and scalable barebones state-management solution using simplified flux principles according to their documentation and now we know because we started to use that too.&lt;br&gt;
With the above introduction to Zustand, Let’s create our solution with the help of Zustand. First of all, install the package to our Application.&lt;br&gt;
yarn add zustan # or dnpm install zustand&lt;br&gt;
Then let’s create the “zustand-page.js” file with the solution.&lt;/p&gt;

&lt;p&gt;Okay, we have addressed the same problem but with a different solution. We can see the expected behavior achieved and now let’s see how the rerendering happens.&lt;/p&gt;

&lt;p&gt;According to the Profiler, now you can see how the rerenders happen. With the help of Zustand, we have achieved the perfoamce issue too. And the creation of the store and subscribing to the Components are also pretty straightforward.&lt;br&gt;
There are a lot more features offered with the Zustand. You can go through their documentation and find more.&lt;br&gt;
Thank you for reading 🙏.&lt;br&gt;
It would help me a lot 😁&lt;br&gt;
React&lt;br&gt;
React Context Api&lt;br&gt;
Prop Drilling&lt;/p&gt;

&lt;p&gt;Context Api&lt;br&gt;
3&lt;/p&gt;

&lt;p&gt;1&lt;/p&gt;

&lt;p&gt;More from Vimukthi Jayasinghe&lt;br&gt;
Follow&lt;/p&gt;

&lt;p&gt;Experienced Software Engineer with a demonstrated history of working in the computer software industry.&lt;br&gt;
More From Medium&lt;br&gt;
Angular Performance: Web Workers&lt;br&gt;
Chidume Nnamdi 🔥💻🎵🎮 in Bits and Pieces&lt;/p&gt;

&lt;p&gt;How to implement JestJS on existing website&lt;br&gt;
Andy Greco&lt;/p&gt;

&lt;p&gt;Greedy algorithms&lt;br&gt;
chathurya&lt;/p&gt;

&lt;p&gt;Intigriti’s December XSS challenge By E1u5iv3F0x&lt;br&gt;
Martin Stoynov&lt;/p&gt;

&lt;p&gt;Chapter 11: How to build a Google Home App with DialogFlow | Fulfillment via Webhook&lt;br&gt;
Moses Sam Paul in Heptagon&lt;/p&gt;

&lt;p&gt;React Native — Full authentication flow with Spotify— Chapter 2: Backend Proxy (Firebase Functions…&lt;br&gt;
Thomas Swolfs&lt;/p&gt;

&lt;p&gt;Asynchronous communication in JavaScript: fetch() vs ajax()&lt;br&gt;
William Harris&lt;/p&gt;

&lt;p&gt;How to Debug a TypeScript Node.js App in Visual Studio Code&lt;br&gt;
Bilal Rifas in JavaScript in Plain English&lt;/p&gt;

&lt;p&gt;About&lt;br&gt;
Write&lt;br&gt;
Help&lt;br&gt;
Legal&lt;br&gt;
Get the Medium app&lt;br&gt;
A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store&lt;br&gt;
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Control React Applications From Cypress Tests</title>
      <dc:creator>Smilepk</dc:creator>
      <pubDate>Thu, 17 Feb 2022 11:56:03 +0000</pubDate>
      <link>https://forem.com/smilepk/control-react-applications-from-cypress-tests-dok</link>
      <guid>https://forem.com/smilepk/control-react-applications-from-cypress-tests-dok</guid>
      <description>&lt;p&gt;How to access and change the internal component state from end-to-end tests using cypress-react-app-actions.&lt;br&gt;
In the previous blog post Access React Components From Cypress E2E Tests I have shown how the test code could get to the React component's internals, similar to what the React DevTools browser extension does. In this blog post, I will show how to use this approach to drastically speed up end-to-end tests. The idea is to control the application by setting its internal state rather than using the page UI in every test. We will split a single long test into individual tests, each starting the app where it needs it to be in an instant, rather than going through already tested UI commands. It is similar to what I have shown a long time ago in the blog post Split a very long Cypress test into shorter ones using App Actions. But the approach described in this blog post does not need any modifications to the application code, which is a big deal.&lt;/p&gt;

&lt;p&gt;A single long test #&lt;/p&gt;

&lt;p&gt;Imagine our application contains several forms to fill. The test has to fill the first page before the second page appears. Once the second page is filled, the third page is shown. After filling the third page, the form is submitted and the test is done&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
cypress/integration/single-test.js

/// &amp;lt;reference types="cypress" /&amp;gt;
const typeOptions = { delay: 35 }

it('books hotel (all pages)', () =&amp;gt; {
  cy.visit('/')

  cy.log('**First page**')
  cy.contains('h1', 'Book Hotel 1')

  cy.get('#first').type('Joe', typeOptions)
  cy.get('#last').type('Smith', typeOptions)
  cy.get('#email').type('my-email@foo.bar', typeOptions)

  cy.get('#field1a').type('Field 1a text value', typeOptions)
  cy.get('#field1b').type('Field 1b text value', typeOptions)
  cy.get('#field1c').type('Field 1c text value', typeOptions)
  cy.get('#field1d').type('Field 1d text value', typeOptions)
  cy.get('#field1e').type('Field 1e text value', typeOptions)

  cy.contains('Next').click()

  cy.log('**Second page**')
  cy.contains('h1', 'Book Hotel 2')
  // we are on the second page

  cy.get('#username').type('JoeSmith', typeOptions)
  cy.get('#field2a').type('Field 2a text value', typeOptions)
  cy.get('#field2b').type('Field 2b text value', typeOptions)
  cy.get('#field2c').type('Field 2c text value', typeOptions)
  cy.get('#field2d').type('Field 2d text value', typeOptions)
  cy.get('#field2e').type('Field 2e text value', typeOptions)
  cy.get('#field2f').type('Field 2f text value', typeOptions)
  cy.get('#field2g').type('Field 2g text value', typeOptions)
  cy.contains('Next').click()

  cy.log('**Third page**')
  cy.contains('h1', 'Book Hotel 3')

  cy.get('#field3a').type('Field 3a text value', typeOptions)
  cy.get('#field3b').type('Field 3b text value', typeOptions)
  cy.get('#field3c').type('Field 3c text value', typeOptions)
  cy.get('#field3d').type('Field 3d text value', typeOptions)
  cy.get('#field3e').type('Field 3e text value', typeOptions)
  cy.get('#field3f').type('Field 3f text value', typeOptions)
  cy.get('#field3g').type('Field 3g text value', typeOptions)
  cy.contains('button', 'Sign up').click()

  cy.contains('button', 'Thank you')
})

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

&lt;/div&gt;



&lt;p&gt;The above test takes almost 19 seconds to finish. Of course, it is the slowest end-to-end test in the world, but you have to sit and wait for it, even if you are only interested in changing how it tests the form submission for example.&lt;/p&gt;

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

&lt;p&gt;The app state after the first page #&lt;/p&gt;

&lt;p&gt;All the fields we fill on the first page go into the internal state of the application. The application creates a form for each page and passes the change handler function as a prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
index.js
import Step1 from './Step1.jsx'

handleChange = (event) =&amp;gt; {
  const { name, value } = event.target
  this.setState({
    [name]: value,
  })
}

handleSubmit = (event) =&amp;gt; {
  event.preventDefault()

  console.log('submitting state', this.state)

  const { email, username } = this.state

  this.setState({
    submitted: true,
  })

  alert(`Your registration detail: \n
          Email: ${email} \n
          Username: ${username}`)
}

&amp;lt;Step1
  currentStep={this.state.currentStep}
  handleChange={this.handleChange}
  email={this.state.email}
/&amp;gt;
&amp;lt;Step2
  currentStep={this.state.currentStep}
  handleChange={this.handleChange}
  username={this.state.username}
/&amp;gt;
&amp;lt;Step3
  currentStep={this.state.currentStep}
  handleChange={this.handleChange}
  password={this.state.password}
  submitted={this.state.submitted}
/&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Thus we can validate that the Step1 component is working correctly by checking the state after we fill the form through the page.&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
cypress/integration/actions.js

beforeEach(() =&amp;gt; {
  cy.visit('/')
})

it('first page', () =&amp;gt; {
  cy.log('**First page**')
  cy.contains('h1', 'Book Hotel 1')

  cy.get('#first').type('Joe', typeOptions)
  cy.get('#last').type('Smith', typeOptions)
  cy.get('#email').type('my-email@foo.bar', typeOptions)

  cy.get('#field1a').type('Field 1a text value', typeOptions)
  cy.get('#field1b').type('Field 1b text value', typeOptions)
  cy.get('#field1c').type('Field 1c text value', typeOptions)
  cy.get('#field1d').type('Field 1d text value', typeOptions)
  cy.get('#field1e').type('Field 1e text value', typeOptions)

  cy.contains('Next').click()

  cy.log('Second page')
  cy.contains('h1', 'Book Hotel 2')
})

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://glebbahmutov.com/blog/images/react-app-actions/step1.gif" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are testing the page just like a human user would - by going to each input field and typing text. Once the fields are filled, we click the button "Next" and check if we end up on the second page. But how do we check if the values we typed really were stored correctly by the application?&lt;/p&gt;

&lt;p&gt;By getting access to the application state through React internals. I wrote cypress-react-app-actions plugin that gets to the React component from a DOM element, similar to how React DevTools browser extension works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
$ npm i -D cypress-react-app-actions
+ cypress-react-app-actions@1.0.2

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

&lt;/div&gt;



&lt;p&gt;We should import the plugin from our spec or from the support file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
/ https://github.com/bahmutov/cypress-react-app-actions
import 'cypress-react-app-actions'
// now we can use the child command .getComponent()

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

&lt;/div&gt;



&lt;p&gt;Let's see what fields the component has at the end of the test above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cy.log('Second page')
cy.contains('h1', 'Book Hotel 2')
cy.get('form')
  .getComponent()
  .its('state')
  .then(console.log)

``

The application state object after finishing step one

Tip: you can see all component fields and methods by printing it to the console with cy.get('form').getComponent().then(console.log) command.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lsj0svk123alg2y2a1wb.png)

The component's state should always include the field values we have typed, so let's verify this. We could use "deep.equal" or "deep.include" assertion, or even cy-spok here.

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

&lt;/div&gt;



&lt;p&gt;cypress/integration/actions.js&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feluts90pavrtpamahv1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feluts90pavrtpamahv1z.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
const startOfSecondPageState = {&lt;br&gt;
  currentStep: 2,&lt;br&gt;
  email: '&lt;a href="mailto:my-email@foo.bar"&gt;my-email@foo.bar&lt;/a&gt;',&lt;br&gt;
  field1a: 'Field 1a text value',&lt;br&gt;
  field1b: 'Field 1b text value',&lt;br&gt;
  field1c: 'Field 1c text value',&lt;br&gt;
  field1d: 'Field 1d text value',&lt;br&gt;
  field1e: 'Field 1e text value',&lt;br&gt;
  first: 'Joe',&lt;br&gt;
  last: 'Smith',&lt;br&gt;
  username: '',&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;beforeEach(() =&amp;gt; {&lt;br&gt;
  cy.visit('/')&lt;br&gt;
})&lt;/p&gt;

&lt;p&gt;it('first page', () =&amp;gt; {&lt;br&gt;
  ...&lt;br&gt;
  cy.contains('Next').click()&lt;/p&gt;

&lt;p&gt;cy.log('Second page')&lt;br&gt;
  cy.contains('h1', 'Book Hotel 2')&lt;br&gt;
  cy.get('form')&lt;br&gt;
    .getComponent()&lt;br&gt;
    .its('state')&lt;br&gt;
    .should('deep.equal', startOfSecondPageState)&lt;br&gt;
})&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0ytmdw6r0qdm8gygock.png)

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

&lt;/div&gt;



&lt;p&gt;// the end of the first test&lt;br&gt;
cy.get('form')&lt;br&gt;
  .getComponent()&lt;br&gt;
  .its('state')&lt;br&gt;
  .should('deep.equal', startOfSecondPageSt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Thus we can set the app's state to the object startOfSecondPageState and the application will behave as if we went through the form, filling it by typing. It is the same application behaviour.

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

&lt;/div&gt;



&lt;p&gt;beforeEach(() =&amp;gt; {&lt;br&gt;
  cy.visit('/')&lt;br&gt;
})&lt;/p&gt;

&lt;p&gt;it('second page', () =&amp;gt; {&lt;br&gt;
  cy.get('form').getComponent().invoke('setState', startOfSecondPageState)&lt;/p&gt;

&lt;p&gt;cy.log('&lt;strong&gt;Second page&lt;/strong&gt;')&lt;br&gt;
  cy.contains('h1', 'Book Hotel 2')&lt;br&gt;
  // start filling input fields on page 2&lt;br&gt;
  cy.get('#username').type('JoeSmith', typeOptions)&lt;br&gt;
  cy.get('#field2a').type('Field 2a text value', typeOptions)&lt;br&gt;
  cy.get('#field2b').type('Field 2b text value', typeOptions)&lt;br&gt;
  cy.get('#field2c').type('Field 2c text value', typeOptions)&lt;br&gt;
  cy.get('#field2d').type('Field 2d text value', typeOptions)&lt;br&gt;
  cy.get('#field2e').type('Field 2e text value', typeOptions)&lt;br&gt;
  cy.get('#field2f').type('Field 2f text value', typeOptions)&lt;br&gt;
  cy.get('#field2g').type('Field 2g text value', typeOptions)&lt;br&gt;
  cy.contains('Next').click()&lt;/p&gt;

&lt;p&gt;cy.log('Third page')&lt;br&gt;
  cy.contains('h1', 'Book Hotel 3')&lt;br&gt;
})&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
[](https://glebbahmutov.com/blog/images/react-app-actions/second.gif)

Beautiful. How does the application finish? Again - it has a certain internal state we can verify.

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

&lt;/div&gt;



&lt;p&gt;const startOfThirdPageState = {&lt;br&gt;
  ...startOfSecondPageState,&lt;br&gt;
  currentStep: 3,&lt;br&gt;
  username: 'JoeSmith',&lt;br&gt;
  field2a: 'Field 2a text value',&lt;br&gt;
  field2b: 'Field 2b text value',&lt;br&gt;
  field2c: 'Field 2c text value',&lt;br&gt;
  field2d: 'Field 2d text value',&lt;br&gt;
  field2e: 'Field 2e text value',&lt;br&gt;
  field2f: 'Field 2f text value',&lt;br&gt;
  field2g: 'Field 2g text value',&lt;br&gt;
}&lt;br&gt;
...&lt;br&gt;
cy.log('Third page')&lt;br&gt;
cy.contains('h1', 'Book Hotel 3')&lt;br&gt;
cy.get('form')&lt;br&gt;
  .getComponent()&lt;br&gt;
  .its('state')&lt;br&gt;
  .should('deep.equal', startOfThirdPageState)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
The third page #

We similarly start the third test to verify we can fill the form on the third page. We set the state to the same state object the second test has finished with. Even better - we know the user will submit the form, so we can spy on the component's method handleSubmit.

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

&lt;/div&gt;



&lt;p&gt;it('third page', () =&amp;gt; {&lt;br&gt;
  cy.get('form')&lt;br&gt;
    .getComponent()&lt;br&gt;
    .then((comp) =&amp;gt; {&lt;br&gt;
      cy.spy(comp, 'handleSubmit').as('handleSubmit')&lt;br&gt;
    })&lt;br&gt;
    .invoke('setState', startOfThirdPageState)&lt;/p&gt;

&lt;p&gt;cy.log('&lt;strong&gt;Third page&lt;/strong&gt;')&lt;br&gt;
  cy.contains('h1', 'Book Hotel 3')&lt;br&gt;
  ...&lt;br&gt;
  cy.contains('button', 'Sign up').click()&lt;br&gt;
  cy.contains('button', 'Thank you')&lt;/p&gt;

&lt;p&gt;cy.get('form').parent().getComponent().its('state').should('deep.include', {&lt;br&gt;
    submitted: true,&lt;br&gt;
    username: 'JoeSmith',&lt;br&gt;
  })&lt;/p&gt;

&lt;p&gt;// the spy is called once&lt;br&gt;
  cy.get('@handleSubmit').should('be.calledOnce')&lt;br&gt;
})&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

[](https://glebbahmutov.com/blog/images/react-app-actions/second.gif)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38ql60juorhbzn2vz9i6.png)

The third test verifies the form was submitted

It is up to the developer to decide which application internal properties to verify.

Invoking app actions #

We can verify the internal application state and we can call the component's methods. For example, we can call the form's submit method ourselves.











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

&lt;/div&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>devops</category>
      <category>docker</category>
    </item>
    <item>
      <title>Build Decoupled React Components with Inversion of Control</title>
      <dc:creator>Smilepk</dc:creator>
      <pubDate>Mon, 07 Feb 2022 10:47:33 +0000</pubDate>
      <link>https://forem.com/smilepk/build-decoupled-react-components-with-inversion-of-control-10d0</link>
      <guid>https://forem.com/smilepk/build-decoupled-react-components-with-inversion-of-control-10d0</guid>
      <description>&lt;p&gt;Imagine you’re implementing an e-commerce checkout, and the product manager has temporally chosen PayPal as payment provider. But it’s planned to change the provider for another one, e.g.: Stripe. Looking for small changes in the future, how would you implement this?&lt;br&gt;
Inversion of Control (IoC) probably will help you in this case.&lt;br&gt;
What is IoC?&lt;br&gt;
IoC is a programming principle where you invert the control flow of a program, it’s used to decouple your code. You can read more about &lt;a href="https://dev.tourl"&gt;here&lt;/a&gt;, let’s go code.&lt;/p&gt;

&lt;p&gt;You have the checkout.component.tsx that is responsible for creating the checkout flow. It renders the product list, total of payment and the payment form that is provided by PayPal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
interface Props {}

const CheckoutComponent = (props: Props) =&amp;gt; {
  const [products, setProducts] = useState([...products]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const total = useMemo(() =&amp;gt; ...total, []);

  const onPayError = () =&amp;gt; { ... };

  const onPaySuccess = () =&amp;gt; { ... };

  const onPay = () =&amp;gt; {
     paypal.someMethod(onPaySuccess, onPayError);
  };

  // All the payment stuff goes here

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        Products:
        &amp;lt;ul&amp;gt;
          {products.map(product =&amp;gt; &amp;lt;li key={product.id}&amp;gt;{product.name} - U${product.price}&amp;lt;/li&amp;gt;)}
        &amp;lt;/ul&amp;gt;
        &amp;lt;p&amp;gt;Total: U${total}&amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;PaypalForm /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;The problem here is that your checkout flow knows about PayPal, and that can generate a huge refactor in the future.&lt;br&gt;
To prevent this, you can use ElementType and interfaces.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
interface ProviderProps {
  onPaymentSucceed: () =&amp;gt; void;
  onPaymentError: (error: string) =&amp;gt; void;
  onPaymentStart: () =&amp;gt; void;
  ... any prop here
}

interface ComponentProps {
  provider: JSX ElementConstructor&amp;lt;ProviderProps&amp;gt;;
}


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

&lt;/div&gt;



&lt;p&gt;ProviderProps ensure that any provider will implement the correct methods. ComponentProps forces the checkout flow to receive a provider and mount it, passing the given props.&lt;br&gt;
Now we can create a “dumb” component that knows how to control the screen state, like loading and feedback.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const CheckoutComponent = ({ provider: Provider }: ComponentProps) =&amp;gt; {
  const [products, setProducts] = useState([...products]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const total = useMemo(() =&amp;gt; ...total, []);

  const onPaymentError = (error: string) =&amp;gt; setError(error);

  const onPaymentSucceed = () =&amp;gt; redirectToHome();

  const onPaymentStart = () =&amp;gt; setLoading(true);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        Products:
        &amp;lt;ul&amp;gt;
          {products.map(product =&amp;gt; &amp;lt;li key={product.id}&amp;gt;{product.name} - U${product.price}&amp;lt;/li&amp;gt;)}
        &amp;lt;/ul&amp;gt;
        &amp;lt;p&amp;gt;Total: U${total}&amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;Provider
        onPaymentStart={onPaymentStart}
        onPaymentSucceed={onPaymentSucceed}
        onPaymentError={onPaymentError}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;And the responsible for managing the payment with PayPal can be isolated, totally decoupling the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const PayPalProvider = ({ onPaymentSucceed, onPaymentError, onPaymentStart }: ProviderProps) =&amp;gt; {
  const handlePayment = () =&amp;gt; {
    onPaymentStart();

    paypal.someMethod()
      .then(() =&amp;gt; {
        onPaymentSucceed();
      })
      .catch(error =&amp;gt; {
        onPaymentError(error.message);
      });
  };

  return (
    &amp;lt;form onSubmit={handlePayment}&amp;gt;
      &amp;lt;PayPalForm /&amp;gt;
      &amp;lt;button type="submit"&amp;gt;Pay&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;Now, you can create a simple container that mount the checkout component and pass the correct props.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import PayPalContainer from './paypal.container';

const CheckoutContainer = () =&amp;gt; (
  &amp;lt;CheckoutComponent provider={PayPalContainer} // any props here /&amp;gt;
);

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

&lt;/div&gt;



&lt;p&gt;You can even create a factory method that returns the correct provider in a scenario you have more than one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
export enum Provider {
  PAYPAL = "PAYPAL",
  STRIPE = "STRIPE"
}

const getSelectedProvider = (): Provider =&amp;gt; {...};

const getProviderContainer = (provider: Provider) =&amp;gt; {
  switch (provider) {
    case Provider.PAYPAL:
      return PayPalContainer;
    case Provider.STRIPE:
      return StripeProvider;
  }
};

const CheckoutContainer = () =&amp;gt; {
  const provider = getSelectedProvider();

  return &amp;lt;CheckoutComponent provider={getProviderContainer(provider)} /&amp;gt;;
};

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

&lt;/div&gt;



&lt;p&gt;I hope that this article helped you to understand how to use inversion of control with react and how to decouple your code to be more maintainable.&lt;/p&gt;

&lt;p&gt;Build with independent components, for speed and scale&lt;br&gt;
Instead of building monolithic apps, build independent components first and compose them into features and applications. It makes development faster and helps teams build more consistent and scalable applications.&lt;br&gt;
OSS Tools like Bit offer a great developer experience for building independent components and composing applications. Many teams start by building their Design Systems or Micro Frontends, through independent components.&lt;a&gt; Give it a try →&lt;/a&gt;&lt;/p&gt;

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

</description>
    </item>
    <item>
      <title>Understanding React Lifecycles </title>
      <dc:creator>Smilepk</dc:creator>
      <pubDate>Tue, 01 Feb 2022 18:17:04 +0000</pubDate>
      <link>https://forem.com/smilepk/understanding-react-lifecycles-5gp3</link>
      <guid>https://forem.com/smilepk/understanding-react-lifecycles-5gp3</guid>
      <description>&lt;p&gt;Simply and directly, lifecycle refers to the 3 stages that a React component goes through during its existence.&lt;br&gt;
Every component in React goes through three stages which are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mounting&lt;/li&gt;
&lt;li&gt;Update&lt;/li&gt;
&lt;li&gt;Unmounting&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is important that you, as a React developer, know these 3 phases and what methods are associated with each of them. These methods can be overwritten in class components to perform side effects and manage the state of the component.&lt;br&gt;
Let’s take a look at these methods in each of the phases:&lt;br&gt;
Mounting&lt;br&gt;
This is the initial phase of any component. It corresponds to the moment when the component will be inserted in the DOM. That is, when it starts to exist on your browser’s screen.&lt;br&gt;
In this phase there are 4 methods that are executed in the following order:&lt;/p&gt;

&lt;p&gt;contructor()&lt;br&gt;
getDerivedStateFromProps()&lt;br&gt;
render()&lt;br&gt;
componentDidMount()&lt;/p&gt;

&lt;p&gt;Of these methods, only the third (render) is mandatory when creating a class component. The others are left to the developer to implement or not in their component.&lt;/p&gt;

&lt;p&gt;The first, constructor, is used in React components to set the initial state value.&lt;br&gt;
The getDerivedStateFromProps method is used for one purpose only: It allows a component to update its state through a change of props. See two examples of its use here. In the following example I set the state of the counter with the value passed in the prop.&lt;br&gt;
The third and only mandatory is render. When called, it must examine this.props and this.state and return one of the following types: a React element, a Portal, a string, a number, a boolean, or the value null. The render method should remain pure, that is, do not create side effects (such as API calls) in it.&lt;/p&gt;

&lt;p&gt;Today it is no longer necessary for you to call the constructor to initialize a state, which eliminates the need for it.&lt;br&gt;
The getDerivedStateFromProps method adds some complexity to our component and overall you won’t need to use it.&lt;br&gt;
This post on the React blog indicates why not to use derived state&lt;br&gt;
Updating&lt;br&gt;
When the component overwrites some props change (i.e. its parent component passes new props) or when the internal state overwrites a change (by this.setState({}) for example) the component enters the updating phase.&lt;br&gt;
Just like in the assembly phase, a defined sequence of methods will be called. They are:&lt;br&gt;
getDerivedStateFromProps()&lt;br&gt;
shouldComponentUpdate()&lt;br&gt;
render()&lt;br&gt;
getSnapshotBeforeUpdate()&lt;br&gt;
componentDidUpdate()&lt;br&gt;
The first method, getDerivedStateFromProps we already know and covered in the assembly phase. Its behavior is the same here in the update phase.&lt;/p&gt;

&lt;p&gt;The second method, shouldComponentUpdate will determine whether the methods in the sequence are executed or not. That is, it will determine whether the component should be rendered again or not. This method exists only as a way for us to avoid unnecessary updating, and thus optimize the performance of our applications.&lt;br&gt;
If the this.forceUpdate() method has been called the update will not call shouldComponentUpdate, and the component will be forcefully updated as the name implies.&lt;br&gt;
getSnapshotBeforeUpdate is then called just before the most recently rendered output is committed. It allows your component to grab some information from the DOM (for example, the scroll position) before it is potentially changed.&lt;br&gt;
Any value returned by this life cycle will be passed as a third parameter, called snapshot, to the componentDidUpdate method.&lt;br&gt;
With the DOM updated, the componentDidUpdate method is finally called.&lt;/p&gt;

&lt;p&gt;UnMounting&lt;/p&gt;

&lt;p&gt;When the component is going to be removed from the DOM, by changing state or props, we are in the disassembly.&lt;br&gt;
Here we have only one life cycle method, which is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;componentWillMount()&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This method is executed just before the component is removed. It is used to remove entries and listeners. An example is with the use of setInterval, that even if the component is removed, it will continue to run regardless of the existence of the component that invoked it.&lt;/p&gt;

&lt;p&gt;Legacy methods&lt;br&gt;
For creating confusion and some hard-to-solve bugs, some React lifecycle methods are being deprecated. In version 17 they can still be used with the UNSAFE_ prefix in front of their names. To understand more about why they are being deprecated, [see this post on the React blog]&lt;br&gt;
UNSAFE_componentWillMount()&lt;br&gt;
UNSAFE_componentWillReceiveProps()&lt;br&gt;
UNSAFE_componentWillUpdate()&lt;br&gt;
Conclusion&lt;br&gt;
I hope that now you have a better sense of what is the lifecycle! this is definitely a concept that will help you build a better and more predictable UI in the future.&lt;/p&gt;

</description>
      <category>react</category>
      <category>node</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Free React Templates You can Use for Your Projects</title>
      <dc:creator>Smilepk</dc:creator>
      <pubDate>Tue, 01 Feb 2022 17:57:34 +0000</pubDate>
      <link>https://forem.com/smilepk/free-react-templates-you-can-use-for-your-projects-7c9</link>
      <guid>https://forem.com/smilepk/free-react-templates-you-can-use-for-your-projects-7c9</guid>
      <description>&lt;p&gt;Nowadays, the majority of developers use React for their web development projects. React is one of the popular JavaScript libraries for frontend developers, it’s a powerful tool to easily build user interfaces and create web applications.&lt;br&gt;
There are a lot of free React resources that you can use to help you boost your productivity and build projects faster than ever. Templates and themes are the best way to save time when starting a React project. Especially if you just want to quickly build a project without focusing a lot on the design process.&lt;br&gt;
Most of these templates you can start with are open-sourced on GitHub by other developers like you and me. Also, if you’re not a good designer, these templates can definitely help you to improve your project's design and follow UI/UX best practices.&lt;br&gt;
So in this article, I will share with you a list of awesome templates you can use to build anything with React. Let’s get right into it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Holly Template
&lt;a href="https://demos.onepagelove.com/html/holly/"&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Holly is a responsive React template for anyone who wants to create a beautiful landing page to collect &lt;/p&gt;

&lt;p&gt;Capture by the author from Holly-react.&lt;br&gt;
You can easily clone the template to your machine using Git. Of course, you might also customize the template as you want and edit the code as well. Here is the live demo if you want to see the design.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Carolina Admin Dashboard
&lt;a href="https://demo.uifort.com/carolina-react-admin-dashboard-material-ui-free-demo/DashboardDefault"&gt;Carolina &lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Carolina Admin Dashboard is a free React template that you can use to build a functional admin dashboard using React.&lt;/p&gt;

&lt;p&gt;Capture by the author from Carolina Admin Dashboard.&lt;br&gt;
This professional template is built using the Material UI framework. It has a lot of different components with a clean design structure. Carolina Admin Dashboard is a very useful template to start with, especially if you’re building some kind of analytics web application.&lt;br&gt;
What’s good about this template:&lt;br&gt;
Fully responsive.&lt;br&gt;
Follows UI/UX best practices.&lt;br&gt;
Utilities and helpers are included.&lt;br&gt;
Clean layout and structure.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://open.cruip.com/"&gt;https://open.cruip.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open is another amazing and free React template for any developer who wants to quickly create a beautiful landing page for any type of project.&lt;/p&gt;

&lt;p&gt;Capture by the author from Open.&lt;br&gt;
The template has a very clean and professional design layout that makes you stand out. There are a lot of well-designed reusable components and elements you can benefit from when using this template.&lt;br&gt;
Advantages:&lt;br&gt;
Dark and minimal design layout.&lt;br&gt;
Fully responsive of course.&lt;br&gt;
Custom beautiful icons and elements.&lt;br&gt;
Good for SaaS products, online services, and open-source projects.&lt;br&gt;
You can also have look at a live demo(external link) if you want to see the full design layout.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Treact
&lt;a href="https://treact.owaiskhan.me/components/landingPages/RestaurantLandingPage"&gt;&lt;/a&gt;
Treact is an awesome gallery that comes with beautiful React UI templates and components that you can use for free to quickly build any type of project.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Capture by the author from Treact.&lt;br&gt;
Features:&lt;br&gt;
Fully Responsive.&lt;br&gt;
7 Landing Page Demos.&lt;br&gt;
Uses TailwindCSS.&lt;br&gt;
8 Inner Pages.&lt;br&gt;
A lot of well-designed components.&lt;br&gt;
Easy to install and customize.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Next-Portfolio-Dev
&lt;a href="https://dribbble.com/shots/17035515-Personal-Portfolio-Web-Landing-Page-Design"&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notus NextJS is a Free Tailwind CSS UI Kit And Admin. It's a great theme with nice colours, cool features and build tools to kickstart your project.&lt;/p&gt;

&lt;p&gt;Another open-source React Template to help you quickly build a basic developer portfolio website.&lt;br&gt;
&lt;a href="https://pickbazar-react.vercel.app/"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Capture by the author from GitHub.&lt;br&gt;
The template uses TypeScript and NextJS and you can customize it as you want. The code is clean and easy to understand. You can see more info on the GitHub repository.&lt;br&gt;
Features:&lt;br&gt;
Easy to install and customize.&lt;br&gt;
Simple clean design with nice illustrations.&lt;br&gt;
Fully responsive.&lt;br&gt;
Dark mode feature.&lt;br&gt;
PWA (for desktop &amp;amp; mobile).&lt;br&gt;
You can deploy it with one click.&lt;br&gt;
100% score on performance, accessibility, and SEO.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gatsby Starter Ghost&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://demo.jamify.org/"&gt;https://demo.jamify.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a very useful React template if you’re looking to easily create a blog or a publication website where you can share your thoughts and ideas.&lt;/p&gt;

&lt;p&gt;Capture by the author from Gatsby Starter Ghost(external link).&lt;br&gt;
The template allows you to easily build lightning-fast websites using Ghost and Gatsby. It’s a good starting point for content-driven sites.&lt;br&gt;
Features:&lt;br&gt;
Fully responsive.&lt;br&gt;
Blazing fast.&lt;br&gt;
Great for SEO.&lt;br&gt;
Clean blog post design and structure.&lt;br&gt;
Easy to install and deploy.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React Nice Resume
React Nice Resume is a simple and clean React template that you can use for portfolio websites. Whether you’re a developer, a designer, or a creator, this template is a good fit and starting point for you.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Capture by the author from React Nice Resume.&lt;br&gt;
&lt;a href="https://nordicgiant2.github.io/react-nice-resume-page/index.html"&gt;&lt;/a&gt;&lt;br&gt;
Features:&lt;br&gt;
Fully responsive.&lt;br&gt;
Nice animated background.&lt;br&gt;
Clean design.&lt;br&gt;
Smooth scrolling to sections.&lt;br&gt;
Easy to install and deploy.&lt;br&gt;
Conclusion&lt;br&gt;
So as you can see, this was a good list of useful React templates that you can use as a starting point and customize them the way you like. Starting with templates is a good way to help you build projects faster and boost your productivity. You don’t have to always start from scratch.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
      <category>react</category>
    </item>
    <item>
      <title>FREE React UI Libraries for Web developers</title>
      <dc:creator>Smilepk</dc:creator>
      <pubDate>Sun, 30 Jan 2022 19:53:11 +0000</pubDate>
      <link>https://forem.com/smilepk/free-react-ui-libraries-for-web-developers-15d0</link>
      <guid>https://forem.com/smilepk/free-react-ui-libraries-for-web-developers-15d0</guid>
      <description>&lt;p&gt;15 FREE React UI Libraries for Web developers&lt;/p&gt;

&lt;p&gt;1: NextUI&lt;br&gt;
2: Mantine&lt;br&gt;
3: Elastic UI&lt;br&gt;
4: Theme UI&lt;br&gt;
5: Chakra UI&lt;br&gt;
6: Material UI&lt;br&gt;
7: ReactStrap&lt;br&gt;
8: BlueprintJS&lt;br&gt;
9: Arco Design&lt;br&gt;
10: React Admin&lt;br&gt;
11: Shards React&lt;br&gt;
12: React Toolbox&lt;br&gt;
13: React Desktop&lt;br&gt;
14: React Bootstrap&lt;br&gt;
15: React Virtualized&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
      <category>react</category>
    </item>
    <item>
      <title>React Native uses native Components</title>
      <dc:creator>Smilepk</dc:creator>
      <pubDate>Fri, 28 Jan 2022 15:11:52 +0000</pubDate>
      <link>https://forem.com/smilepk/react-native-uses-native-components-871</link>
      <guid>https://forem.com/smilepk/react-native-uses-native-components-871</guid>
      <description>&lt;p&gt;What Is React Native?&lt;br&gt;
React Native is a well-known JavaScript-based app framework used for mobile apps and software development. It enables developers to develop natively generated apps for iOS and Android. You can develop a React Native-Based application for various platforms using the same codebase as the software development company. &lt;br&gt;
React Native is one such framework that is used for software development. It allows app development for multiple platforms with a single code base for iOS, Android, Windows with a single code base. React Native is one of the most known and highly used cross-platform for mobile app development &lt;/p&gt;

&lt;p&gt;To know the framework and understand the elements for an excellent react application, &lt;br&gt;
you need to go through the basic structure of a React Native, &lt;br&gt;
and some of the basic React concepts, like JSX, state, &lt;br&gt;
and more.&lt;/p&gt;

&lt;p&gt;What React Native Can Do&lt;br&gt;
It makes platform-specific versions to share code across platforms where it will be easy to share a code with a single codebase.&lt;br&gt;
Leveraging one team support for two platforms and conveying a standard technology.&lt;br&gt;
Why Use React Native for App Development?&lt;br&gt;
It is a cross-platform and very easy to develop the app.&lt;br&gt;
It is time and cost-effective over other frameworks.&lt;br&gt;
With React Native, complex features and app tasks are made easy to provide a more enhanced app user experience.&lt;br&gt;
You will get all answers from React Native community and libraries for seamless development.&lt;br&gt;
It serves a customized user experience to each user on the same application.&lt;br&gt;
With React Native, detecting bugs are easier as it uses a single codebase for Android and iOS.&lt;br&gt;
Top 7 React Native Components for Software Development&lt;br&gt;
When you decide to develop software with React Native, you must understand the components in React for app designing. As per the platform guidelines, React Native components are useful for developing a robust business app.&lt;/p&gt;

&lt;p&gt;Lets' look at some React Native components that every developer needs for robust app development.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React Native Elements
React Native as a cross-platform UI toolkit sets a few excellent open-source UI components at one location. Its elements are an execution of the material design system.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It includes a set of general-purpose UI components for application design and overall user experience. The most amazing thing with React Native elements is its themes, which can be changed in the runtime without reloading the application. So, a business can easily focus on logic and develop an attractive app with the visual appearance of your product.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Material Kit – React Native
Material Kit of React Native is completely coded with the app template. It is highly recommended to develop apps faster and effectively. It comes with over 200 variations of components such as inputs, buttons, cards, navigations, and more that offer you the freedom of choosing and combining.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All components can take variations in color, that you can easily modify inside our theme file.&lt;/p&gt;

&lt;p&gt;Benefits of React Native Material Kit&lt;br&gt;
Google Material Design&lt;br&gt;
Open-Source Fonts&lt;br&gt;
expo.io + iOS/Android&lt;br&gt;
Documentation&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React Native Bit
Bit is a React Native tool for component-driven app development that is used for quick app development. It is an extensible toolchain for systems that are easy to understand, test, maintain, and simple to collaborate on.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bit’s USP lies in letting developers to create components outside an application. Developers can then utilize them to compose as many applications as they want with the help of Bit component. Also, developers can alter the functionality of components in the app by adding or removing them from applications.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React Native Base
Native Base is easy to access, and our developers use it for an excellent app experience. It is available in the utility-first library that helps you develop a uniform design system across all platforms, including iOS, Android, and Web.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Theme ability is the element offered by React Native known as Native Base and is personalized as per your app theme and component styles.&lt;/p&gt;

&lt;p&gt;ARIA, powered by React Native, offers React hooks that allow developers to create accessible design systems in less time than other frameworks.&lt;/p&gt;

&lt;p&gt;Advantages of NativeBase&lt;br&gt;
Naturally Beautiful – Native Base crafts a beauty in an app that is inherited in itself, offering attractive components.&lt;br&gt;
Multi-Platform – It supports multiple platforms and is thus easy to develop. You can ask developers to customize app properties using platform-specific mounts.&lt;br&gt;
Accessible – NativeBase is easy to access and use and provides the box effect, including focus management and keyboard navigation.&lt;br&gt;
Customizable – As mentioned, it is a default theme used to add components in the app that are customized as per-app requirements.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vector Icons – React Native
Vector Icons is a known component of React that is Perfect for logos, buttons, and nav/tab bars. It is simple to extend, style, and incorporate into your app development.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;React Native with 3,000+ icons in the library helps you find components that fit your needs.&lt;/p&gt;

&lt;p&gt;Advantages of Vector Icons Component&lt;br&gt;
It is highly intuitive for designing buttons, logos, and nav/tab bars.&lt;br&gt;
Vector Icons will enable you to import icons faster.&lt;br&gt;
They are simple to extend, style, and integrate into your apps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React Native Ignite
Ignite is a well-known React Native boilerplate which is highly used for software development. React Native Ignite is a collection of Infinite Red’s thoughts on layout, patterns, and stack in one place.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As per the official React website, developers save their development time for around four weeks using React Native Ignite. Also, Ignite contains React Navigation 5, React Native, MobX-React-Lite, AsyncStorage, TypeScript, MobX-State-Tree and is Flipper-ready.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React Native Paper
React Native Paper, the last but not the least component of React, is a collection of customizable and production-ready components. If you plan for React Native mobile app development, hire developers who are experienced in React Native Paper as it helps you add interaction that suits almost every use-case design.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One can easily customize features like default colors or make your design with the help of this component. In addition, we utilize the theming support provided by React Native Paper along with the option to switch between dark and light modes.&lt;/p&gt;

&lt;p&gt;Advantages of React Native Paper&lt;br&gt;
It is a high-quality, standard-compliant material design library.&lt;br&gt;
It also covers all significant use-cases for app development.&lt;br&gt;
React Native Paper is free and open-source which makes it quickly available.&lt;br&gt;
Its fast, interface, responsive, and works reliably on both platforms.&lt;br&gt;
Conclusion&lt;br&gt;
These are some of the best available UI components of React Native that are highly important for your future software development. React Native with easily access libraries are simple to easy and its components are developers' choices for effective app development. React Native is an optimal choice when incorporated with the parts of native development with React and a best-in-class JavaScript library for building user interfaces.&lt;/p&gt;

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