<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thisura Thenuka</title>
    <description>The latest articles on DEV Community by Thisura Thenuka (@thisurathenuka).</description>
    <link>https://dev.to/thisurathenuka</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%2F285203%2Fa0f994ff-43ec-4f20-979f-3016c36e5393.png</url>
      <title>DEV Community: Thisura Thenuka</title>
      <link>https://dev.to/thisurathenuka</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thisurathenuka"/>
    <language>en</language>
    <item>
      <title>Demystifying CORS - Everything You Need to Know</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Wed, 01 Mar 2023 03:50:11 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/demystifying-cors-everything-you-need-to-know-4523</link>
      <guid>https://dev.to/thisurathenuka/demystifying-cors-everything-you-need-to-know-4523</guid>
      <description>&lt;p&gt;If you’re a web developer, chances are you’ve come across the pesky CORS error. But fear not! This article is here to help fellow developers understand and master the CORS policy. I’ll break it down for you in simple terms so you can tackle this error with ease. So, let’s jump right in and unravel the mysteries of CORS!&lt;/p&gt;

&lt;h1&gt;
  
  
  What is the Same-Origin Policy?
&lt;/h1&gt;

&lt;p&gt;The Same-Origin Policy is like a rule that web browsers follow to keep you safe on the internet.&lt;/p&gt;

&lt;p&gt;It says that if a web page from one website tries to do something on a different website, like read information or send data, the web browser won’t let it happen. It’s like a security guard that stops people from going where they’re not supposed to.&lt;/p&gt;

&lt;p&gt;This is important because it helps protect your personal information and keeps you safe from bad things on the internet. Imagine if anyone could read your emails or see your bank account information just by going to a website! The Same-Origin Policy helps prevent that from happening.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is CORS?
&lt;/h1&gt;

&lt;p&gt;Cross-Origin Resource Sharing or CORS is a way for web pages to ask permission from a different website to use its information.&lt;/p&gt;

&lt;p&gt;Let’s say you want to view some pictures on a website called “A”. But the pictures are stored on a different website called “B”. Normally, your web browser won’t show you the pictures because of the Same-Origin Policy.&lt;/p&gt;

&lt;p&gt;But with CORS, website “A” can send a special message called a “CORS request” to website “B”. This message asks website “B” if it’s okay for website “A” to see the pictures. If website “B” says it’s okay, then your web browser will show you the pictures from website “B” on website “A”.&lt;/p&gt;

&lt;p&gt;CORS helps web pages work together and share information safely, like when you share your toys with your friends. It’s important because it allows websites to work together and show you the information you want to see.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are preflight requests?
&lt;/h1&gt;

&lt;p&gt;Preflight requests are like asking for permission before doing something.&lt;/p&gt;

&lt;p&gt;Let’s say a website wants to share information with another website using CORS, but the information is sensitive and needs extra protection. The website will send a special message called a “preflight request” before sending the actual message.&lt;/p&gt;

&lt;p&gt;The preflight request asks the other website if it’s okay to send sensitive information. It’s like asking your parents if it’s okay to go to a friend’s house for a sleepover.&lt;/p&gt;

&lt;p&gt;The other website will then send a message back saying if it’s okay to send the information or not. If it’s okay, the original website will send the sensitive information, but if it’s not okay, the information won’t be sent.&lt;/p&gt;

&lt;p&gt;Preflight requests help keep your information safe on the internet by making sure that websites only send and receive information when it’s safe to do so. It’s like checking with your parents before doing something that might be dangerous.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are CORS headers?
&lt;/h1&gt;

&lt;p&gt;CORS headers are messages that websites use to talk to each other and decide if it’s safe to share information. Different kinds of CORS headers have different jobs, just like how different tools have different jobs in a toolbox.&lt;/p&gt;

&lt;p&gt;Here are a few examples of different CORS headers and what they do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Access-Control-Allow-Origin: This CORS header tells your web browser which websites are allowed to see the information. It’s like telling your friends which toys they can play with.
 
&lt;/li&gt;
&lt;li&gt;Access-Control-Allow-Methods: This CORS header tells your web browser which kinds of actions it can take with the information, like reading or editing. It’s like telling your friends which games they can play with the toys.
 
&lt;/li&gt;
&lt;li&gt;Access-Control-Allow-Credentials: This CORS header tells your web browser if it’s okay to send personal information, like passwords. It’s like telling your friends if it’s okay to come into your room or not.
 
&lt;/li&gt;
&lt;li&gt;Access-Control-Allow-Headers: This CORS header tells your web browser which kinds of information it can share, like text or pictures. It’s like telling your friends what kind of snacks they can have.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By using these different CORS headers, websites can make sure that they’re only sharing information that’s safe to share, and keeping your personal information secure. It’s like making sure that only your trusted friends can come over to play, and that they know the rules for playing with your toys.&lt;/p&gt;

&lt;h1&gt;
  
  
  How do I handle CORS errors?
&lt;/h1&gt;

&lt;p&gt;Picture this — you’re on a website and you spot some juicy information on another website that you’d love to get your hands on. But before you can access it, your browser needs to ask for permission. It sends a preflight request to check if the other website will let you use its resources. If the answer is no, you’ll encounter the dreaded CORS error, blocking your request.&lt;/p&gt;

&lt;p&gt;There are a few different types of CORS errors, but they all mean the same thing: you can’t access the information or resources you want. Here are the most common CORS errors that you will encounter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access-Control-Allow-Origin: This error means that the website you’re trying to access doesn’t allow other websites to use its resources.
 
&lt;/li&gt;
&lt;li&gt;Access-Control-Allow-Headers: This error means that the website you’re trying to access doesn’t allow you to use certain headers in your request.
 
&lt;/li&gt;
&lt;li&gt;Access-Control-Allow-Methods: This error means that the website you’re trying to access doesn’t allow you to use certain methods, like GET or POST, to access its resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you run into a CORS error, don’t worry! There are ways to handle it. One way is to contact the owner of the website you’re trying to access and ask them to allow other websites to use its resources. Another way is to use a proxy server, which acts as a middleman between you and the website you’re trying to access.&lt;/p&gt;

&lt;p&gt;If you’d like to read more about all the different CORS errors, you can refer to the MDN Docs article from &lt;a href="[https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors)"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are the CORS Best Practices?
&lt;/h1&gt;

&lt;p&gt;To ensure your website is secure and functional, it’s important to follow some best practices when working with CORS.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Include the necessary CORS headers in your server’s response: When a browser makes a cross-origin request, the server being accessed must include specific response headers to permit the request. Make sure your server includes the appropriate CORS headers such as Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers.
 
&lt;/li&gt;
&lt;li&gt;Only allow access to necessary resources: To minimize the risk of unauthorized access, only allow cross-origin access to necessary resources. Avoid allowing access to sensitive information or resources unless it’s required.
 
&lt;/li&gt;
&lt;li&gt;Use SSL/TLS encryption: Use SSL/TLS encryption to ensure that any data being transmitted is secure. This can help prevent unauthorized interception of data.
 
&lt;/li&gt;
&lt;li&gt;Set appropriate CORS configuration: Set up CORS configuration based on your website’s requirements. For example, if your website has a public API that should be accessible to third-party websites, set up CORS to allow cross-origin requests from those specific domains.
 
&lt;/li&gt;
&lt;li&gt;Monitor CORS requests: Monitor cross-origin requests to your website to identify any unusual or potentially malicious activity. Implement logging and monitoring tools to detect any unauthorized access attempts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By following these best practices, you can help ensure that your website is secure and functional while allowing cross-origin requests as needed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Understanding and being able to handle the Cross-Origin Resource Sharing (CORS) policy is crucial for every web developer. During my early days in web development, I had to face the dreadful CORS error which led me to waste so much time trying out numerous solutions from Stack Overflow without truly comprehending the concept. But, now that I have gained ample knowledge about CORS, I can confidently say that you don’t have to suffer the same fate as I did. So, take the time to understand CORS and save yourself from the hassle of going through a maze of solutions.&lt;/p&gt;

&lt;p&gt;Thank you so much for taking the time to read my article! My utmost priority was to simplify complex concepts, and I hope I’ve achieved that. If you found my article informative and useful, please drop a comment below and don’t forget to follow me for more articles like this. Oh, and spread the word by sharing it with your friends and colleagues, they might thank you for it!&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Demystifying DNS - Everything You Need to Know</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Mon, 27 Feb 2023 10:34:04 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/demystifying-dns-everything-you-need-to-know-nfc</link>
      <guid>https://dev.to/thisurathenuka/demystifying-dns-everything-you-need-to-know-nfc</guid>
      <description>&lt;p&gt;The article’s objective is to cover all the key information about the Domain Name System (DNS). Everyone interested in learning more about DNS should read this article. I will try to explain what you need to know in layman’s terms. Without further ado, let’s get into it.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is DNS and why is it important?
&lt;/h1&gt;

&lt;p&gt;DNS is like a big phone book for the internet. You know how you have a phone book at home with all your friends’ phone numbers and addresses? Well, DNS is like that, but for websites.&lt;/p&gt;

&lt;p&gt;When you want to go to a website, you type in the website’s name, like “&lt;a href="%5Bhttp://google.com%5D(http://google.com)"&gt;google.com&lt;/a&gt;". DNS takes that name and looks it up in the phone book to find the website’s “phone number”, which is called an IP address. Then, DNS tells your computer the IP address, and your computer uses that to find the website and show it to you.&lt;/p&gt;

&lt;p&gt;DNS is essential because it helps us find websites easily and quickly, without having to remember a bunch of numbers. It’s like having an astute helper who knows where all the websites are and how to get to them!&lt;/p&gt;

&lt;h1&gt;
  
  
  What is the hierarchy of DNS?
&lt;/h1&gt;

&lt;p&gt;Remember how I explained that DNS is like a big phone book for the internet? Well, it’s not just one big phone book. It’s actually lots of phone books, all working together in a big chain.&lt;/p&gt;

&lt;p&gt;At the very top of the chain is something called the “root” server. This server lists all the top-level domains (TLDs), like .com, .org, .net, and so on.&lt;/p&gt;

&lt;p&gt;When you type in a website name, like “&lt;a href="%5Bhttp://google.com%5D(http://google.com)"&gt;google.com&lt;/a&gt;", your computer goes to the next level of the chain, which is the server for the “.com” top-level domain. That server has a list of all the websites that end in “.com”, and it can tell your computer where to find “&lt;a href="%5Bhttp://google.com%5D(http://google.com)"&gt;google.com&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;Then, your computer goes to the next level of the chain, which is the server for “&lt;a href="%5Bhttp://google.com%5D(http://google.com)"&gt;google.com&lt;/a&gt;". That server has a list of all the pages on the Google website, and it can tell your computer where to find the page you’re looking for.&lt;/p&gt;

&lt;p&gt;This chain of servers is called the “DNS hierarchy”, and it helps your computer find the right website quickly and easily. It’s like a big team of helpers, each one passing along the information to the next one until you get to where you want to go.&lt;/p&gt;

&lt;p&gt;Here is a simple diagram of the DNS hierarchy for you to get an idea.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tPEM57hf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbeihp8k4t1005wi5kcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tPEM57hf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbeihp8k4t1005wi5kcu.png" alt="dns-heirarchy" width="466" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, that’s how DNS hierarchy works! It’s a big chain of servers, each one responsible for a different part of the internet phone book, all working together to help us find websites.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are the DNS server types?
&lt;/h1&gt;

&lt;p&gt;DNS servers are like special computers that help to make the internet work. There are two main types of DNS servers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;authoritative DNS servers
&lt;/li&gt;
&lt;li&gt;recursive DNS servers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An authoritative DNS server is like a phone book for the internet. It stores information about domain names and their corresponding IP addresses. When someone wants to visit a website, their computer asks the authoritative DNS server for the IP address that corresponds to the domain name they’re trying to visit.&lt;/p&gt;

&lt;p&gt;A recursive DNS server is like a helper for your computer. When your computer wants to visit a website, it asks the recursive DNS server for the IP address that corresponds to the domain name. The recursive DNS server then goes and asks the authoritative DNS server for the information. Once it gets the information, it sends it back to your computer, which can then connect to the website.&lt;/p&gt;

&lt;p&gt;Recursive DNS servers are important because they can help to speed up your internet experience. They store information about domain names and their corresponding IP addresses in a special cache so that they can quickly give you the information you need without having to go all the way to the authoritative DNS server every time.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are DNS records?
&lt;/h1&gt;

&lt;p&gt;DNS records are like little notes that tell your computer where to find a website. They are a part of the DNS system, which helps your computer find the right website when you type in a name like “&lt;a href="%5Bhttp://google.com%5D(http://google.com)"&gt;google.com&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;There are different types of DNS records, each one with a different job. Here are some of the most common ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A (Address) record: This is the most important DNS record because it tells your computer the IP address of the web server hosting a website. When you type in a website name like “&lt;a href="%5Bhttp://google.com%5D(http://google.com)"&gt;google.com&lt;/a&gt;", your computer looks up the A record for that domain name to find the IP address of the web server.
 
&lt;/li&gt;
&lt;li&gt;CNAME (Canonical Name) record: This record is like a shortcut. It tells your computer to look up the IP address for one domain name, but use the website content from another domain name. For example, the CNAME record for “test.google.com” might tell your computer to use the website content from “&lt;a href="%5Bhttp://google.com%5D(http://google.com)"&gt;google.com&lt;/a&gt;". This record is usually used in place of an A record. All CNAME records always point to a domain, not an IP address.
 
&lt;/li&gt;
&lt;li&gt;MX (Mail Exchange) record: This record tells your computer where to send an email for a domain name. It’s used by email servers to find the correct destination for incoming email messages.
 
&lt;/li&gt;
&lt;li&gt;TXT (Text) record: This record is like a note that can contain any kind of text information. It’s often used to provide additional information about a domain name, such as ownership or security details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are just a few examples of the types of DNS records that exist. Each one has a specific job to help your computer find the right website or send an email to the right place. DNS records are like little helpers that work together to make sure everything on the internet runs smoothly!&lt;/p&gt;

&lt;h1&gt;
  
  
  What is DNS propagation and caching?
&lt;/h1&gt;

&lt;p&gt;When you type in a website name like “&lt;a href="%5Bhttp://google.com%5D(http://google.com)"&gt;google.com&lt;/a&gt;", your computer uses the DNS system to find the IP address of the web server hosting that website. But did you know that the DNS system can take some time to update with new information?&lt;/p&gt;

&lt;p&gt;This is because of something called DNS propagation. When a change is made to the DNS records for a domain name, it can take some time for that change to be propagated, or spread out, to all of the DNS servers around the world. This means that some people might still see the old information for a little while, even after a change has been made.&lt;/p&gt;

&lt;p&gt;Another thing to know about DNS is that your computer doesn’t always look up the DNS information from scratch every time you visit a website. Instead, it stores the information in a cache or a temporary storage area, so it can access it more quickly the next time you visit that website.&lt;/p&gt;

&lt;p&gt;DNS caching is helpful because it makes your internet experience faster and smoother. Your computer doesn’t have to spend time looking up the DNS information every time you visit a website. Instead, it can use the information it already has stored in the cache.&lt;/p&gt;

&lt;p&gt;However, DNS caching can also cause problems when changes are made to DNS records. Because your computer is using the cached information, it might not see the updated information right away. This is another reason why DNS propagation can take some time. You can &lt;a href="%5Bhttps://www.keycdn.com/support/dns-cache%5D(https://www.keycdn.com/support/dns-cache)"&gt;flush DNS cache&lt;/a&gt; to get rid of this issue.&lt;/p&gt;

&lt;p&gt;So, DNS propagation and caching are two things that affect how quickly and accurately your computer can find the websites you’re looking for. Sometimes it might take a little bit of time for everything to update, but don’t worry — your computer and the DNS system are always working hard to make sure you can access the internet quickly and easily!&lt;/p&gt;

&lt;h1&gt;
  
  
  What are DNS security and DNSSEC?
&lt;/h1&gt;

&lt;p&gt;DNS security is important because it helps to make sure that the DNS system is working correctly and that you’re truly connecting to the website you think you are. Someone could try to trick the DNS system, either by changing the DNS records for a website or by creating a fake website that looks like the real one.&lt;/p&gt;

&lt;p&gt;One way that DNS security is improved is through something called DNSSEC. This is a system that adds extra security information to the DNS records for a website. When your computer looks up the DNS information for a website that has DNSSEC, it can check the security information to make sure that the information it’s getting is really from the website it thinks it is.&lt;/p&gt;

&lt;p&gt;DNSSEC works by adding a digital signature to the DNS records for a website. This signature is like a special code that proves that the information is real and hasn’t been tampered with. Your computer can check the signature to make sure that it’s connecting to the real website and not a fake one.&lt;/p&gt;

&lt;p&gt;DNSSEC is a very important part of DNS security because it helps to protect against attacks that try to trick the DNS system. With DNSSEC, you can be more confident that the websites you’re visiting are the ones you intend to visit, and that your internet experience is secure and trustworthy.&lt;/p&gt;

&lt;h1&gt;
  
  
  How does DNS load balancing work?
&lt;/h1&gt;

&lt;p&gt;Sometimes, when lots of people want to visit a website, the server that hosts that website can get overwhelmed and stop working properly. This can make the website slow or even cause it to crash! To prevent this from happening, website owners can use something called DNS load balancing.&lt;/p&gt;

&lt;p&gt;DNS load balancing is when a website owner sets up multiple servers to host their website. When someone tries to visit the website, the DNS system can choose which server to send them to. This helps spread out the traffic and prevent any server from getting too overwhelmed.&lt;/p&gt;

&lt;p&gt;One way that the DNS system can choose which server to send someone to is by using something called &lt;strong&gt;round-robin DNS&lt;/strong&gt;. Round-robin DNS is when the DNS system rotates through a list of IP addresses for the different servers. So, if three servers are hosting a website, the DNS system might send the first person who tries to visit the website to the first server, then send the second person to the second server, and so on.&lt;/p&gt;

&lt;p&gt;Round-robin DNS is a simple and effective way to do DNS load balancing. By spreading out the traffic among multiple servers, website owners can ensure that their website stays fast and responsive, even when lots of people are trying to visit it simultaneously.&lt;/p&gt;

&lt;h1&gt;
  
  
  How do I troubleshoot DNS?
&lt;/h1&gt;

&lt;p&gt;Sometimes, things can go wrong with DNS servers. When this happens, you can use the following checklist of troubleshooting techniques to use to figure out what’s going on.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check your internet connection: Before you do anything else, make sure that your internet connection is working properly. If your internet connection is down, you won’t be able to access any websites, no matter what you do!
 
&lt;/li&gt;
&lt;li&gt;Try a different device: If you’re having trouble accessing a website on one device, try accessing it on a different device. This can help you figure out whether the problem is with the website or with your device.
 
&lt;/li&gt;
&lt;li&gt;Check your DNS settings: Make sure that your device is set up to use the correct DNS servers. If you’re not sure what the correct DNS servers are, you can try using Google’s DNS servers (8.8.8.8 and 8.8.4.4).
 
&lt;/li&gt;
&lt;li&gt;Clear your DNS cache: Sometimes, your device’s DNS cache can get corrupted. When this happens, you might not be able to access certain websites. To fix this, you can try clearing your device’s DNS cache.
 
&lt;/li&gt;
&lt;li&gt;Check the website’s DNS records: If you’re having trouble accessing a particular website, it could be because there’s something wrong with the website’s DNS records. You can use a special tool called a DNS lookup tool to check the website’s DNS records and see if there are any problems.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In conclusion, DNS is a critical component of the internet infrastructure that enables us to access websites and services by their domain names. Understanding the hierarchy of DNS, different types of DNS servers, DNS records, and DNS security can help us manage and troubleshoot DNS effectively. Additionally, learning about DNS propagation, caching, and load balancing can improve website performance and availability.&lt;/p&gt;

&lt;p&gt;Finally, thank you for taking the time to read my article. I tried my best to break the concepts down into simple terms. If you found my article helpful, please make to share it with your friends and colleagues.&lt;/p&gt;

</description>
      <category>dns</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Add Redux to your React app in 6 Simple Steps</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Sat, 20 Aug 2022 12:24:00 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/add-redux-to-your-react-app-in-6-simple-steps-43bb</link>
      <guid>https://dev.to/thisurathenuka/add-redux-to-your-react-app-in-6-simple-steps-43bb</guid>
      <description>&lt;p&gt;Redux is a predictable state container for JavaScript apps. &lt;/p&gt;

&lt;h1&gt;
  
  
  Do I need to use Redux in my React app?
&lt;/h1&gt;

&lt;p&gt;It depends.&lt;/p&gt;

&lt;p&gt;If your app is simple and works with a minimal number of states, there is no need to add redux to your app.&lt;/p&gt;

&lt;p&gt;If your app is complex and has a lot of stuff going on, you should consider adding redux to your app. It will provide a clean and simple structure to handle states and improve the longevity of the code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Redux vs useContext and useReducer
&lt;/h1&gt;

&lt;p&gt;By utilizing React's useContext and useReducer hooks, we can provide the same functionality as Redux. The boilerplate code is significantly less, and it is much simpler.&lt;/p&gt;

&lt;p&gt;But it's crucial that you understand how Redux functions because most software companies already use it in their projects, and it will undoubtedly help you in your next interview.&lt;/p&gt;

&lt;h1&gt;
  
  
  Redux Basic Concepts
&lt;/h1&gt;

&lt;p&gt;There are a few simple concepts you should understand before adding redux to your react app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Store
&lt;/h2&gt;

&lt;p&gt;The Redux Store holds the state of your app. Your app is always subscribed to the store. But your app can't &lt;strong&gt;directly&lt;/strong&gt; change the state in the store.&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%2Fg8yhym0je6stv394hnlc.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%2Fg8yhym0je6stv394hnlc.png" alt="Redux Store"&gt;&lt;/a&gt;&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%2Fmnce0z49cf5m0i204pk6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmnce0z49cf5m0i204pk6.gif" alt="what-say-you"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where actions and action creators come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Action Types, Actions and Action Creators
&lt;/h2&gt;

&lt;p&gt;Action types are constants that are used to define the values used for the type property of Actions.&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ADD_TASK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ADD_TASK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;An action is any object with a &lt;strong&gt;type&lt;/strong&gt; property. Actions help us describe what needs to happen.&lt;/p&gt;

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

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ADD_TASK&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;An action creator is simply a JS function that returns an action.&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addTask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ADD_TASK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The only thing your app can do is to "&lt;strong&gt;dispatch&lt;/strong&gt;" actions. Dispatch is a method provided by the react-redux library's &lt;code&gt;useDispatch&lt;/code&gt; hook. I'll get into this later when we implement the code.&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%2Fy5ctayt33uzx23u2n1ow.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%2Fy5ctayt33uzx23u2n1ow.png" alt="redux actions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your app can change the state in the Redux store by dispatching actions. &lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://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%2Fcrxun0x2d77gs6oevanf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcrxun0x2d77gs6oevanf.gif" alt="how-is-that-possible"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An action only describes what needs to happen. It doesn't describe how we want the states to change. We need to use a reducer for this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reducer
&lt;/h2&gt;

&lt;p&gt;A reducer is a JS function that takes in &lt;code&gt;initialState&lt;/code&gt; and &lt;code&gt;action&lt;/code&gt; as input and returns an updated state object.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="na"&gt;taskTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;taskDescription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskReducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="na"&gt;ADD_TASK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;taskTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;taskDescription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;When an action is dispatched, the relevant reducer will update the state according to the action.&lt;/p&gt;

&lt;p&gt;When we create the Redux store, we feed all the reducers to the store. So, the reducers can update the state in the store which is what we want.&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%2Fwmtcmgpwjmvsm731wp10.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%2Fwmtcmgpwjmvsm731wp10.png" alt="Redux Cycle"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Feeling Overwhelmed?
&lt;/h1&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%2Fy39mxkzkzof8lb4ye1sl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy39mxkzkzof8lb4ye1sl.gif" alt="complex"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I completely understand if you feel swamped, especially if you are only now becoming familiar with these ideas. Have no fear; I've been there. When we begin writing the code, you will have a better understanding of it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Adding Redux to your React App
&lt;/h1&gt;

&lt;p&gt;Redux will be used to manage states in my simple to-do app, which will allow users to add tasks. I'm simply doing this as a demonstration; a basic app like this doesn't need redux.&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%2Fvfo07z70ygt0t1n7hnyi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfo07z70ygt0t1n7hnyi.gif" alt="To-Do App"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 - Installing required libraries
&lt;/h2&gt;

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

&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="nx"&gt;redux&lt;/span&gt; &lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;redux&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;reduxjs&lt;/span&gt;&lt;span class="sr"&gt;/toolki&lt;/span&gt;&lt;span class="err"&gt;t
&lt;/span&gt;

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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 2 - Create Actions, Action Types and Action Creators
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;taskActionTypes.js&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ADD_TASK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ADD_TASK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_TASK_TITLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPDATE_TASK_TITLE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_TASK_DESCRIPTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPDATE_TASK_DESCRIPTION&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;taskActions.js&lt;/strong&gt;&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ADD_TASK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_TASK_DESCRIPTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_TASK_TITLE&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./taskActionTypes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addTask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ADD_TASK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateTaskTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_TASK_TITLE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateTaskDescription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_TASK_DESCRIPTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;When we are passing values to action creators, the convention is to call that attribute "&lt;strong&gt;payload&lt;/strong&gt;".&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 - Create Reducer(s)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;taskReducer.js&lt;/strong&gt;&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ADD_TASK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_TASK_DESCRIPTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_TASK_TITLE&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./taskActionTypes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="na"&gt;taskTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;taskDescription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskReducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="na"&gt;ADD_TASK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="na"&gt;taskTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;taskDescription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="na"&gt;UPDATE_TASK_TITLE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;taskTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="na"&gt;UPDATE_TASK_DESCRIPTION&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;taskDescription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;taskReducer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;In this case, we only need the taskReducer. But in a complex app, there will be multiple reducers to handle different states. In that case, the convention is to create a reducer called "&lt;strong&gt;rootReducer&lt;/strong&gt;" by combining all the other reducers and feeding that reducer to the store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;rootReducer.js&lt;/strong&gt;&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;combineReducers&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;taskReducer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./tasks/taskReducer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootReducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;combineReducers&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;taskReducer&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;rootReducer&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 4 - Create the Store
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;configureStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@reduxjs/toolkit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;rootReducer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./rootReducer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;rootReducer&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

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


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 5 - Wrap the Root Component with Provider
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;index.js&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom/client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./redux/store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StrictMode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Provider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/React.StrictMode&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 6 - useDispatch() and useSelector()
&lt;/h2&gt;

&lt;p&gt;You can use useSelector() to access the states in the Redux store.&lt;/p&gt;

&lt;p&gt;You can use useDispatch() to access the dispatch method which helps you to dispatch actions&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;useDispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateTaskDescription&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateTaskTitle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../redux/tasks/taskActions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;taskContainer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;350px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;mainContainer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-webkit-center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;AddTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDispatch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taskTitle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskDescription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taskDescription&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onAddTask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;taskTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;taskDescription&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onTaskTitleChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;updateTaskTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onTaskDescriptionChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;updateTaskDescription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainContainer&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taskContainer&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Task Title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onTaskTitleChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;taskTitle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Task Description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onTaskDescriptionChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                       &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;taskDescription&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onAddTask&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Add&lt;/span&gt; &lt;span class="nx"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;AddTasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;That's about it. We successfully added Redux to a React app. &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%2Fmy27ff60yreib4cdf1ga.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmy27ff60yreib4cdf1ga.gif" alt="dance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to look into the code and try in out for yourself, here is the Code Sandbox version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io/embed/divine-platform-43jj6l?fontsize=14&amp;amp;hidenavigation=1&amp;amp;theme=dark" rel="noopener noreferrer"&gt;https://codesandbox.io/embed/divine-platform-43jj6l?fontsize=14&amp;amp;hidenavigation=1&amp;amp;theme=dark&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;At first glance, adding Redux to your React app could appear difficult. But it gets a lot simpler when we take each concept in turn and develop the logic on our own.&lt;/p&gt;

&lt;p&gt;I am still trying to learn these concepts on my own. Please feel free to bring up any gaps in my reasoning and the problems you encounter.&lt;/p&gt;

&lt;p&gt;Thank you for reading my article. If you learned something new, please make sure to drop a like and share the article among your fellow developers 🥳&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>redux</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Make Errors User-Friendly with React Error Boundaries</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Sat, 13 Aug 2022 16:13:00 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/make-errors-user-friendly-with-react-error-boundaries-9e7</link>
      <guid>https://dev.to/thisurathenuka/make-errors-user-friendly-with-react-error-boundaries-9e7</guid>
      <description>&lt;h1&gt;
  
  
  What are Error Boundaries ?
&lt;/h1&gt;

&lt;p&gt;React Error Boundaries are used to show a user-friendly UI to users when unexpected JavaScript errors occur.&lt;/p&gt;

&lt;p&gt;A JavaScript error in a part of the UI usually renders a white screen and crashes the entire app. React Version 16 introduced a solution to this issue with the new “Error Boundary” concept.&lt;/p&gt;

&lt;h1&gt;
  
  
  How can I implement Error Boundaries ?
&lt;/h1&gt;

&lt;p&gt;You can implement React Error Boundaries in your React app in 2 simple steps&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an error boundary component&lt;/li&gt;
&lt;li&gt;Wrap error-prone component with error boundary component&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating Error Boundary Component
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;A class component becomes an error boundary if it defines either (or both) of the lifecycle methods &lt;code&gt;static getDerivedStateFromError()&lt;/code&gt; or &lt;code&gt;componentDidCatch()&lt;/code&gt;. Use &lt;code&gt;static getDerivedStateFromError()&lt;/code&gt; to render a fallback UI after an error has been thrown. Use &lt;code&gt;componentDidCatch()&lt;/code&gt; to log error information. (&lt;a href="https://reactjs.org/docs/error-boundaries.html" rel="noopener noreferrer"&gt;https://reactjs.org/docs/error-boundaries.html&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is the example error boundary component provided in the React documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;errorInfo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;componentDidCatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errorInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Catch errors in any components below and re-render with error message&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;errorInfo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;errorInfo&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="c1"&gt;// You can also log error messages to an error reporting service here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errorInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Error path&lt;/span&gt;
        &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Something&lt;/span&gt; &lt;span class="nx"&gt;went&lt;/span&gt; &lt;span class="nx"&gt;wrong&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;details&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;whiteSpace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pre-wrap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errorInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;componentStack&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/details&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="c1"&gt;// Normally, just render children&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;You can create your own error boundary with a fancier UI according to your use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping with Error Boundary
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/GA1s4aZhfe5f2N3fFb/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/GA1s4aZhfe5f2N3fFb/giphy.gif" alt="wrapping-with-error-boundary"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two ways you could wrap components with the error boundary&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can wrap the top-level component&lt;/li&gt;
&lt;li&gt;You can wrap individual components&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Wrapping Top-Level Component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ErrorBoundary&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&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%2Fqv6xn7ct73ialmg4oywm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqv6xn7ct73ialmg4oywm.gif" alt="error-boundaries-for-root"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping Individual Components
&lt;/h3&gt;

&lt;p&gt;This approach would be ideal if your app has multiple different isolated sections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BankingController&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ErrorBoundary&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ProfileController&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ErrorBoundary&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PolicyController&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ErrorBoundary&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An error occurred in BankingController would not stop user from using the PolicyController or ProfileController.&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%2Fxx3ep9el45tcl6uvzsub.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxx3ep9el45tcl6uvzsub.gif" alt="error-boundaries-for-individual"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  So, Is my React app “white screen”-free now?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l3q2K5jinAlChoCLS/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l3q2K5jinAlChoCLS/giphy.gif" alt="wow-image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, React error boundaries can catch all errors except for the following :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Event Handlers&lt;/li&gt;
&lt;li&gt;Asynchronous code&lt;/li&gt;
&lt;li&gt;Server Side Rendering&lt;/li&gt;
&lt;li&gt;Errors thrown in the error boundary itself&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But you can always make use of regular JavaScript try/catch blocks whenever needed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As of React 16, errors that were not caught by any error boundary will result in unmounting of the whole React component tree&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;React error boundaries provide a way for developers to make our apps more user-friendly. In my opinion, every React app should make use of React error boundaries and it makes a drastic difference in the user experience.&lt;/p&gt;

&lt;p&gt;Thank you for taking the time to read my article. Hope you enjoyed it. If you learned something new, make sure to drop a like and share the article with your fellow developers. &lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Write Our Own Custom Hooks in React</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Sun, 26 Jun 2022 11:19:58 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/how-to-write-our-own-custom-hooks-in-react-1b1e</link>
      <guid>https://dev.to/thisurathenuka/how-to-write-our-own-custom-hooks-in-react-1b1e</guid>
      <description>&lt;p&gt;To make life simpler for developers, React has introduced a wide variety of hooks. In addition, React allows us to build our own custom hooks.&lt;/p&gt;

&lt;p&gt;Today, I will explain how we can create and use React custom hooks.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are Custom Hooks in React?
&lt;/h1&gt;

&lt;p&gt;React custom hooks are a way to extract component logic into reusable functions. There is one convention you should know about before writing our own React hooks&lt;/p&gt;

&lt;h2&gt;
  
  
  "use" in front of the custom hook
&lt;/h2&gt;

&lt;p&gt;React advises us to only use React hooks inside React functional components or custom hooks. React advises us not to use React hooks inside regular JS functions. The thought process behind this is that if we use React hooks inside normal JS functions, there is a chance for them to get "hidden" inside the call stack. Especially in a large codebase, it would be impossible to go through each and every function to see where React hooks have been used.&lt;/p&gt;

&lt;p&gt;The thought process is the same in this case as well. It would be simpler for us to determine where React hooks have been used if we prefixed our custom hook names with "use".&lt;/p&gt;

&lt;p&gt;So, the name of your custom hook should look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useMyCustomHook()
useOnlineStatus()
useCommentFilter()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  How to write React Custom Hooks?
&lt;/h1&gt;

&lt;p&gt;I've created a simple React hook to check if a given player is retired or not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useRetiredStatus.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useRetiredStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isRetired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsRetired&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Assumption: The age of retirement for cricket is 40 yrs&lt;/span&gt;
        &lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;setIsRetired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;setIsRetired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;isRetired&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;App.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useRetiredStatus&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./useRetiredStatus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;players&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Kumar Sangakkara&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Angelo Mathews&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rohit Sharma&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mahela Jayawardene&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;David Miller &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPlayer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;players&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;retiredStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRetiredStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`Dear Cricket Fans, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;retiredStatus&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;retired&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;still playing the game&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



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

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--St958787--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8pe28rdy8zw3wkq1nwwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--St958787--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8pe28rdy8zw3wkq1nwwe.png" alt="Output" width="412" height="38"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With React Custom Hooks, there are no limitations. We can change input and output variables into anything we want just like in a regular function. With this knowledge, you will be able to create custom hooks for all the unique requirements in your projects.&lt;/p&gt;

&lt;h1&gt;
  
  
  Can't I just use a JS function, instead of creating a custom hook?
&lt;/h1&gt;

&lt;p&gt;You can use a JS function if your code does not make use of React hooks. &lt;/p&gt;

&lt;p&gt;If the code contains React hooks, you should create a custom hook so that your code aligns with &lt;a href="https://reactjs.org/docs/hooks-rules.html"&gt;React's rules of hooks&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Learning how to make use of React custom hooks will make your code look more cleaner and more readable. I hope you will be able to implement React custom hooks in your next project.&lt;/p&gt;

&lt;p&gt;Thank you for reading the article. Hope you learned something valuable today. Until next time, take care guys.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Promises - JavaScript Concepts Simplified</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Sat, 12 Feb 2022 14:58:03 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/promises-javascript-concepts-simplified-in2</link>
      <guid>https://dev.to/thisurathenuka/promises-javascript-concepts-simplified-in2</guid>
      <description>&lt;h2&gt;
  
  
  What is a Promise?
&lt;/h2&gt;

&lt;p&gt;By definition, a promise is a declaration that one will do something or that a particular thing will happen. In the programming world, a promise is an object that represents the eventual completion (or failure) of an asynchronous operation. &lt;/p&gt;

&lt;h2&gt;
  
  
  States
&lt;/h2&gt;

&lt;p&gt;A promise can have the following states.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pending (Initial State, neither fulfilled nor rejected)&lt;/li&gt;
&lt;li&gt;Fulfilled (The operation was a success)&lt;/li&gt;
&lt;li&gt;Rejected (The operation was a failure)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A pending promise can either be fulfilled or rejected. We can attach handler methods to handle the events of promises getting &lt;code&gt;fulfilled&lt;/code&gt; and &lt;code&gt;rejected&lt;/code&gt;. We can use the then method in promises to attach these handlers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;promise.then(handleSuccess, handleRejection)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have attached two handler methods to the above promise. Now, if the promise gets fulfilled, &lt;code&gt;handleSuccess&lt;/code&gt; will be called and if it gets rejected, the &lt;code&gt;handleRejection&lt;/code&gt; method will be called.&lt;/p&gt;

&lt;p&gt;When a promise is not in the pending state, we say the promise is settled. Please keep in mind that being settled is merely a linguistic convenience, not a state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods
&lt;/h2&gt;

&lt;p&gt;In addition, promise objects have multiple methods that can be really useful when handling promises.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Promise.all()
&lt;/h2&gt;

&lt;p&gt;Input - An iterable of promises&lt;br&gt;
Output - A single promise that resolves into an array of the results of the input promises&lt;/p&gt;

&lt;p&gt;This method is useful when you have more than one promise and you want to do something only when all the operations are completed successfully. &lt;code&gt;Promise.all()&lt;/code&gt; will reject immediately upon any of the input promises rejecting. For example, if you want to make multiple API calls and the code relies on all of them to be successful, you can use &lt;code&gt;Promise.all()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const firstPromise = new Promise((resolve, reject) =&amp;gt; {
  setTimeout(resolve, 300, "First Promise");
});

const secondPromise = new Promise((resolve, reject) =&amp;gt; {
  setTimeout(resolve, 100, "Second Promise");
});

const thirdPromise = new Promise((resolve, reject) =&amp;gt; {
  setTimeout(resolve, 1000, "Third Promise");
});

const rejectedPromise = Promise.reject("EVERYBODY STAY CALM. STAY F***ING CALM. I WAS REJECTED");

//Promise.all() method
Promise.all([firstPromise, secondPromise, thirdPromise])
  .then((results) =&amp;gt; {
    console.log("All the promises were fulfilled here - ", results);
  })
  .catch((error) =&amp;gt; {
    console.error("Error: ", error);
  });

//Promise.all() method with a rejected promise
Promise.all([firstPromise, rejectedPromise, thirdPromise])
  .then((results) =&amp;gt; {
    console.log("All the promises were fulfilled");
    console.log("Response from all method - ", results);
  })
  .catch((error) =&amp;gt; {
    console.error("Error: ", error);
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error:  EVERYBODY STAY CALM. STAY F***ING CALM. I WAS REJECTED
All the promises were fulfilled here -  [ 'First Promise', 'Second Promise', 'Third Promise' ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Promise.allSettled()
&lt;/h2&gt;

&lt;p&gt;Input - An iterable of promises&lt;br&gt;
Output - A single promise that resolves into an array of the results of the input promises&lt;/p&gt;

&lt;p&gt;We can use this method when the tasks are dependent on each other and you want to know all the results of all the promises regardless of the result of each promise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Promise.allSettled() method with a rejected promise
Promise.allSettled([firstPromise, rejectedPromise, thirdPromise])
  .then((results) =&amp;gt; {
    console.log("I don't care if all the results are fulfilled or not");
    console.log("Response from allSettled method - ", results);
  })
  .catch((error) =&amp;gt; {
    console.error("Error: ", error);
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can clearly see the difference between the &lt;code&gt;all&lt;/code&gt; and &lt;code&gt;allSettled&lt;/code&gt; methods. The &lt;code&gt;all&lt;/code&gt; method wants all the promises to be fulfilled while &lt;code&gt;allSettled&lt;/code&gt; method only wants the promises to be &lt;code&gt;settled&lt;/code&gt; (regardless of &lt;code&gt;fulfilled&lt;/code&gt; or &lt;code&gt;rejected&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I don't care if all the results are fulfilled or not
Response from allSettled method -  [
  { status: 'fulfilled', value: 'First Promise' },
  {
    status: 'rejected',
    reason: 'EVERYBODY STAY CALM. STAY F***ING CALM. I WAS REJECTED'
  },
  { status: 'fulfilled', value: 'Third Promise' }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Promise.any()
&lt;/h2&gt;

&lt;p&gt;Input - An iterable of promises&lt;br&gt;
Output - A single promise that resolves as soon as any of the promises in the iterable fulfils, with the value of the fulfilled promise&lt;/p&gt;

&lt;p&gt;If none of the promises gets fulfilled, then the returned promise is rejected with an &lt;code&gt;AggregateError&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const firstPromise = new Promise((resolve, reject) =&amp;gt; {
  setTimeout(resolve, 300, "First Promise");
});

const secondPromise = new Promise((resolve, reject) =&amp;gt; {
  setTimeout(resolve, 100, "Second Promise");
});

const thirdPromise = new Promise((resolve, reject) =&amp;gt; {
  setTimeout(resolve, 1000, "Third Promise");
});

const rejectedPromise = Promise.reject(
  "EVERYBODY STAY CALM. STAY F***ING CALM. I WAS REJECTED"
);

//Promise.any() Method
Promise.any([firstPromise, secondPromise])
  .then((fasterPromise) =&amp;gt; {
    console.log("Response from any method with no rejections - ", fasterPromise);
  })
  .catch((error) =&amp;gt; {
    console.error("Error: ", error);
  });

//Promise.any() Method with rejections
Promise.any([rejectedPromise, rejectedPromise])
  .then((fasterPromise) =&amp;gt; {
    console.log("Response from any method with rejections - ", fasterPromise);
  })
  .catch((error) =&amp;gt; {
    console.error("Error: ", error);
  });


//Promise.any() Method
Promise.any([firstPromise, secondPromise]).then((fasterPromise) =&amp;gt; {
  console.log("Response from any method - ", fasterPromise);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error:  [AggregateError: All promises were rejected]
Response from any method with no rejections -  Second Promise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Promise.race()
&lt;/h2&gt;

&lt;p&gt;Input - An iterable of promises&lt;br&gt;
Output - A promise that &lt;code&gt;fulfils&lt;/code&gt; or &lt;code&gt;rejects&lt;/code&gt; as soon as one of the promises in an iterable fulfils or rejects, with the value or reason from that promise&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const firstPromise = new Promise((resolve, reject) =&amp;gt; {
  setTimeout(resolve, 300, "First Promise");
});

const secondPromise = new Promise((resolve, reject) =&amp;gt; {
  setTimeout(resolve, 100, "Second Promise");
});

const thirdPromise = new Promise((resolve, reject) =&amp;gt; {
  setTimeout(resolve, 1000, "Third Promise");
});

const rejectedPromise = Promise.reject(
  "EVERYBODY STAY CALM. STAY F***ING CALM. I WAS REJECTED"
);

//Promise.race() Method
Promise.race([firstPromise, secondPromise])
  .then((fasterPromise) =&amp;gt; {
    console.log(
      "Response from race method with no rejections - ",
      fasterPromise
    );
  })
  .catch((error) =&amp;gt; {
    console.error("Error: ", error);
  });

//Promise.race() Method with rejections
Promise.race([secondPromise, rejectedPromise])
  .then((fasterPromise) =&amp;gt; {
    console.log("Response from race method with rejections - ", fasterPromise);
  })
  .catch((error) =&amp;gt; {
    console.error("Error: ", error);
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the name of the method suggests, we have a race here. It does not matter whether the promises are &lt;code&gt;fulfilled&lt;/code&gt; or &lt;code&gt;rejected&lt;/code&gt;. The &lt;code&gt;race&lt;/code&gt; method returns the fastest settled promise.&lt;/p&gt;

&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error:  EVERYBODY STAY CALM. STAY F***ING CALM. I WAS REJECTED
Response from race method with no rejections -  Second Promise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Promise.reject() and Promise.resolve()
&lt;/h2&gt;

&lt;p&gt;You are already familiar with the reject method since I’ve used it in earlier examples. Basically, we use the reject method to reject a promise.&lt;/p&gt;

&lt;p&gt;In addition, we have the resolve method which returns a promise that is resolved with the given value, or the promise passed as value, if the value was a promise object. Resolved is not to be confused with fulfilled. Please read &lt;a href="https://stackoverflow.com/questions/35398365/js-promises-fulfill-vs-resolve"&gt;this StackOverflow answer&lt;/a&gt; to learn more about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fates
&lt;/h2&gt;

&lt;p&gt;Promises also have two mutually exclusive fates, resolved and unresolved.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If we try to resolve or reject a promise and it has no effect, we say the promise is resolved.&lt;/li&gt;
&lt;li&gt;If we try to resolve or reject a promise and it has an effect, we say the promise is unresolved.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;To sum things up, we use promises to handle asynchronous operations in JavaScript. Especially, when there are multiple asynchronous operations running, it would be a nightmare to handle them if you don't know about promises.&lt;/p&gt;

&lt;p&gt;I hope you learned something valuable from Today's article. If you liked it, drop a like and follow me so that you don't miss the upcoming articles. And as always, stay safe guys 😷&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Higher-Order Functions - JavaScript Concepts Simplified</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Thu, 23 Sep 2021 14:01:20 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/higher-order-functions-javascript-concepts-simplified-49ok</link>
      <guid>https://dev.to/thisurathenuka/higher-order-functions-javascript-concepts-simplified-49ok</guid>
      <description>&lt;p&gt;Hello guys, I'm back with another article in my &lt;strong&gt;JavaScript Concepts Simplified&lt;/strong&gt; series. Today, I'm going to go through the concept of Higher-Order Functions. &lt;/p&gt;

&lt;p&gt;This is not necessarily specific to JavaScript per se. But it is an essential concept you must learn when going forward with JavaScript. If you read my article regarding closures, you do already have some experience with higher-order functions even if you do not have an idea.&lt;/p&gt;

&lt;p&gt;The term, &lt;strong&gt;Higher-Order Functions&lt;/strong&gt; aka &lt;strong&gt;HOF&lt;/strong&gt;s, is said to be  &lt;a href="https://softwareengineering.stackexchange.com/questions/186035/who-first-coined-the-term-higher-order-function-and-or-first-class-citizen"&gt;coined way back in 1891&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Useful Terminology
&lt;/h1&gt;

&lt;p&gt;Before learning Higher-Order functions, let's quickly check out few other concepts that would aid you in understanding higher-order functions better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Functional Programming
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Functional programming (often abbreviated FP) is the process of building software by composing pure functions, avoiding shared state, mutable data, and side-effects. Functional programming is declarative rather than imperative, and the application state flows through pure functions. Contrast with object-oriented programming, where application state is usually shared and colocated with methods in objects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0"&gt;Source - Medium&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  First-Class Functions
&lt;/h2&gt;

&lt;p&gt;In a programming language where functions are treated as variables, it is said to have &lt;strong&gt;First-Class functions&lt;/strong&gt;. In such a language like JS, a function can be passed as an argument to other functions, can be assigned as a value to a variable and can be returned by another function&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a Higher-Order Function?
&lt;/h1&gt;

&lt;p&gt;A Higher-Order Function is a function that does at least one of the following things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Takes one or more functions as arguments&lt;/li&gt;
&lt;li&gt;Returns a function as a result&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All the functions that are not higher-order functions are called &lt;strong&gt;first-order functions&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Usage
&lt;/h1&gt;

&lt;p&gt;JavaScript has a list of inbuilt HOFs as well as we can write our own HOFs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inbuilt Higher-Order Functions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Array filter method
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const numbers = [1, 2, 3, 4, 5, 6, 7]
const smallerThanFive = x =&amp;gt; x &amp;lt; 5
console.log(numbers.filter(smallerThanFive)) // [1, 2, 3, 4]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we are &lt;em&gt;passing a function&lt;/em&gt; called &lt;strong&gt;smallerThanFive&lt;/strong&gt; to the filter method as the callback function. Read more on the filter method  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Array find method
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const innings = [
    {player: "Sanga", score: 59},
    {player: "Mahela", score: 70},
    {player: "Angie", score: 85}
];
const higherThanSeventyFive = inning =&amp;gt; inning.score &amp;gt; 75
console.log(innings.find(higherThanSeventyFive)) //{ player: 'Angie', score: 85 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we are &lt;em&gt;passing a function&lt;/em&gt; called &lt;strong&gt;higherThanSeventyFive&lt;/strong&gt; to the find method as the callback function. Read more on the find method &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Array map method
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const numbers = [1, 2, 3, 4]
const multiplyByTwo = x =&amp;gt; x * 2
console.log(numbers.map(multiplyByTwo)) // [2, 4, 6, 8]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we are &lt;em&gt;passing a function&lt;/em&gt; called &lt;strong&gt;multiplyByTwo&lt;/strong&gt; to the map method as the callback function. Read more on the map method  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The list goes on and on. I'd like to recommend you to check out the  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array"&gt;MDN Docs articles on Array methods&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Higher-Order Functions
&lt;/h2&gt;

&lt;p&gt;Since all the above examples were about passing functions as parameters, let's make our own higher-order function return a function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const multiply = (firstValue) =&amp;gt; (secondValue) =&amp;gt; firstValue * secondValue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me write this without the arrow function syntax to make things a bit clearer for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function multiply (firstValue) {
  return function (secondValue){
    return firstValue * secondValue;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;multiply&lt;/strong&gt; function gets the &lt;strong&gt;firstValue&lt;/strong&gt; as an argument and returns a function that asks for the &lt;strong&gt;secondValue&lt;/strong&gt; as an argument. Here is how you call this function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;multiply(10)(20) //Returns 200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of you might be thinking, "&lt;em&gt;We can just write this in a single function and pass both values into that. Why did you use a higher-order function for this?&lt;/em&gt;". Yes, you are right. There is no need for writing a higher-order function to multiply two values. &lt;/p&gt;

&lt;p&gt;But, if you want to make the inner functions not accessible to the outside, you can write a higher-order function. And learning to write higher-order functions would save you a lot of time.&lt;/p&gt;

&lt;p&gt;I know this could be hard to grasp, especially if you are new to functional programming. I believe you understand what is happening in the above function. But some of you might not still understand the thinking process behind writing a higher-order function like this. &lt;/p&gt;

&lt;p&gt;Let me take you through the thinking process so that you can attempt writing your own higher-order function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explaining The Thought Process
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function multiply (firstValue) {
  //Do some stuff with firstValue
}

multiply(10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you have a normal function that takes in an argument called &lt;strong&gt;firstValue&lt;/strong&gt;. And then you realize that you have to write another function, but you don't want to make it accessible from the outside. So, what are your options?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function multiply (firstValue) {
  //Do some stuff with firstValue
  return function (secondValue) {
    //Do some stuff with firstValue and secondValue
  }
}

multiply(10)(20)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can write it as a nested function. But then, there is no way for you to pass arguments from outside (You can pass the value to the outer function and then pass it to the inner function. But that is not a good coding practice). What you can do is to return the inner function and take in an argument from the inner function. Likewise, you can just keep writing functions inside functions as much as you need.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;To sum things up, higher-order functions are just like regular functions in JavaScript. The only difference is that while the regular functions take in variables and return variables, Higher-Order functions take in functions and return functions.&lt;/p&gt;

&lt;p&gt;I hope you learned something valuable from Today's article. If you liked it, drop a like and follow me so that you don't miss the upcoming articles. And as always, stay safe guys 😷&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Closures - JavaScript Concepts Simplified</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Mon, 20 Sep 2021 11:31:27 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/closures-javascript-concepts-simplified-4665</link>
      <guid>https://dev.to/thisurathenuka/closures-javascript-concepts-simplified-4665</guid>
      <description>&lt;p&gt;Hello guys, Today we are going to go over the concept of &lt;strong&gt;closure&lt;/strong&gt; in JavaScript.&lt;/p&gt;

&lt;h1&gt;
  
  
  Background Terms
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;IIFE&lt;/strong&gt;s aka Immediately Invoked Function Expressions are JavaScript functions that run as soon as they are defined. I am already writing a detailed article regarding IIFEs. So until then, if you do not know about IIFEs, just think of it as an anonymous function that runs automatically and here is the default syntax for it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(function () {
  //Write your code here
})()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Lexical scoping&lt;/strong&gt; is the concept of &lt;strong&gt;a variable defined outside a function&lt;/strong&gt; being &lt;strong&gt;accessible inside another function&lt;/strong&gt; defined after the variable declaration&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a Closure?
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures"&gt;Source - MDN Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me simplify. Think you have an IIFE that has a variable called &lt;strong&gt;total&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(function () {
  let total = 0
})();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usually, since the &lt;strong&gt;total&lt;/strong&gt; variable is defined inside the IIFE as a local variable, we can only use the &lt;strong&gt;total&lt;/strong&gt; variable inside the IIFE.&lt;/p&gt;

&lt;p&gt;But there is one way around it. If you define another function inside the IIFE, then that function also can access the variables of the parent function (IIFE) and hence can access the &lt;strong&gt;total&lt;/strong&gt;. Here is how that would look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(function () {
  let total = 0
  function print() {
    console.log("Here is the total : ", total)
  }
  print();
})();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prints &lt;strong&gt;total&lt;/strong&gt;'s current value (0) on the console.&lt;/p&gt;

&lt;p&gt;So, now you would say, "Right, but still the &lt;strong&gt;total&lt;/strong&gt; variable is only accessible from inside the IIFE". Yes, you are absolutely right. So, let's just return the function. &lt;/p&gt;

&lt;p&gt;You can think of functions in JavaScript as another variable type. We can just return the function and assign it into a variable. And since we are assigning the function reference to a variable, we don't even have to have a name for the inner function. Cool, right?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const addition = (function () {
  let total = 0
  return function (){
    total += 1
    console.log("The total is : ", total)
  }
})();

addition()
addition()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the console output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The total is :  1
The total is :  2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that &lt;strong&gt;the outer function doesn't have to be an IIFE&lt;/strong&gt;. You can use the same concept with normal functions as well like in the following code snippet. I'm just using IIFEs to make the code cleaner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Using Normal Functions
function addition() {
  let total = 0;
  return function () {
    total += 1;
    console.log("The total is : ", total);
  };
}

//This returns the same console output as before
let returningFunction = addition()
returningFunction()
returningFunction()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can just call this function as much as you want now. You are updating the value of a local variable from outside the function. This is the concept of &lt;strong&gt;closure&lt;/strong&gt; in JavaScript.&lt;/p&gt;

&lt;p&gt;If you want, we can take this a step further by &lt;strong&gt;returning a set of functions&lt;/strong&gt; like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const manipulate = (function () {
  let total = 0
  return {
    increment : function () {
      total += 1
      console.log("The total is : ", total)
    },
    decrement: function () {
      total -= 1
      console.log("The total is : ", total)
    }
  }
})();

manipulate.increment()
manipulate.increment()
manipulate.decrement()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the console output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The total is :  1
The total is :  2
The total is :  1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Multiple Nested Functions
&lt;/h1&gt;

&lt;p&gt;Take a look at this example from the  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures"&gt;MDN Docs&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;// global scope
var e = 10;
function sum(a){
  return function(b){
    return function(c){
      // outer functions scope
      return function(d){
        // local scope
        return a + b + c + d + e;
      }
    }
  }
}

console.log(sum(1)(2)(3)(4)); // log 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see we can just keep writing anonymous functions inside functions and use all the passed values. This also can be done using named functions as well. But you have to write few more lines when calling the functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// global scope
var e = 10;
function sum(a){
  return function sum2(b){
    return function sum3(c){
      // outer functions scope
      return function sum4(d){
        // local scope
        return a + b + c + d + e;
      }
    }
  }
}

var sum2 = sum(1);
var sum3 = sum2(2);
var sum4 = sum3(3);
var result = sum4(4);
console.log(result) //log 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Well, that is pretty much all you need to know to get started with JavaScript closures. Try to think of where you can add closure in your codebases. We will only get better if we start practising these concepts on a daily basis.&lt;/p&gt;

&lt;p&gt;If you want to learn more in-depth stuff regarding closures like performance considerations, you should check out  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures"&gt;the MDN Docs article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for reading my article. I hope you learned something valuable today. If you did, don't forget to follow my blog and share the article with your friends. And more importantly, stay safe 😷&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Event Bubbling - JavaScript Concepts Simplified</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Sat, 18 Sep 2021 17:30:10 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/event-bubbling-javascript-concepts-simplified-8bi</link>
      <guid>https://dev.to/thisurathenuka/event-bubbling-javascript-concepts-simplified-8bi</guid>
      <description>&lt;p&gt;Hello guys, welcome to another article in the JavaScript Concepts Simplified article series. Today, we'll be looking into Event Bubbling in JavaScript.&lt;/p&gt;

&lt;p&gt;I'm just going to go through some of the basic things you need to know before going into the main event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background Knowledge
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;event&lt;/strong&gt; is an action or an occurrence that happens in your system. The simplest example would be the user clicking on a button.&lt;/p&gt;

&lt;p&gt;For each event that is fired, we can write an &lt;strong&gt;event handler&lt;/strong&gt; (A JavaScript function to handle the event) to do what we want to do. For example, we can write an event handler function to print something on the screen once the user clicks on the button.&lt;/p&gt;

&lt;p&gt;We also have &lt;strong&gt;event listeners&lt;/strong&gt; in JavaScript. Event listeners listen to the events happening. So, if we want to print something on the screen once the user clicks on the button, we need to first create an event listener to listen for the click event of the button.&lt;/p&gt;

&lt;p&gt;When we are loading HTML pages in browsers, the browser creates a tree-like structure for each page called the &lt;strong&gt;DOM&lt;/strong&gt;. For example, if you have a button inside your &lt;em&gt;body&lt;/em&gt; tag, the path to the button element would be &lt;strong&gt;html&lt;/strong&gt; -&amp;gt; &lt;strong&gt;body&lt;/strong&gt; -&amp;gt; &lt;strong&gt;button&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Phases of Event Handling
&lt;/h2&gt;

&lt;p&gt;When it comes to handling events, modern browsers have three phases.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Capturing Phase&lt;/li&gt;
&lt;li&gt;Target Phase&lt;/li&gt;
&lt;li&gt;Bubbling Phase&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Capturing Phase
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The browser checks to see if the element's outer-most ancestor has an onclick event handler registered on it for the capturing phase, and runs it if so.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events" rel="noopener noreferrer"&gt;Source - MDN Docs&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  The Target Phase
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The browser checks to see if the target property has an event handler for the click event registered on it, and runs it if so.&lt;/p&gt;

&lt;p&gt;Then, if &lt;strong&gt;bubbles&lt;/strong&gt; is true, it propagates the event to the direct parent of the selected element, then the next one, and so on. Otherwise, if &lt;strong&gt;bubbles&lt;/strong&gt; is false, it doesn’t propagate the event to any ancestors of the target.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events" rel="noopener noreferrer"&gt;Source - MDN Docs&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  The Bubbling Phase
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The browser checks to see if the direct parent of the element selected has an onclick event handler registered on it for the bubbling phase, and runs it if so.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events" rel="noopener noreferrer"&gt;Source - MDN Docs&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, What?
&lt;/h2&gt;

&lt;p&gt;It is hard to grasp the issue by reading the above lines. Let me simplify. Here is the issue we are facing. &lt;/p&gt;

&lt;p&gt;Think you have created a UI with two &lt;strong&gt;div&lt;/strong&gt; blocks (Block A and Block B). Block B is placed inside Block A. And you have created event handlers for the click event of both &lt;strong&gt;div&lt;/strong&gt; tags.&lt;/p&gt;

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

&lt;p&gt;Now when you click on &lt;strong&gt;Block B&lt;/strong&gt;, before calling B's event handler, the browser calls A's event handler function. Obviously, this is not what we expected. When we click on B, only the event handler of B should be called.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do we fix this?
&lt;/h2&gt;

&lt;p&gt;Luckily, we do have a solution for this. In the &lt;strong&gt;event&lt;/strong&gt; object, we have a function called &lt;strong&gt;stopPropogation&lt;/strong&gt;. You can call this function at the start of the event handler function of B. You will see that only the event handler function of B is getting executed this time.&lt;/p&gt;

&lt;h2&gt;
  
  
  When is Event Bubbling Useful?
&lt;/h2&gt;

&lt;p&gt;There could be some use cases where this can be useful. For example, when you have a list of items and you want to do something for all of the items, you will usually have to add event listeners for all the items.&lt;/p&gt;

&lt;p&gt;But since you now know the concept of event bubbling, you can just write and assign the event handler for the parent node and see the magic happen.&lt;/p&gt;

&lt;p&gt;This concept is called &lt;strong&gt;event delegation&lt;/strong&gt;. You can read more on that in  &lt;a href="https://davidwalsh.name/event-delegate" rel="noopener noreferrer"&gt;this article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for reading the article. Hope you learned something valuable today. And most importantly, stay safe guys 😷&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Hoisting - JavaScript Concepts Simplified</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Sat, 18 Sep 2021 05:15:19 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/hoisting-javascript-concepts-simplified-3dl4</link>
      <guid>https://dev.to/thisurathenuka/hoisting-javascript-concepts-simplified-3dl4</guid>
      <description>&lt;p&gt;Hello there, today we’ll look at the hoisting idea in JavaScript.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Hoisting
&lt;/h1&gt;

&lt;p&gt;Hoisting is the process where the interpreter allocates memory for &lt;strong&gt;variables&lt;/strong&gt; and &lt;strong&gt;function declarations&lt;/strong&gt; before the execution of code.&lt;/p&gt;

&lt;p&gt;Variables declared using the &lt;strong&gt;var&lt;/strong&gt; keyword are initialized automatically with a value of &lt;strong&gt;&lt;em&gt;undefined&lt;/em&gt;&lt;/strong&gt;. When the keywords &lt;strong&gt;let&lt;/strong&gt; and &lt;strong&gt;const&lt;/strong&gt; are used to declare a variable, they will not be initialized with hoisting.&lt;/p&gt;

&lt;h1&gt;
  
  
  Interpreter vs Us
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Declaring Variables – Using var keyword
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(sport)
var sport = "Cricket"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a look at the above code. We have used the variable before even declaring it. This should throw an error, right? Well, it does not. Here is when hoisting comes to the rescue.&lt;/p&gt;

&lt;p&gt;Executing this code logs &lt;strong&gt;&lt;em&gt;undefined&lt;/em&gt;&lt;/strong&gt; in the console. You will understand why this happens when you see how the interpreter sees the code.&lt;/p&gt;

&lt;p&gt;Here is how the interpreter sees 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;var sport;
console.log(sport)
sport = "Cricket"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Declaring Variables – Using let/const keywords
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(player)
let player = "Sanga"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should also log &lt;strong&gt;&lt;em&gt;undefined&lt;/em&gt;&lt;/strong&gt; as the output, right? Well, sadly the hoisting does not initialize &lt;strong&gt;let&lt;/strong&gt; and &lt;strong&gt;const&lt;/strong&gt; variables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Please note that all the declarations in JavaScript are getting "&lt;strong&gt;hoisted&lt;/strong&gt;". It is just that when it comes to &lt;strong&gt;let&lt;/strong&gt; and &lt;strong&gt;const&lt;/strong&gt;, the declared variables stay uninitialized. They will only get initialized when the &lt;strong&gt;let&lt;/strong&gt; or &lt;strong&gt;const&lt;/strong&gt; statements are executed and hence throws an error. This time between the variable creation and initialization is called the &lt;strong&gt;Temporal Dead Zone&lt;/strong&gt;. (Read  &lt;a href="https://stackoverflow.com/questions/31219420/are-variables-declared-with-let-or-const-hoisted"&gt;this StackOverflow answer&lt;/a&gt;  to learn more)&lt;/p&gt;

&lt;p&gt;The above code throws a &lt;strong&gt;ReferenceError&lt;/strong&gt; since the variable does not get initialized in this case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ReferenceError: Cannot access 'player' before initialization
    at Object.&amp;lt;anonymous&amp;gt; (C:\Users\ThenukaAluthGedara\Desktop\Hoisting.js:1:13)
←[90m    at Module._compile (internal/modules/cjs/loader.js:1063:30)←[39m
←[90m    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)←[39m
←[90m    at Module.load (internal/modules/cjs/loader.js:928:32)←[39m
←[90m    at Function.Module._load (internal/modules/cjs/loader.js:769:14)←[39m
←[90m    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)←[39m
←[90m    at internal/main/run_main_module.js:17:47←[39m
Please note that only declarations are hoisted in JavaScript.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following code still does throw a ReferenceError since the variable has only been initialized.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(name)
name = "Sanga"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Hoisting with Function Declarations
&lt;/h2&gt;

&lt;p&gt;Both following code snippets work fine since the interpreter always sees the function declarations first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;greeting("The Coding Cricketer")

function greeting(siteName){
    console.log("Welcome to " + siteName)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function greeting(siteName){
    console.log("Welcome to " + siteName)
}

greeting("The Coding Cricketer")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Further Reading
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting"&gt;MDN Docs on Hoisting&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.w3schools.com/js/js_hoisting.asp"&gt;W3Schools article on Hoisting&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/understanding-hoisting-in-javascript"&gt;Digital Ocean article on Hoisting&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;It is always a good coding practice to declare the variables at the top of the scope&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You will not be able to use variables without declaring them first if you use “&lt;strong&gt;use strict&lt;/strong&gt;” in JavaScript. I will discuss this in a future article.&lt;/p&gt;

&lt;p&gt;Thank you for reading my article. I hope you learned something valuable today. If you liked it, drop a like and subscribe to my blog. I’ll see you soon with my next article. Stay Safe 😷&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Automate your Deployments using Bash Scripts</title>
      <dc:creator>Thisura Thenuka</dc:creator>
      <pubDate>Sun, 09 May 2021 17:19:01 +0000</pubDate>
      <link>https://dev.to/thisurathenuka/automate-your-deployments-using-bash-scripts-3p05</link>
      <guid>https://dev.to/thisurathenuka/automate-your-deployments-using-bash-scripts-3p05</guid>
      <description>&lt;p&gt;If you are a developer who is working on a project that doesn't have a code pipeline, this article would help you save a lot of time. Well, I understand that could be a very small group of people, but I am happy even if only one person learns something from this article.&lt;/p&gt;

&lt;p&gt;In this article, I am going to cover the reason why you should automate your tasks as a developer and how you can use bash scripts to help you with that. Besides, I am going to explain some basic bash concepts to help you understand my bash script which I'll be sharing later in the article.&lt;/p&gt;

&lt;p&gt;Without further ado, let's hop into the article.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why should we focus on Automation as Developers?&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Getting rid of Repetitive Tasks&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As developers, we usually have to go through a set of repetitive tasks every single day. You'll be able to identify those tasks if you observe your daily routine. I believe that if I have to do the same thing twice, I need to automate it (I haven't automated much yet, but I always try to live by this). If you think about it, this actually is a core coding principle. This is just like writing a function to stop writing the same code over and over again.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Self-Satisfaction&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I don't know if you ever have tried to automate something. It feels so satisfying when you finish automating something. The process is fun and interesting. You will learn so many things along the way. I didn't know much about Bash until I wanted to automatically deploy my services without doing individually which was really time-consuming. But now, I do have sound knowledge about Bash.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What are Bash Scripts?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Bash is a command language and also is a UNIX shell. It is the default command interpreter among Linux/GNU systems around the world. &lt;strong&gt;BASH&lt;/strong&gt; (&lt;strong&gt;B&lt;/strong&gt;ourne-&lt;strong&gt;A&lt;/strong&gt;gain &lt;strong&gt;SH&lt;/strong&gt;ell) was released in 1989 as a free software replacement for the Bourne Shell.&lt;/p&gt;

&lt;p&gt;Bash Scripts are just plain text files with a set of commands. Basically, these are commands what we would usually type in on the command line. We just have created a file to put all the commands in it so that when we run that file, all the commands will be executed.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How can we use Bash Scripts for Automation?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here what we are just going to create a single bash script file by putting in all the commands that we would have to type in when we log into the server. Instead of typing that set of commands individually which takes a lot of time, we are going to run this bash script file and let the magic happen.&lt;/p&gt;

&lt;p&gt;Before I go into revealing and explaining my code, I think it would be much better if we learn the basics of Bash scripts. If you have a decent knowledge about BASH commands, you may directly skip over to the bash script.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Bash Basics&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Creating a file&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Bash Scripts have an extension of &lt;strong&gt;.sh&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can create a bash script with &lt;strong&gt;nano &lt;a href="http://testing.sh/" rel="noopener noreferrer"&gt;testing.sh&lt;/a&gt;&lt;/strong&gt; or &lt;strong&gt;touch &lt;a href="http://testing.sh/" rel="noopener noreferrer"&gt;testing.sh&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Parts of a Bash Script&lt;/strong&gt;
&lt;/h3&gt;

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

&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Created by Thisura&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The first line contains two parts. #! is called the Shebang. Next to the Shebang, we have to specify the path to the interpreter (You can find this by typing &lt;strong&gt;which bash&lt;/strong&gt;). If you exactly don't know the path of the interpreter, you can just specify the first line like this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#!/usr/bin/env bash&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Important: There can't be any spaces between the characters in the first line. This line always has to be the first line of the bash script.&lt;/p&gt;

&lt;p&gt;The 3rd line is a comment. Comments start with &lt;strong&gt;#&lt;/strong&gt; in Bash.&lt;/p&gt;

&lt;p&gt;The 4th line is printing &lt;strong&gt;Hello World&lt;/strong&gt; in the terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Making it executable&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To make a bash script executable, we have to type &lt;strong&gt;chmod +x &lt;a href="http://testing.sh/" rel="noopener noreferrer"&gt;testing.sh&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Running a Bash Script&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We can run the bash script file by typing &lt;strong&gt;./testing.sh&lt;/strong&gt; (Here the dot indicates the current directory) or &lt;strong&gt;bash &lt;a href="http://testing.sh/" rel="noopener noreferrer"&gt;testing.sh&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can also run the bash script without specifying the directory. For that, we need to add the script's directory to the &lt;strong&gt;$PATH&lt;/strong&gt; variable by typing &lt;strong&gt;PATH=$PATH:/path/to/script&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The motivation behind creating the script&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I have been working with Spring Boot and React environments. So, the services that I have to deploy usually are jar files and React builds. After uploading the releases to the server, I usually have to go to each folder and kill the existing service, run the new service and check if the service is running properly. In some projects, there are about 8 services and it takes forever to do the deployment.&lt;/p&gt;

&lt;p&gt;So, in my free time, I began searching for a way to speed up the process. After some research, I realized creating a bash script would be the easiest and quickest way forward. So, I started learning Bash and after a lot of trial and error, I managed to create a bash script file that literally saved me literally hours. I'm still learning and trying to optimize what I have.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Bash Script for Automating Deployments&lt;/strong&gt;
&lt;/h2&gt;

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

&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;frontend_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'/root/Deployments/Frontend/bp-f-v0.4.0-zsic-iat'&lt;/span&gt;
&lt;span class="nv"&gt;backend_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'/root/Deployments/Backend'&lt;/span&gt;
&lt;span class="nv"&gt;auth_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'/root/Deployments/Auth'&lt;/span&gt;
&lt;span class="nv"&gt;reporting_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'/root/Deployments/Reporting'&lt;/span&gt;
&lt;span class="nv"&gt;claims_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'/root/Deployments/Claims'&lt;/span&gt;
&lt;span class="nv"&gt;email_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'/root/Deployments/Email'&lt;/span&gt;

&lt;span class="nv"&gt;reporting_release_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'rp-s-v0.3.0-zsic-iat.jar'&lt;/span&gt;
&lt;span class="nv"&gt;reporting_sleep&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30

&lt;span class="nv"&gt;backend_release_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'bp-s-v0.4.7-zsic-iat.jar'&lt;/span&gt;
&lt;span class="nv"&gt;backend_sleep&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30

&lt;span class="nv"&gt;auth_release_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ua-s-v1.2.2-zsic-iat.jar'&lt;/span&gt;
&lt;span class="nv"&gt;auth_sleep&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30

&lt;span class="nv"&gt;claims_release_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'cl-s-v5.0.2-zsic-iat.jar'&lt;/span&gt;
&lt;span class="nv"&gt;claims_sleep&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30

&lt;span class="nv"&gt;email_release_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'em-s-v0.0.1.-zsic-iat.jar'&lt;/span&gt;
&lt;span class="nv"&gt;email_sleep&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30

&lt;span class="k"&gt;function &lt;/span&gt;kill_existing_services &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Killing Exisiting Services : "&lt;/span&gt;
    fuser &lt;span class="nt"&gt;-k&lt;/span&gt; 8087/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    fuser &lt;span class="nt"&gt;-k&lt;/span&gt; 8091/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    fuser &lt;span class="nt"&gt;-k&lt;/span&gt; 8206/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    fuser &lt;span class="nt"&gt;-k&lt;/span&gt; 8001/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    fuser &lt;span class="nt"&gt;-k&lt;/span&gt; 9988/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    fuser &lt;span class="nt"&gt;-k&lt;/span&gt; 6999/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function &lt;/span&gt;deploy_releases &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
    java &lt;span class="nt"&gt;-jar&lt;/span&gt; &lt;span class="nv"&gt;$2&lt;/span&gt; &amp;amp;
    &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="nv"&gt;$3&lt;/span&gt;
    &lt;span class="nv"&gt;PID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$!&lt;/span&gt;
    &lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-INT&lt;/span&gt; &lt;span class="nv"&gt;$PID&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function &lt;/span&gt;checking_service_status &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Checking if services were deployed successfully : "&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Reporting  Service : "&lt;/span&gt;
    fuser 8087/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Backend  Service : "&lt;/span&gt;
    fuser 8091/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Auth  Service : "&lt;/span&gt;
    fuser 8206/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Email  Service : "&lt;/span&gt;
    fuser 9988/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Claim  Service : "&lt;/span&gt;
    fuser 8001/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;2
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function &lt;/span&gt;deploying_frontend &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deploying Frontend Service (Please press Ctrl + C once the running stops)"&lt;/span&gt;
    &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$frontend_path&lt;/span&gt;
    &lt;span class="nb"&gt;nohup &lt;/span&gt;node server.js &amp;amp;
&lt;span class="o"&gt;}&lt;/span&gt;

kill_existing_services
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deploying Services : "&lt;/span&gt;
deploy_releases &lt;span class="nv"&gt;$reporting_path&lt;/span&gt; &lt;span class="nv"&gt;$reporting_release_name&lt;/span&gt; &lt;span class="nv"&gt;$reporting_sleep&lt;/span&gt;
deploy_releases &lt;span class="nv"&gt;$backend_path&lt;/span&gt; &lt;span class="nv"&gt;$backend_release_name&lt;/span&gt; &lt;span class="nv"&gt;$backend_sleep&lt;/span&gt;
deploy_releases &lt;span class="nv"&gt;$auth_path&lt;/span&gt; &lt;span class="nv"&gt;$auth_release_name&lt;/span&gt; &lt;span class="nv"&gt;$auth_sleep&lt;/span&gt;
deploy_releases &lt;span class="nv"&gt;$claims_path&lt;/span&gt; &lt;span class="nv"&gt;$claims_release_name&lt;/span&gt; &lt;span class="nv"&gt;$claims_sleep&lt;/span&gt;
deploy_releases &lt;span class="nv"&gt;$email_path&lt;/span&gt; &lt;span class="nv"&gt;$email_release_name&lt;/span&gt; &lt;span class="nv"&gt;$email_sleep&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt;
checking_service_status
deploying_frontend


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

&lt;/div&gt;

&lt;p&gt;Firstly, I have created variables for all the paths, release names and I also have specified an amount of time until which the thread will be sleeping (Until that relevant service is deployed).&lt;/p&gt;

&lt;p&gt;I've created this bash script file using four functions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;kill_existing_services - This function kills the current running services in the specified ports where our services are running&lt;/li&gt;
&lt;/ul&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%2Fag8t7y1sxox8mo71t5gz.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%2Fag8t7y1sxox8mo71t5gz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deploy_releases - This function will deploying our backend releases in the server&lt;/li&gt;
&lt;li&gt;checking_service_status - This function will check if the services were deployed in the specified ports&lt;/li&gt;
&lt;/ul&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%2Ftpr57s3lbb3i8hawzf80.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%2Ftpr57s3lbb3i8hawzf80.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deploying_frontend - This function will deploy the frontend service&lt;/li&gt;
&lt;/ul&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%2F7psqysq209lryf6uygwm.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%2F7psqysq209lryf6uygwm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When calling the deploy_releases function, I am passing the release path, release name and sleep time as parameters. $1 is the first parameter and so on. I have made the thread sleep for 30 seconds to give time for each service to be deployed. This does differ on how good your internet connection is. You may adjust the time accordingly.&lt;/p&gt;

&lt;p&gt;I believe other functions are pretty much self-explanatory.&lt;/p&gt;

&lt;p&gt;I know this is not the perfect script for this. I am sharing this script for you to get an idea about how you should go on automating your tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this article, you learned the importance and benefits of automating repetitive tasks as a developer. In addition, you learned the basic of Bash scripts and I shared my deployment script for you to get an idea about how you would create your own.&lt;/p&gt;

&lt;p&gt;If you feel like you learned something valuable today, please drop a like and share the article with your friends. If you are interested in studying Bash further, I highly recommend you guys to start by reading the following article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.taniarascia.com/how-to-create-and-use-bash-scripts/" rel="noopener noreferrer"&gt;https://www.taniarascia.com/how-to-create-and-use-bash-scripts/&lt;/a&gt;&lt;/p&gt;

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