<?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: Adekola Olawale</title>
    <description>The latest articles on DEV Community by Adekola Olawale (@adekolaolawale).</description>
    <link>https://dev.to/adekolaolawale</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%2F60533%2F2494dd20-23a3-45ac-9259-1a04e11ebbaf.png</url>
      <title>DEV Community: Adekola Olawale</title>
      <link>https://dev.to/adekolaolawale</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adekolaolawale"/>
    <language>en</language>
    <item>
      <title>Firebase Authentication: Build a Smooth Authentication Flow System with Firebase</title>
      <dc:creator>Adekola Olawale</dc:creator>
      <pubDate>Mon, 19 Dec 2022 11:32:00 +0000</pubDate>
      <link>https://dev.to/adekolaolawale/firebase-authentication-build-a-smooth-authentication-flow-system-with-firebase-3h9l</link>
      <guid>https://dev.to/adekolaolawale/firebase-authentication-build-a-smooth-authentication-flow-system-with-firebase-3h9l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we are going to follow a step-by-step guide on how to set up the Firebase authentication service, and then walk through how to implement the service in your application. An authentication service protects your website from unverified users having access to the website’s features or contents. It ensures users are who they say they are. It proves users’ identity is genuine by verifying their credentials, which are usually the username/email and password. We’ve all experienced this on platforms such as Facebook, Instagram or Twitter when we are trying to sign into our accounts.&lt;/p&gt;

&lt;p&gt;Authentication service such as Firebase authentication provided by Google’s Backend as a Service (BaaS) product, Firebase, makes the authentication process super easy for developers. It provides an array of authentication methods, ranging from native providers such as plain email and password or social providers like Facebook, Twitter, LinkedIn, GitHub &amp;amp; Google. Implementing the social sign-up/sign-in providers in the sign-up and sign-in flow improves the experience of users on your website. Signing up or signing in through this process is less stressful cognitively, users do not have to start trying to remember their password when they could just click on a social sign-in button, and be signed up or signed in seamlessly without any hassle whatsoever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Firebase Authentication Service
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9norm7dubrrbgtwkeecm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9norm7dubrrbgtwkeecm.png" alt="Firebase console" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Proceed to &lt;a href="https://console.firebase.google.com" rel="noopener noreferrer"&gt;https://console.firebase.google.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sign into your Firebase account or sign-up if you don’t have an account.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;strong&gt;Add project (+)&lt;/strong&gt; box to set up a new project.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fic2zi5t79yhh2uvda225.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fic2zi5t79yhh2uvda225.png" alt="Create project interface" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Type your project name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disable the Google Analytics functionality on the next page, we don’t need it for this project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;strong&gt;Create project&lt;/strong&gt; button.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fclfbvw434xmt7yseicgv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fclfbvw434xmt7yseicgv.png" alt="Project dashboard" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;strong&gt;&amp;lt;/&amp;gt;&lt;/strong&gt; icon button, since we are building a sign-in system for a web app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type a name for your web app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the Register app button.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ffwyqunakc5z45t3tya1f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ffwyqunakc5z45t3tya1f.png" alt="Add Firebase SDK interface" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code&gt;firebase.js&lt;/code&gt; file in your code editor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the firebase configuration content in the blue box image above.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste it into the &lt;code&gt;firebase.js&lt;/code&gt; file&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point your &lt;code&gt;firebase.js&lt;/code&gt; file 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;// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "*************************",
  authDomain: "**********************",
  projectId: "*****************",
  storageBucket: "****************",
  messagingSenderId: "*******",
  appId: "*************"
};

// Initialize Firebase and export
export const app = initializeApp(firebaseConfig);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The parts hashed out above should be replaced with your unique value provided by the Firebase SDK. It was hashed out for security purposes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3vid7zebw8bgzsu83910.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3vid7zebw8bgzsu83910.png" alt="Project dashboard displaying Firebase products" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Head back to the Firebase console.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the Continue to console button.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you just created a web app in your firebase project. It’s possible to create another app as well like a mobile app if you are developing a mobile app, in this case, you will be clicking the android or &lt;strong&gt;iOS&lt;/strong&gt; icon (depending on the operating system architecture for the mobile app) in the interface in step 3.&lt;/p&gt;

&lt;p&gt;With this newly created web app, we can access any Firebase service available on the console like the authentication service we will be using shortly.&lt;/p&gt;

&lt;p&gt;To avoid prolonging this article unnecessarily by focusing too much on setting the authentication process, you can follow the rest of the &lt;a href="https://scribehow.com/shared/Google_Workflow__Vh9OoquKQZmELug5EkJaMg" rel="noopener noreferrer"&gt;setup flow&lt;/a&gt; where you can work with a clear visual illustration of the steps. I would strongly advise you to visit the link above to complete the authentication setup on the firebase console.&lt;/p&gt;

&lt;p&gt;As stated earlier in step 4, Firebase provides SDKs for any product that we want to utilize in our project. However, before we can have access to the authentication SDK we need to install it into our project. The SDK can be installed by running the following command in your CLI or terminal:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Make sure you change the directory (cd) to the folder your project is sitting in before running the command above in your command line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sign-Up Flow
&lt;/h2&gt;

&lt;p&gt;The sign-up process is a user’s introduction to a website, and before the user can be trusted to enjoy the resources or view the content of the website, they need to be authenticated, which is a way of ensuring a user is who they say they are on the internet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Password-based Sign-Up
&lt;/h3&gt;

&lt;p&gt;As stated earlier, we are going to be authenticating our users in two ways: via email/password and via Google, of course, there are more ways to authenticate too, Phone, Facebook, Twitter, Apple, and GitHub among others.&lt;/p&gt;

&lt;p&gt;Before any serious coding commences, let’s get the form interface design out of the way first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import { Link } from "react-router-dom";
import {
  createUserWithEmailAndPassword,
  getAuth
} from "firebase/auth";
import { useState } from "react";

const PasswordSignUp = () =&amp;gt; {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState(false);
  const [errorMessage, setErrorMessage] = useState("");

  // instantiate the auth service SDK
  const auth = getAuth();

  const handleChange = (e) =&amp;gt; {
    const { name, value } = e.target;

    if (name === "email") setEmail(value);
    if (name === "password") setPassword(value);
  };

  // Handle user sign up with email and password
  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();

    try {
      // create a new user with email and password
      const userCredential = await createUserWithEmailAndPassword(
        auth,
        email,
        password
      );

      // Pull out user's data from the userCredential property
      const user = userCredential.user;
    } catch (err) {
      // Handle errors here
      const errorMessage = err.message;
      const errorCode = err.code;

      setError(true);

      switch (errorCode) {
        case "auth/weak-password":
          setErrorMessage("The password is too weak.");
          break;
        case "auth/email-already-in-use":
          setErrorMessage(
            "This email address is already in use by another account."
          );
        case "auth/invalid-email":
          setErrorMessage("This email address is invalid.");
          break;
        case "auth/operation-not-allowed":
          setErrorMessage("Email/password accounts are not enabled.");
          break;
        default:
          setErrorMessage(errorMessage);
          break;
      }
    }
  };

  return (
    &amp;lt;div className='signupContainer'&amp;gt;
      &amp;lt;div className='signupContainer__box'&amp;gt;
        &amp;lt;div className='signupContainer__box__inner'&amp;gt;
          &amp;lt;h1&amp;gt;Sign Up&amp;lt;/h1&amp;gt;
          &amp;lt;form className='signupContainer__box__form' onSubmit={handleSubmit}&amp;gt;
            &amp;lt;input
              type='email'
              placeholder='Email'
              onChange={handleChange}
              name='email'
              value={email}
            /&amp;gt;
            &amp;lt;input
              type='password'
              placeholder='Password'
              onChange={handleChange}
              name='password'
              value={password}
            /&amp;gt;
            &amp;lt;button type='submit'&amp;gt;Sign Up&amp;lt;/button&amp;gt;
            {error &amp;amp;&amp;amp; &amp;lt;p&amp;gt;{errorMessage}&amp;lt;/p&amp;gt;}
          &amp;lt;/form&amp;gt;

          &amp;lt;div className='signupContainer__box__login'&amp;gt;
            &amp;lt;p&amp;gt;
              Already have an account? &amp;lt;Link to='/signin'&amp;gt;Sign In&amp;lt;/Link&amp;gt;
            &amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;A lot is going on in the code above so we will dive into every aspect of the code and try to understand the message it is conveying. First off, we are importing the &lt;code&gt;createUserWithEmailAndPassword&lt;/code&gt; method and the &lt;code&gt;getAuth&lt;/code&gt; method in lines 4 to 6.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;createUserWithEmailAndPassword&lt;/code&gt; method aid in creating a new user account with the &lt;code&gt;email&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; from the input value which will be provided as arguments in the method along with the auth variable instantiated in line 16, &lt;code&gt;auth&lt;/code&gt; variable is an authentication instance from the firebase authentication service. Then on successful creation of the user account (once the returned Promise is resolved), the user will be signed into the website or application. The returned Promise is the user credential object (&lt;code&gt;userCredential&lt;/code&gt;), from this user credential (&lt;code&gt;userCredential.user&lt;/code&gt;) we can pull out the email we provided to sign-up from the email property, the username, phone number and the image URL can be accessed as &lt;code&gt;displayName&lt;/code&gt;, &lt;code&gt;phoneNumber&lt;/code&gt; and &lt;code&gt;photoURL&lt;/code&gt; properties respectively.&lt;/p&gt;

&lt;p&gt;The input value we pulled from &lt;code&gt;e.target&lt;/code&gt; is used to get the email and password the user typed, since we are using one &lt;code&gt;handleChange&lt;/code&gt; function in lines 18 to 23 for the &lt;code&gt;onChange&lt;/code&gt; prop for the email and password input fields we can decide which input value is needed based on what the input name attribute value (&lt;code&gt;e.target.name&lt;/code&gt;)is equal to, &lt;code&gt;email&lt;/code&gt; or &lt;code&gt;password&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the catch block, lines 39 to 64, we handle the errors gracefully with a switch statement. Firebase auth service provides error codes for developers to provide an appropriate contextual message for their users, like if &lt;code&gt;err.code&lt;/code&gt; is equal to &lt;code&gt;auth/invalid-email&lt;/code&gt; we can tell the user that the &lt;em&gt;email address is invalid&lt;/em&gt;, improving the user experience and accessibility of our website in the process. The &lt;code&gt;errorMessage&lt;/code&gt; state is updated with the right message according to the context of the error, then we do a conditional rendering in line 88 to check if there is an error, in that case, display a certain error message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fi9zfie8zcx86grj67zqf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fi9zfie8zcx86grj67zqf.png" alt="Firebase authentication users interface" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The moment any of your users signs up successfully their respective user account details will be saved onto Firebase authentication, you can access this by clicking the &lt;strong&gt;Users&lt;/strong&gt; tab on the Authentication page. The user’s id together with the email address used, provider (email/password, Google or Twitter), date the user first signed up and their latest sign-in date will be provided and can be accessed in their interface above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Authentication Sign-Up
&lt;/h3&gt;

&lt;p&gt;Firebase Google authentication provider should be enabled before proceeding with this part. Follow the &lt;a href="https://scribehow.com/shared/Google_Workflow__Vh9OoquKQZmELug5EkJaMg" rel="noopener noreferrer"&gt;setup flow&lt;/a&gt; provided earlier to enable the Google authentication provider on your Firebase console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import googleLogo from "../assets/images/googleLogo.webp";
import { Link } from "react-router-dom";
import {
  signInWithPopup,
  GoogleAuthProvider,
  getAuth
} from "firebase/auth";
import { useState } from "react";

const GoogleSignUp = () =&amp;gt; {
  const [error, setError] = useState(false);
  const [googleErrorMessage, setGoogleErrorMessage] = useState("");

  // Instantiate the auth service SDK
  const auth = getAuth();

  // Handle user sign up with google
  const handleGoogleSignUp = async (e) =&amp;gt; {
    e.preventDefault();

     // Instantiate a GoogleAuthProvider object
    const provider = new GoogleAuthProvider();

    try {
      // Sign in with a pop-up window
      const result = await signInWithPopup(auth, provider);

      // Pull signed-in user credential.
      const user = result.user;
    } catch (err) {
      // Handle errors here.
      const errorMessage = err.message;
      const errorCode = err.code;

      setError(true);

      switch (errorCode) {
        case "auth/operation-not-allowed":
          setGoogleErrorMessage("Email/password accounts are not enabled.");
          break;
        case "auth/operation-not-supported-in-this-environment":
          setGoogleErrorMessage("HTTP protocol is not supported. Please use HTTPS.")
          break;
        case "auth/popup-blocked":
          setGoogleErrorMessage("Popup has been blocked by the browser. Please allow popups for this website.")
          break;
        case "auth/popup-closed-by-user":
          setGoogleErrorMessage("Popup has been closed by the user before finalizing the operation. Please try again.")
          break;
        default:
          setGoogleErrorMessage(errorMessage);
          break;
      }
    }
  };

  return (
    &amp;lt;div className='signupContainer'&amp;gt;
      &amp;lt;div className='signupContainer__box__google'&amp;gt;
        &amp;lt;button onClick={handleGoogleSignUp}&amp;gt;
          &amp;lt;span&amp;gt;
            &amp;lt;img src={googleLogo} alt='Google Logo' /&amp;gt;
          &amp;lt;/span&amp;gt;
            Sign Up with Google
        &amp;lt;/button&amp;gt;
          {error &amp;amp;&amp;amp; &amp;lt;p&amp;gt;{googleErrorMessage}&amp;lt;/p&amp;gt;}
      &amp;lt;/div&amp;gt;

          &amp;lt;div className='signupContainer__box__login'&amp;gt;
            &amp;lt;p&amp;gt;
              Already have an account? &amp;lt;Link to='/signin'&amp;gt;Sign In&amp;lt;/Link&amp;gt;
            &amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;From the code above in lines 3 to 7 you can see we imported &lt;code&gt;signInWithPopup&lt;/code&gt; method which authenticates users using a popup-based OAuth authentication flow, &lt;code&gt;GoogleAuthProvider&lt;/code&gt; which is an instance of the Google provider object and the &lt;code&gt;getAuth&lt;/code&gt; instance to connect to the Firebase authentication service.&lt;/p&gt;

&lt;p&gt;In lines 15 and 21 we instantiate the authentication service and the Google Authentication Provider respectively. We proceed to run an asynchronous operation with the &lt;code&gt;signInWithPopup&lt;/code&gt; method in line 23, if the operation succeeds the signed-in user is returned along with the provider's credential in the &lt;code&gt;result&lt;/code&gt; constant in line 23. To pull out the user's credentials like &lt;code&gt;displayName&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt; and &lt;code&gt;photoURL&lt;/code&gt; (this is the image attributed to the Google account the user used to sign-up) we implement &lt;code&gt;result.user&lt;/code&gt;, we may want to use these credentials on the home page to display the user's name or image.&lt;/p&gt;

&lt;p&gt;It’s always a best practice to handle errors in your code gracefully to enhance the user’s experience while interacting with your website. Plus, it is necessary to deal with form validation on both the client side and server side to ensure consistency in the user’s data that was input in the form fields. Lines 37 to 53 implement a switch statement to handle various error messages provided by Firebase authentication when signing up with the Google provider is unsuccessful, with these error messages we create appropriate feedback for the user based on the action taken by the user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fcp17lycozh2cyd69yjr0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fcp17lycozh2cyd69yjr0.png" alt="Sign up page interface" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to your Firebase console authentication page, and click the Users tab where all the users that have signed up on your website will be displayed showing the provider used for authentication under the Providers column. Google G icon will be displayed for users that sign up with Google.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sign-In Flow
&lt;/h2&gt;

&lt;p&gt;At this point, we will be implementing the sign-in authentication flow using password-based authentication and Google authentication provider to ease the sign-in process for the users without the constant pressure to remember their password.&lt;/p&gt;

&lt;h3&gt;
  
  
  Password-based Sign-In
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import { Link } from "react-router-dom";
import { useState } from "react";
import {
  signInWithEmailAndPassword,
  getAuth
} from "firebase/auth";

const PasswordSignIn = () =&amp;gt; {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState(false);
  const [errorMessage, setErrorMessage] = useState("");

  // Instantiate the auth service SDK
  const auth = getAuth();

  const handleChange = (e) =&amp;gt; {
    const { name, value } = e.target;

    if (name === "email") setEmail(value);
    if (name === "password") setPassword(value);
  };

  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();

    try {
      // Sign in with email and password in firebase auth service
      const userCredential = await signInWithEmailAndPassword(
        auth,
        email,
        password
      );

      // The signed-in user info
      const user = userCredential.user;
    } catch (err) {
     // Handle Errors here.
      const errorMessage = err.message;
      const errorCode = err.code;

      setError(true);
      console.log(errorCode)

      switch (errorCode) {
        case "auth/invalid-email":
          setErrorMessage("This email address is invalid.");
          break;
        case "auth/user-disabled":
          setErrorMessage(
            "This email address is disabled by the administrator."
          );
          break;
        case "auth/user-not-found":
          setErrorMessage("This email address is not registered.");
          break;
        case "auth/wrong-password":
          setErrorMessage("The password is invalid or the user does not have a password.")
          break;
        default:
          setErrorMessage(errorMessage);
          break;
      }
    }
  };

  return (
    &amp;lt;div className='signinContainer'&amp;gt;
      &amp;lt;div className='signinContainer__box'&amp;gt;
        &amp;lt;div className='signinContainer__box__inner'&amp;gt;
          &amp;lt;h1&amp;gt;Sign In&amp;lt;/h1&amp;gt;
          &amp;lt;form className='signinContainer__box__form' onSubmit={handleSubmit}&amp;gt;
            &amp;lt;input
              type='email'
              placeholder='Email'
              name='email'
              onChange={handleChange}
            /&amp;gt;
            &amp;lt;input
              type='password'
              placeholder='Password'
              name='password'
              onChange={handleChange}
            /&amp;gt;
            &amp;lt;button type='submit'&amp;gt;Sign In&amp;lt;/button&amp;gt;
            {error &amp;amp;&amp;amp; &amp;lt;p&amp;gt;{errorMessage}&amp;lt;/p&amp;gt;}
          &amp;lt;/form&amp;gt;

          &amp;lt;div className='signinContainer__box__signup'&amp;gt;
            &amp;lt;p&amp;gt;
              Don't have an account? &amp;lt;Link to='/signup'&amp;gt;Sign Up&amp;lt;/Link&amp;gt;
            &amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;The code for the sign-in flow using email/password is not too different from the signup flow code, the only difference is the &lt;code&gt;signInWithEmailAndPassword&lt;/code&gt; method imported in lines 4 to 9. We sign in the user in lines 26 to 30 with the email and password they entered in the form fields, and then we store the returned Promise inside the &lt;code&gt;userCredential&lt;/code&gt; constant. From this &lt;code&gt;userCredential&lt;/code&gt; constant, we get all the user's info using &lt;code&gt;userCredential.user&lt;/code&gt; as in line 33 above. Afterwards, we handle any errors in the catch block if the sign-in process failed. The appropriate error message feedback will be displayed in crimson color under the &lt;strong&gt;Sign In&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnk5j6ws8u81dkgjpcdmh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnk5j6ws8u81dkgjpcdmh.png" alt="Sign In interface displaying an error feedback" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Authentication Sign In
&lt;/h3&gt;

&lt;p&gt;The code that handles the sign-up and sign-in flow using the Google authentication provider is the same really since the user’s Google account email and password will always remain consistent considering the Google details were saved on the Firebase authentication during the sign-up process. The only thing that will change is just instead of a &lt;strong&gt;Sign Up With Google&lt;/strong&gt; button it will be a &lt;strong&gt;Sign In With Google&lt;/strong&gt; button.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signing Out
&lt;/h2&gt;

&lt;p&gt;The sign-out implementation is not complex, it’s pretty straightforward.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { signOut, getAuth } from "firebase/auth";

const Home = () =&amp;gt; {
 // Instantiate the auth service SDK
 const auth = getAuth();

  return (
    &amp;lt;section className='home'&amp;gt;
      &amp;lt;div className='home__container'&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; signOut(auth)}&amp;gt;Sign Out&amp;lt;/button&amp;gt;   
      &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;
  );
};
export default Home;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the code displayed above, we can see all we need to do is import the Firebase authentication SDKs, the &lt;code&gt;signOut&lt;/code&gt; and &lt;code&gt;getAuth&lt;/code&gt; method. The instantiated auth service SDK, &lt;code&gt;auth&lt;/code&gt; will be provided as an argument to the &lt;code&gt;signOut&lt;/code&gt; method we imported earlier. The current user will be signed out of the website and removed from the Firebase authentication user's account on clicking the Sign Out button.&lt;/p&gt;

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

&lt;p&gt;Firebase’s suite of products has been valuable in building dynamic, efficient web and mobile applications among them being the authentication service, it also provides tools to monitor deployed applications’ performance like Crashlytics and Performance Monitoring. Firebase comes with a complete package of tools to aid companies, businesses and developers in creating top-value digital products that tackle their customer’s pressing needs. We will be introduced to Firebase Firestore in my next Firebase article. Cheers✌&lt;/p&gt;

</description>
      <category>documentation</category>
    </item>
    <item>
      <title>Demystifying React 18</title>
      <dc:creator>Adekola Olawale</dc:creator>
      <pubDate>Sun, 16 Oct 2022 14:40:36 +0000</pubDate>
      <link>https://dev.to/adekolaolawale/demystifying-react-18-56bb</link>
      <guid>https://dev.to/adekolaolawale/demystifying-react-18-56bb</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0yrPyo65--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AuTitDuBGONygRJY3tpLJ8g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0yrPyo65--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AuTitDuBGONygRJY3tpLJ8g.png" alt="Demystifying React cover image" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;React 18 is a major improvement in the rendering mechanisms of React. The focus was on improved performance of user interfaces for a much better experience for the user on the website.&lt;/p&gt;

&lt;p&gt;The newly added features are completely user-centred, to make sure users don’t wait too long before interacting with the website, which translates to significantly less bounce rate on the site, more lead conversion and increased revenue for businesses. This is a win-win for users and businesses, everybody is happy and the world is all the better for it😀.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migration to React 18
&lt;/h2&gt;

&lt;p&gt;Upgrade to React 18 only applies to React projects built before React 18 was released. Projects created after React 18 release do not need to bother about a manual upgrade, as the React project will automatically come with the new React 18 features.&lt;/p&gt;

&lt;p&gt;To begin with, React and ReactDOM has to be re-installed in the project to get the new APIs and the concurrent rendering mechanism (we will talk about this soon enough) that comes with React and ReactDOM.&lt;br&gt;
&lt;/p&gt;

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

// yarn install
yarn add react react-dom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start enjoying the new shiny features shipped with React 18, we need to bring the new root API into the project. The new root API is the main feature that introduces the concurrent rendering mechanism, which is the coolest thing about the React 18 upgrade if you ask me.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Before React 18
import React from 'react'
import ReactDOM from 'react-dom';
import App from 'App';

ReactDOM.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;,
  document.getElementById('root')
)


// After React 18
import React from 'react'
import { createRoot } from 'react-dom/client';
import App from 'App';

const root = createRoot(document.getElementById('root'))

root.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://twitter.com/rickhanlonii"&gt;Rick Hanlon’s&lt;/a&gt; &lt;a href="https://github.com/reactwg/react-18/discussions/5"&gt;discussions&lt;/a&gt; on the differences between the two root APIs stated that the Legacy Root API is the API we have been using to create our web application’s root pre-React 18 release, and the New Root API is the upgraded API that introduces the most efficient and functional performance on React projects’ rendering mechanism yet.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;root&lt;/strong&gt; in React is like a container that houses all the elements/nodes/components in a React project. It is a top-level data structure that serves as a reference point from which the rest of the components in the DOM tree are descended.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concurrent Rendering
&lt;/h2&gt;

&lt;p&gt;According to the Merriam-Webster dictionary, concurrent means &lt;strong&gt;&lt;em&gt;operating or occurring at the same time.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Concurrent Rendering is a rendering mechanism which involves making urgent user actions (like clicking and typing) a priority in the UI rendering process. This means any less urgent task on the UI can be interrupted and put on hold in its rendering process while the more urgent task takes precedence.&lt;/p&gt;

&lt;p&gt;Dan Abramov’s &lt;a href="https://github.com/reactwg/react-18/discussions/46#discussioncomment-846650"&gt;&lt;em&gt;concise explanation of concurrency&lt;/em&gt;&lt;/a&gt; is a perfect analogy to comprehend this workflow. Imagine this scenario; you are having a chat with your friend, and unexpectedly a message was sent by your boss, the tone of this message seems urgent. The boss needs some information sent to her immediately. Well, what do you do? You tell your friend to wait because you need to send something urgent to your boss. Moments later you are done with the task your boss requested, and then you resume chatting with your friend.&lt;/p&gt;

&lt;p&gt;Concurrency in this context allows you to put your friend on hold and respond to your boss, which is an efficient way to handle communication with multiple parties at the same time. Non-concurrency on the other hand makes sure you conclude the conversation with your friend before responding to your boss, which is not ideal. I can assure this course of action can get you fired.&lt;/p&gt;

&lt;p&gt;The messages sent in this case are the &lt;strong&gt;&lt;em&gt;state&lt;/em&gt;&lt;/strong&gt; updates that happen behind the scenes, say a website a loading all DOM nodes in the component tree and a user wants to navigate to the contact page from the navigation bar, this latest user action will take precedence over the rendering of the component tree at the moment, the rendering process will be interrupted and the website will display the contact page accordingly.&lt;/p&gt;

&lt;p&gt;The debut of concurrency brought about the reveal of the transition feature when the transition feature is implemented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transitions
&lt;/h2&gt;

&lt;p&gt;Transitions are a massive upgrade for React in handling slow user interactions in the user interface due to high latency in the network connection of the end user or the complexity and large size of the data packets that go through the TCP (Transmission Control Protocol) connection layer.&lt;/p&gt;

&lt;p&gt;With that said, it is vital to understand how big a problem transitions are solving. Until React 18, the rendering process regarding state updates has been done indiscriminately by the React engine. However, with the debut of the concurrent rendering mechanism, as we discussed earlier transitions can work perfectly as the transition feature was built to work with concurrency.&lt;/p&gt;

&lt;p&gt;React 18 now provides an API called &lt;strong&gt;&lt;em&gt;startTransition,&lt;/em&gt;&lt;/strong&gt; this API provides the option of prioritizing the urgency of user interactions in the user interface. Users’ actions like clicking, typing or pressing can be prioritized as urgent over less urgent tasks like UI changes such as the display of search results.&lt;/p&gt;

&lt;p&gt;For instance, you visit a website that displays software development jobs and decides to search for frontend jobs, intermediate roles, and remote &amp;amp; hybrid jobs. Let’s say these filters as represented as checkboxes on the UI, when you click these checkboxes you would expect them to respond by displaying a checkmark in the box, although it is okay for the search results to take a few moments to display.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;startTransition&lt;/em&gt;&lt;/strong&gt; API helps improve the user’s experience on the UI by making their interactions intuitive. Imagine you are trying to open the Twitter app on your phone, the moment you tap on the app you would expect it to respond by showing the splash screen, at this point, you would expect the display of UI content to take a moment.&lt;/p&gt;

&lt;p&gt;However, on the flip side if you were to tap on the app it takes a while to show a splash or some sort of visual feedback to affirm your tap action you will assume your phone is frozen right? I wager, if only the Twitter app keeps acting this way, it won’t take long before you remove it from your phone.&lt;/p&gt;

&lt;p&gt;This is the problem transition is solving, making sure the user interface doesn’t freeze due to response to multiple state updates based on user actions. To enjoy the transition feature, wrap less urgent tasks, like UI transitions from one view to another, inside the &lt;strong&gt;&lt;em&gt;startTransition&lt;/em&gt;&lt;/strong&gt; feature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { UpButton, DownButton } from "./Icons";
import { useEffect, useState, useTransition } from "react";
import Spinner from "./Spinner";

const BOOK_URL = "http://localhost:3000/books.json";

const Book = ({ title, author, publicationYear }) =&amp;gt; {
  return (
    &amp;lt;div className={styles.book}&amp;gt;
      &amp;lt;h2 className={styles.bookTitle}&amp;gt;{title}&amp;lt;/h2&amp;gt;
      &amp;lt;p className={styles.bookDescription}&amp;gt;
        Published by &amp;lt;strong&amp;gt;{author}&amp;lt;/strong&amp;gt; in &amp;lt;em&amp;gt;{publicationYear}&amp;lt;/em&amp;gt;
      &amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

const Transition = () =&amp;gt; {
  const [books, setBooks] = useState(null);
  const [search, setSearch] = useState("");
  const [loading, setLoading] = useState(false);
  const [startTransition, isPending] = useTransition();

  // Handle search change
  const handleChange = (e) =&amp;gt; {
    let lowerCaseSearch = e.target.value.toLowerCase();

    setSearch(lowerCaseSearch);
  };

  useEffect(() =&amp;gt; {
    setLoading(true);
    setTimeout(fetchBook, 2000);
  }, []);

  const fetchBook = async () =&amp;gt; {
    try {
      const res = await fetch(BOOK_URL);
      const data = await res.json();
      setBooks(data.books);
      setLoading(false);
    } catch (err) {
      console.log(err);
    }
  };

  // Filter books by search query
  const filteredBooks = books?.filter((book) =&amp;gt; {
    /* 
      Relegate the transition of the UI based on the 
      filtering process to the background
    */
    startTransition(() =&amp;gt; {
      return (
        book.title.toLowerCase().includes(search) ||
        book.author.toLowerCase().includes(search)
      );
    });
  });

  /* 
    Render Spinner if fetching data or state update
    will take a while
  */
  if (isPending || loading) return &amp;lt;Spinner /&amp;gt;;

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;header className={styles.header}&amp;gt;
        &amp;lt;input
          type='search'
          id='search'
          placeholder='Search books...'
          className={styles.search}
          onChange={handleChange}
        /&amp;gt;
      &amp;lt;/header&amp;gt;
      &amp;lt;main&amp;gt;

        {/* Render books */}
        {filteredBooks &amp;amp;&amp;amp; (
          &amp;lt;div style={isPending ? styles.pending : styles.done}&amp;gt;
            {filteredBooks.map((book, index) =&amp;gt; (
              &amp;lt;Book
                title={book.title}
                author={book.author}
                publicationYear={book.publicationYear}
                key={index}
              /&amp;gt;
            ))}
          &amp;lt;/div&amp;gt;
        )}
      &amp;lt;/main&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;Let’s say we want to create a page where books coming from an API url can be displayed. This page will have a search field where the value typed into it will filter the list of books displayed on the page. Now assume that the amount of data coming from the API is ginormous and the network connection (get the data from the server the API is stored) is very slow. This means while the user is typing in the input field, the letters would be slow to appear.&lt;/p&gt;

&lt;p&gt;This is because the React engine is rendering both the filter query state update and the transition of the UI based on the characters typed into the input all at the same time. Doing this will result in a lag in the webpage performance, developers have always handled this in the past with &lt;a href="https://blog.webdevsimplified.com/2022-03/debounce-vs-throttle"&gt;debouncing and throttling&lt;/a&gt;. But even with these concepts state updates will still take a certain amount of time (based on the setTimeout delay value) before a user action reflects on the page. This kind of delay is very crucial regardless of how short it is, it leaves the user thinking the web page is broken.&lt;/p&gt;

&lt;p&gt;In our case, all we need do is just wrap code that filters the book lists with &lt;strong&gt;&lt;em&gt;startTransition.&lt;/em&gt;&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;// Filter books by search query
const filteredBooks = books?.filter((book) =&amp;gt; {
  /* 
    Relegate the transition of the UI based on the 
    filtering process to the background
  */
  startTransition(() =&amp;gt; {
    return (
      book.title.toLowerCase().includes(search) ||
      book.author.toLowerCase().includes(search)
    );
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you might wonder how you may show the user a visual clue that the data they requested is on its way, loading in the background. React 18 provides another feature called &lt;strong&gt;&lt;em&gt;isPending,&lt;/em&gt;&lt;/strong&gt; which we can pull from the &lt;strong&gt;&lt;em&gt;useTransition&lt;/em&gt;&lt;/strong&gt; hook API along with the &lt;strong&gt;&lt;em&gt;startTransition&lt;/em&gt;&lt;/strong&gt; feature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useTransition } from 'react';
import Spinner from './Spinner';

const { startTransition, isPending } = useTransition();

// Filter books by search query
const filteredBooks = books?.filter((book) =&amp;gt; {
  /* 
    Relegate the transition of the UI based on the 
    filtering process to the background
  */
   startTransition(() =&amp;gt; {
     return (
       book.title.toLowerCase().includes(search) ||
       book.author.toLowerCase().includes(search)
     );
   });
});

/* 
  Render Spinner if fetching data or state update
  will take a while
*/
if (isPending || loading) return &amp;lt;Spinner /&amp;gt;;

{/* Books should be rendered here */}
{filteredBooks &amp;amp;&amp;amp; (  
  &amp;lt;div&amp;gt;
    {filteredBooks.map((book, index) =&amp;gt; (
      &amp;lt;Book
        title={book.title}
        author={book.author}
        publicationYear={book.publicationYear}
        key={index}
      /&amp;gt;
    ))}
   &amp;lt;/div&amp;gt;
 )}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the &lt;strong&gt;&lt;em&gt;useTransition&lt;/em&gt;&lt;/strong&gt; hook API, we pulled in &lt;strong&gt;&lt;em&gt;isPending&lt;/em&gt;&lt;/strong&gt; then we implemented a conditional rendering to handle situations when the filtering process or pulling data from API on the backend might take a while. The &lt;strong&gt;&lt;em&gt;isPending&lt;/em&gt;&lt;/strong&gt; feature mainly aims to optimize the user experience so that they don’t have to wonder what is happening in the background.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;em&gt;useId&lt;/em&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;useId&lt;/em&gt;&lt;/strong&gt; hook API was created mainly to help developers build better accessible websites for more inclusivity in the usage of websites. Also to tackle the issue of inconsistency in client and server rendering of the component tree.&lt;/p&gt;

&lt;p&gt;When React is displaying the UI to the user it works with a process called &lt;a href="https://github.com/reactwg/react-18/discussions/37"&gt;&lt;strong&gt;hydration&lt;/strong&gt;&lt;/a&gt;, this means the server spills out the components as dry HTML and then the client (browser) hydrates the HTML with the water of interactivity via the event handlers coming from JavaScript. For this hydration to work appropriately, the browser's UI output must match the server's HTML output. useId helps to solve these challenges pre-React 18.&lt;/p&gt;

&lt;p&gt;With useId, we can generate unique IDs for accessibility attributes whenever we are dealing with form controls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useId } from "react";

const FormControl = () =&amp;gt; {
  // Generate unique IDs for the input fields
  const formControlId = useId();
  const passwordHintId = useId();

  return (
    &amp;lt;form&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;label htmlFor={`${formControlId}-firstName`}&amp;gt;First Name:&amp;lt;/label&amp;gt;
        &amp;lt;input id={`${formControlId}-firstName`} type='text' /&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div&amp;gt;
        &amp;lt;label htmlFor={`${formControlId}-lastName`}&amp;gt;Last Name:&amp;lt;/label&amp;gt;
        &amp;lt;input id={`${formControlId}-lastName`} type='text' /&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div&amp;gt;
        &amp;lt;label htmlFor={`${formControlId}-password`}&amp;gt;Password:&amp;lt;/label&amp;gt;
        &amp;lt;input
          id={`${formControlId}-password`}
          type='password'
          aria-describedby={passwordHintId}
        /&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;p id={passwordHintId}&amp;gt;
        The password should contain at least 6 characters
      &amp;lt;/p&amp;gt;

      &amp;lt;button type='submit'&amp;gt;Submit&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;&lt;em&gt;htmlFor&lt;/em&gt;&lt;/strong&gt; prop on the label elements aids screen-reader users in accessing form fields easily because the screen-reader will read out loud the label when the user focus on the input field. To ensure no two label/input groups are sharing the same ids, we implement the &lt;strong&gt;&lt;em&gt;useId&lt;/em&gt;&lt;/strong&gt;  hook.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;useId&lt;/em&gt;&lt;/strong&gt; is also used to create a unique id value for the &lt;strong&gt;&lt;em&gt;aria-describedby&lt;/em&gt;&lt;/strong&gt; prop which allows us to provide rich and descriptive information about the password input field for screen-reader users. The id value returned from &lt;strong&gt;&lt;em&gt;useId&lt;/em&gt;&lt;/strong&gt; is something like  &lt;strong&gt;&lt;em&gt;:r1:&lt;/em&gt;&lt;/strong&gt; or  &lt;strong&gt;&lt;em&gt;:r2:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One last thing, do not make the mistake of using the useId value as a substitute to generate keys in a list.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  useDeferredValue
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;useDeferredValue&lt;/em&gt;&lt;/strong&gt; hook API is another feature that works similarly to &lt;strong&gt;&lt;em&gt;startTransition,&lt;/em&gt;&lt;/strong&gt; which is regarding the way state updates are handled gracefully to optimize the user’s experience. &lt;strong&gt;&lt;em&gt;useDeferredValue&lt;/em&gt;&lt;/strong&gt; takes any value passed to it as an argument, returns the previous state of the value while the rendering process is going on in the background then displays the new state of value on the UI the moment the rendering process is completed.&lt;/p&gt;

&lt;p&gt;It defers display of the new state until rendering is complete, while the rendering is happening it shows the previous state to the user. This deferred value can trigger visual feedback for the user to keep track of the rendering taking place in the background.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useDeferredValue } from 'react'

function DeferValue() {
  /*
    The current query is controlled by some state that we don't control. It may even be managed 
    by an external store
  */
   const query = useSearchQuery();

   /*
     We don't need the suggestions to update immediately. We just need to keep showing
     the previous results until the new results are accessible
   */
   const deferredQuery = useDeferredValue(query);

   return (
     &amp;lt;&amp;gt;
       {/* The search input updates immediately */}
       &amp;lt;SearchInput query={query} /&amp;gt;

       {/* The suggestions update in a later frame */}
       &amp;lt;Suspense fallback="Loading results..."&amp;gt;
         &amp;lt;SearchSuggestions query={deferredQuery} /&amp;gt;
       &amp;lt;/Suspense&amp;gt;
     &amp;lt;/&amp;gt;   
   );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;useDeferredValue&lt;/em&gt;&lt;/strong&gt; might seem very similar to &lt;strong&gt;&lt;em&gt;startTransition&lt;/em&gt;&lt;/strong&gt; , but there is one major difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;startTransition&lt;/em&gt;&lt;/strong&gt; is used when triggering an update (i.e. &lt;strong&gt;&lt;em&gt;setState&lt;/em&gt;&lt;/strong&gt; ) based on a change in an event that our code can control like &lt;strong&gt;&lt;em&gt;onClick&lt;/em&gt;&lt;/strong&gt; , &lt;strong&gt;&lt;em&gt;onChange&lt;/em&gt;&lt;/strong&gt; , &lt;strong&gt;&lt;em&gt;onFocus&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;useDeferredValue&lt;/em&gt;&lt;/strong&gt; is used when receiving new data from a parent component or based on an event change controlled by an external store like a change in url query or parameter.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Automatic Batching
&lt;/h2&gt;

&lt;p&gt;Batching in React aid in grouping two or more state updates into one re-render. This creates a much better performance of React projects ultimately optimizing the user’s experience.&lt;/p&gt;

&lt;p&gt;With React 17 multiple state updates are only batched when placed in event handlers, anything outside React event handlers is not batched which would have led to unnecessary re-renders. React 18 takes care of this issue by automatically grouping any set of state updates into a re-render in one fell swoop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function AutoBatch() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  // Before React 18: only React events were batched.
  setTimeout(() =&amp;gt; {
    setCount((prevCount) =&amp;gt; prevCount + 1);
    setFlag((prevFlag) =&amp;gt; !prevFlag);
    // React will render twice, once for each state update (no batching)
  }, 1000);

  /*
  After React 18: updates inside of timeouts, promises,
  native event handlers or any other event are now automatically batched.
*/
  setTimeout(() =&amp;gt; {
    setCount((prevCount) =&amp;gt; prevCount + 1);
    setFlag((prevFlag) =&amp;gt; !prevFlag);
    /* 
    React will only re-render once at the end by grouping
    the count &amp;amp; flag state updates
  */
  }, 1000);
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1 style={{ color: flag ? "blue" : "black" }}&amp;gt;{count}&amp;lt;/h1&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine a scenario where you went out to the nearest grocery store to purchase milk, you came back home and immediately you arrived home you remembered you forgot to get some eggs, and then back at home again you did not remember to buy the peanut butter spread. I think we can all agree going back and forth to the grocery store in one day is pretty inefficient and unproductive. However, let’s say before heading to the store you decide to sit down and write down all the items that you need to procure for that day or the next. Afterwards, you head to the store with your head held high confident of what you want and your item list. This will save you time, money and energy going back and forth.&lt;/p&gt;

&lt;p&gt;It’s the same concept as how automatic batching works and the problem it solves, which is preventing wasted re-renders.&lt;/p&gt;

&lt;h2&gt;
  
  
  Suspense
&lt;/h2&gt;

&lt;p&gt;React 18 came with a major upgrade in how the &lt;a href="https://github.com/reactwg/react-18/discussions/37"&gt;&lt;em&gt;&lt;/em&gt;&lt;/a&gt; component feature works. Now it’s not only meant for code splitting with &lt;em&gt;React.lazy&lt;/em&gt; but integration with the newly improved Server-Side Rendering (SSR) architecture for React.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;/em&gt; is now used to solve critical problems in the server-side rendering process, which involves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetch data for the entire app from the server.&lt;/li&gt;
&lt;li&gt;Render that data to HTML and send it in the response.&lt;/li&gt;
&lt;li&gt;Load the JavaScript code from the client for the entire app.&lt;/li&gt;
&lt;li&gt;Connect the JavaScript logic to the server-generated HTML for the entire app (this is &lt;strong&gt;hydration&lt;/strong&gt; ).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the whole process outlined above to work smoothly, each step needs to be completed before the next step can pick up. In such instances, UX will be affected causing a sort of bottleneck in the whole operation. This is where &lt;em&gt;&lt;/em&gt; comes in to combat this SSR problem. It does this by breaking each stage in the flow apart so that there is no need for the next stage to rely on the preceding stage to execute its part in the flow.&lt;/p&gt;

&lt;p&gt;With React 18, two critical SSR features are made available by &lt;em&gt;:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Streaming HTML on the server.&lt;/li&gt;
&lt;li&gt;Selective Hydration on the client.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wAjMZFr8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AGeih6dpIiX2xlf3wAEE6bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wAjMZFr8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AGeih6dpIiX2xlf3wAEE6bg.png" alt="Streaming HTML" width="880" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streaming HTML&lt;/strong&gt; on the server simply means the server will keep sending HTML-rendered data to the client (browser) even if some components of the entire app might be experiencing a lag in transfer due to a slow database or API layer, which might be out of your control. Let’s say we are building an app that renders a post with comments, so instead of waiting to collect all the data for the app on the server before sending any HTML to the client. We can decide to implement the &lt;em&gt;&lt;/em&gt; SSR feature, which streams the HTML output from the server to the client for display on the UI while the comment component can be fetched in the background and replaced by a Spinner fallback placeholder until all the comment data are available for the user’s view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Layout&amp;gt;
  &amp;lt;NavBar /&amp;gt;
  &amp;lt;Sidebar /&amp;gt;
  &amp;lt;RightPane&amp;gt;
    &amp;lt;Post /&amp;gt;
    &amp;lt;Suspense fallback={&amp;lt;Spinner /&amp;gt;}&amp;gt;
      &amp;lt;Comments /&amp;gt;
    &amp;lt;/Suspense&amp;gt;
  &amp;lt;/RightPane&amp;gt;
&amp;lt;/Layout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wrapping the comments component with the &lt;em&gt;&lt;/em&gt; feature helps us save face from our users, which guarantees they will be back to view more posts on our web app 👌.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Selective Hydration&lt;/strong&gt; allows your users to start interacting with components on your website even though the JavaScript code for some components might not be available yet. This prevents awkward situations where users have to wait for your web app to complete its entire rendering process before they can start interacting with it.&lt;/p&gt;

&lt;p&gt;With &amp;lt;&lt;em&gt;Suspense/&amp;gt;&lt;/em&gt; the browser can selectively hydrate any component whose JavaScript code is accessible and hydrate the bare-bone HTML output with functionality and event handlers that makes the app come alive. The moment the JavaScript code for the comments component is obtainable, then the browser starts hydrating the component for the web app interactivity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o2J6d_jE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AW4HevchqFACOSBPDwzlC-Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o2J6d_jE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AW4HevchqFACOSBPDwzlC-Q.png" alt="Selective Hydration" width="880" height="664"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The release of React 18 is already a game changer in how developers build digital products and quality of experience for the users. Kudos to all the contributors and maintainers of this fantastic library, they made sure nothing was taken away from the DX (Developer Experience)and UX (User Experience), and instead added much more to it.&lt;/p&gt;

&lt;p&gt;Concurrent rendering mechanism, automatic batching and improving on SSR architecture prove React is getting smarter and better as it matures. I am here for React growth.&lt;/p&gt;

&lt;p&gt;Now let me go start conceptualizing an exciting project that will enjoy all the joys React 18 brings to the interwebs 😉.&lt;/p&gt;

</description>
      <category>webperf</category>
      <category>react</category>
      <category>webdev</category>
      <category>react18</category>
    </item>
    <item>
      <title>Using Redux Toolkit to Handle Asynchronous Data Requests</title>
      <dc:creator>Adekola Olawale</dc:creator>
      <pubDate>Wed, 05 Oct 2022 18:43:46 +0000</pubDate>
      <link>https://dev.to/adekolaolawale/using-redux-toolkit-to-handle-asynchronous-data-requests-54om</link>
      <guid>https://dev.to/adekolaolawale/using-redux-toolkit-to-handle-asynchronous-data-requests-54om</guid>
      <description>&lt;p&gt;Before the arrival of the Redux Toolkit (initially named Redux Starter Kit) in October 2019, fetching data asynchronously from the backend via Redux is always too much of a hassle. Developers had to settle with the Redux Thunk middleware package to handle asynchronous logic, which involves quite some amount of boilerplate code to be set up and some installation of packages to be made before executing the async logic.&lt;/p&gt;

&lt;p&gt;Redux Thunk middleware is a function that intercepts actions dispatched from the system, triggered by users’ actions on the interface like clicking a post button, and checks if the action is a function, if so it calls that function by returning it. The function, in this case, is an asynchronous function returning a promise, once the promise is resolved or rejected as the case may be, an appropriate action creator will be dispatched to the reducer which ultimately conveys a response back to the component the action was initially executed on.&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%2F9otg6c6mmm21zyafobus.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%2F9otg6c6mmm21zyafobus.png" alt="Simple createAsyncThunk Logic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code syntax above is a perfect example of how the Redux Thunk middleware can be implemented. &lt;strong&gt;addPost&lt;/strong&gt; function is an asynchronous action creator which serves as the middleware that returns the action function by intercepting the &lt;strong&gt;ADD_POST&lt;/strong&gt; action from the frontend and subsequently executes a fetch post request to the backend, and then ultimately dispatches (with the &lt;strong&gt;dispatch&lt;/strong&gt; method) the action type and payload from the form controls on the frontend to the reducer to execute the appropriate logic for adding a post to the view. This is just a concise way of using the Redux Thunk middleware to give you an idea of how it works. But the configuration flow is whole another process in and of itself.&lt;/p&gt;

&lt;p&gt;The configuration process of the Redux Thunk middleware is mostly unnecessarily complex and time-consuming, the time used to properly configure this library can be better used on writing the async logic.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;createAsyncThunk&lt;/strong&gt; API (Application Programming Interface) comes in to save the day by saving you time and energy. This powerful API abstracts away most of the unnecessary parts of the Redux Thunk middleware for better developer productivity. &lt;strong&gt;createAsyncThunk&lt;/strong&gt; API accepts two arguments: an &lt;strong&gt;action type string&lt;/strong&gt; and a &lt;strong&gt;payload creator callback function&lt;/strong&gt;. The action type string argument generates corresponding action types for the Promise lifecycle; &lt;strong&gt;pending, fulfilled, and rejected&lt;/strong&gt;. The payload creator callback function handles the asynchronous responses and requests to and from the backend and ultimately returns a Promise, the kind of Promise depends on its lifecycle status: pending, fulfilled or rejected.&lt;/p&gt;

&lt;p&gt;To further solidify our understanding of the createAsync API, we will be building a lightweight web application that can create and read posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup the Redux Store
&lt;/h2&gt;

&lt;p&gt;Create a file named: &lt;em&gt;&lt;strong&gt;postsSlice.js&lt;/strong&gt;&lt;/em&gt; (this is where most of the Redux logic will live). &lt;em&gt;&lt;strong&gt;postsSlice.js&lt;/strong&gt;&lt;/em&gt; will contain a slice of state for the posts data coming from the API. This file also gives access to the reducer that will be added to the store and the actions we will need to dispatch on any user action (clicking the &lt;strong&gt;Post&lt;/strong&gt; button to add a post).&lt;/p&gt;

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


import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

const initialState = {
  postItems: [],
  status: 'idle',
  error: null
}

// Get all the posts from the API
export const getPosts = createAsyncThunk('posts/getPosts', async (thunkAPI) =&amp;gt; {
  try {
    const res = await axios.get(url)
    return res.data
  } catch (err) {
    return thunkAPI.rejectWithValue({ error: err.message })
  }
})

// Handle POST request to create a new post
export const addPost = createAsyncThunk(
  // The name of the action
  'posts/addPost',
  // The payload creator
  async (initialPost, thunkAPI) =&amp;gt; {
    try {
      const res = await axios.post(url, initialPost)
      return res.data
    } catch (err) {
      return thunkAPI.rejectWithValue({ error: err.message })
    }
  }
)

const postSlice = createSlice({
  /* The name of the slice[this will also be used as the action type string 
    in combination with the extraReducer name i.e posts/getPosts or posts/addPost] 
  */
  name: 'posts',
  // initialState: initialState[ES6 destructuring syntax]
  initialState,
  // Add reducers for the synchronous actions on the UI[we are not using this property for this tutorial]
  reducers: {},
  // Add extraReducers for the asynchronous actions on the UI 
  extraReducers: {
    [getPosts.pending]: (state, action) =&amp;gt; {
      // When data is being fetched
      state.status = 'loading'
    },
    [getPosts.fulfilled]: (state, action) =&amp;gt; {
      // When data is fetched successfully
      state.status = 'successful'

      // Concatenate the new data to the existing data in the array
      state.postItems = state.postItems.concat(action.payload)
    },
    [getPosts.rejected]: (state, action) =&amp;gt; {
      // When data is fetched unsuccessfully
      state.status = 'failed'

      // Update the error message for proper error handling
      state.error = action.error.message
    },
    [addPost.fulfilled]: (state, action) =&amp;gt; {
      // Add the new post created on the UI to the existing posts
      state.postItems.push(action.payload)
    },   
  }
})

// Export the reducer logic from the slice
export default postsSlice.reducer


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

&lt;/div&gt;

&lt;p&gt;From the contents of the &lt;em&gt;&lt;strong&gt;postSlice.js&lt;/strong&gt;&lt;/em&gt; file above, you can see a lot is going on there, so I will break it down in detailed steps (also pay attention to the comments above each line of code).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We import the &lt;em&gt;&lt;strong&gt;createSlice &amp;amp; createAsyncThunk&lt;/strong&gt;&lt;/em&gt; API from Redux Toolkit to create the slice of state for the posts coming from the API and createAsyncThunk to handle the asynchronous requests to and from the API. The &lt;em&gt;&lt;strong&gt;axios&lt;/strong&gt;&lt;/em&gt; package is to deal with the HTTP &lt;em&gt;&lt;strong&gt;get&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;post&lt;/strong&gt;&lt;/em&gt; requests effortlessly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an &lt;em&gt;&lt;strong&gt;initialState&lt;/strong&gt;&lt;/em&gt; object for the reducer to work with the first time it is called from the store. We initialized the object with properties such as &lt;em&gt;&lt;strong&gt;postItems&lt;/strong&gt;&lt;/em&gt; array, status string(‘idle’), and an error object(null).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get the posts coming from the API and handle them asynchronously. This can be done inside the &lt;em&gt;&lt;strong&gt;getPosts&lt;/strong&gt;&lt;/em&gt; function using the &lt;em&gt;&lt;strong&gt;createAsyncThunk&lt;/strong&gt;&lt;/em&gt; API we imported from the Redux Toolkit earlier. &lt;em&gt;&lt;strong&gt;createAsyncThunk&lt;/strong&gt;&lt;/em&gt; contains two arguments; action type string (&lt;em&gt;&lt;strong&gt;posts/getPosts&lt;/strong&gt;&lt;/em&gt;) and the payload creator function (this is where we handle the HTTP &lt;em&gt;&lt;strong&gt;get&lt;/strong&gt;&lt;/em&gt; request for the API using the &lt;em&gt;&lt;strong&gt;axios&lt;/strong&gt;&lt;/em&gt; package we imported earlier). The &lt;em&gt;&lt;strong&gt;thunkAPI&lt;/strong&gt;&lt;/em&gt; parameter is an object provided by the createAsyncThunk API to help handle rejected Promise responses with one of its properties, &lt;em&gt;&lt;strong&gt;rejectWithValue&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new posts created from the UI (User Interface) to the API. The &lt;em&gt;&lt;strong&gt;addPosts&lt;/strong&gt;&lt;/em&gt; function handles this using the &lt;em&gt;&lt;strong&gt;createAsyncThunk&lt;/strong&gt;&lt;/em&gt; API. The syntax structure is the same as the &lt;em&gt;&lt;strong&gt;getPosts&lt;/strong&gt;&lt;/em&gt; function, the only slight difference is that we are implementing an HTTP post request to the backend API, and an &lt;em&gt;&lt;strong&gt;initialPost&lt;/strong&gt;&lt;/em&gt; parameter is added. This parameter stands for the existing posts already contained in the backend API, it’s kinda like we are using a spread operator to copy the existing posts’ state and concatenate it to the new post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A slice of state for posts is created using the &lt;em&gt;&lt;strong&gt;createSlice&lt;/strong&gt;&lt;/em&gt; API, this API creates a reducer logic and exports it as a reducer function which can be added to the store. createSlice makes it easier for developers to create action-type strings &amp;amp; action creators rather than manually creating them, making the code verbose. The &lt;em&gt;&lt;strong&gt;name&lt;/strong&gt;&lt;/em&gt; property declares a string value that specifies the state name: &lt;em&gt;&lt;strong&gt;posts&lt;/strong&gt;&lt;/em&gt;, the combination of the name property with the function name for the &lt;em&gt;&lt;strong&gt;reducers&lt;/strong&gt;&lt;/em&gt; or &lt;em&gt;&lt;strong&gt;extraReducers&lt;/strong&gt;&lt;/em&gt; automatically produces the action-type strings: &lt;em&gt;&lt;strong&gt;posts/getPosts&lt;/strong&gt;&lt;/em&gt; or &lt;em&gt;&lt;strong&gt;posts/addPosts&lt;/strong&gt;&lt;/em&gt; and the action creators: &lt;em&gt;&lt;strong&gt;getPosts &amp;amp; addPosts&lt;/strong&gt;&lt;/em&gt; functions. &lt;em&gt;&lt;strong&gt;initialState&lt;/strong&gt;&lt;/em&gt; property takes in initial data the store can work with when the UI is rendered. &lt;em&gt;&lt;strong&gt;reducers&lt;/strong&gt;&lt;/em&gt; property takes in functions that handle synchronous actions dispatched from the UI while the &lt;em&gt;&lt;strong&gt;extraReducers&lt;/strong&gt;&lt;/em&gt; property (we are more concerned about this property) is used to handle asynchronous actions dispatched to the backend API, a Promise is returned for these types of actions and it needs to be handled gracefully. The Promise returned has a lifecycle it goes through; pending, fulfilled &amp;amp; rejected. With each of these lifecycles, a logic is written that handles the data flow when it is loading from the backend, when it loads successfully and when the data request fails to be loaded. This is the purpose &lt;em&gt;&lt;strong&gt;[getPosts.pending], [getPosts.fulfilled], [getPosts.rejected] &amp;amp; [addPosts.fulfilled]&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;[getPosts.pending]&lt;/strong&gt;&lt;/em&gt; method handles the logic for when the data is being fetched from the backend API, at this point the initial state for &lt;em&gt;&lt;strong&gt;status&lt;/strong&gt;&lt;/em&gt; is updated from &lt;em&gt;&lt;strong&gt;loading&lt;/strong&gt;&lt;/em&gt; to &lt;em&gt;&lt;strong&gt;idle&lt;/strong&gt;&lt;/em&gt;. &lt;em&gt;&lt;strong&gt;[getPosts.fulfilled]&lt;/strong&gt;&lt;/em&gt; method deals with after the data has finished loading from the backend API, the &lt;em&gt;&lt;strong&gt;status&lt;/strong&gt;&lt;/em&gt; state is updated to &lt;em&gt;&lt;strong&gt;successful&lt;/strong&gt;&lt;/em&gt; and the newly fetched data is added to the empty &lt;em&gt;&lt;strong&gt;postItems&lt;/strong&gt;&lt;/em&gt; array which will contain all the posts coming from the API. &lt;em&gt;&lt;strong&gt;[getPosts.rejected]&lt;/strong&gt;&lt;/em&gt; method updates the &lt;em&gt;&lt;strong&gt;status&lt;/strong&gt;&lt;/em&gt; state to &lt;em&gt;&lt;strong&gt;failed&lt;/strong&gt;&lt;/em&gt; and the &lt;em&gt;&lt;strong&gt;error&lt;/strong&gt;&lt;/em&gt; state to the error message coming from the &lt;em&gt;&lt;strong&gt;thunkAPI.rejectWithValue&lt;/strong&gt;&lt;/em&gt; line in the &lt;em&gt;&lt;strong&gt;getPosts&lt;/strong&gt;&lt;/em&gt; function created earlier. &lt;em&gt;&lt;strong&gt;[addPosts.fulfilled]&lt;/strong&gt;&lt;/em&gt; only deals with when a new post is successfully added to the backend from the UI, the pending &amp;amp; fulfilled lifecycles are already handled through the getPosts.pending &amp;amp; getPosts.rejected methods since the logic for pending and rejected lifecycles are the same for both actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The createSlice API contains five properties: actions, caseReducers, getInitialState, name &amp;amp; reducer. To initialize a redux store a reducer needs to be added to it, which will serve as the initial data the UI can work with the moment it mounts. To be able to do this, a reducer needs to be pulled from the createSlice API logic. This is achieved by exporting the &lt;em&gt;&lt;strong&gt;postsSlice&lt;/strong&gt;&lt;/em&gt; object as a reducer, &lt;em&gt;&lt;strong&gt;export default postsSlice.reducer&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Add Data to Store
&lt;/h2&gt;

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

// Pull in configureStore API
import { configureStore } from '@reduxjs/toolkit';

// Pull in the postsSlice reducer and rename it to postsReducer
import postsReducer from '../features/posts/postsSlice';


// Create the Redux store and pass in the postsReducer as the initial data
export const store = configureStore({
  reducer: {
    posts: postsReducer,
  },
})


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

&lt;/div&gt;

&lt;p&gt;In any web application that handles state management with Redux, without the Redux store there is nothing that can be achieved with Redux. It is the same as building an application without using Redux. The Redux store is what ties in everything together and it’s from the store that the UI can pull data via the reducers.&lt;/p&gt;

&lt;p&gt;Updating the state through the application happens in the store after an action has been dispatched to the store, the reducer(s) inside can decide how to update data either by adding data to or removing it from the store based on the logic contained in the reducer function.&lt;/p&gt;

&lt;p&gt;We can see from the logic above, to create the Redux store, that it is the &lt;em&gt;&lt;strong&gt;configureStore API&lt;/strong&gt;&lt;/em&gt; imported from the Redux Toolkit that is bringing everything together. The reducer we exported from postsSlice.js is now imported and renamed as &lt;em&gt;&lt;strong&gt;postsReducer&lt;/strong&gt;&lt;/em&gt;. One of the great things about the &lt;em&gt;&lt;strong&gt;configureStore&lt;/strong&gt;&lt;/em&gt; API is that it automatically passes more than one reducer to the &lt;em&gt;&lt;strong&gt;combineReducers&lt;/strong&gt;&lt;/em&gt; utility behind the scenes. This utility was initially used to bring together two or more reducers before the arrival of the Redux Toolkit. This is one of the ways the Redux Toolkit help make the code much cleaner.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;&lt;strong&gt;posts: postsReducer&lt;/strong&gt;&lt;/em&gt; object communicates to the application globally that the data/state coming in from and added to the backend will be consumed as &lt;em&gt;&lt;strong&gt;state.posts&lt;/strong&gt;&lt;/em&gt; on the frontend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consuming State/Data on the Frontend
&lt;/h2&gt;

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


import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { getPosts } from '../features/posts/postsSlice'

const PostsList = () =&amp;gt; {
  const dispatch = useDispatch()

  // Get the posts from the store
  const posts = useSelector((state) =&amp;gt; state.posts)

  // Pull the post properties
  const { postItems, status, error } = posts

  useEffect(() =&amp;gt; {
    // eslint-disable-next-line no-unused-vars
    let isMounted = true

    // If status is 'idle', then fetch the posts data from the API
    if (status === 'idle') {
      dispatch(getPosts())
    }

    // Cleanup function
    return () =&amp;gt; {
      isMounted = false
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [status, dispatch])

  let bodyContent

  if (status === 'loading') {
    bodyContent = &amp;lt;div className="loader"&amp;gt;&amp;lt;/div&amp;gt;
  } else if (status === 'successful') {
    // Sort the posts by id in descending order
    const sortedPosts = postItems.slice().sort((a, b) =&amp;gt; b.id - a.id)

    // Map through the sorted posts and display them
    bodyContent = sortedPosts.map((post) =&amp;gt; (
      &amp;lt;div key={post.id}&amp;gt;
        &amp;lt;h3&amp;gt;{post.title}&amp;lt;/h3&amp;gt;
        &amp;lt;p&amp;gt;{post.body}&amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
    ))
  } else {
    // Display the error message
    bodyContent = &amp;lt;div&amp;gt;{error}&amp;lt;/div&amp;gt;
  }

  return &amp;lt;div&amp;gt;{bodyContent}&amp;lt;/div&amp;gt;
}

export default PostsList


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

&lt;/div&gt;

&lt;p&gt;Implementing the data/state coming from the store we will need to import a couple of packages. The &lt;em&gt;&lt;strong&gt;useSelector&lt;/strong&gt;&lt;/em&gt; hook aid in selecting the specific data/state we need from the store instead of pulling everything including the ones we don’t need. This ensures our application is unnecessarily bloated affecting performance as a result. &lt;em&gt;&lt;strong&gt;useDispatch&lt;/strong&gt;&lt;/em&gt; hook helps with dispatching actions (based on users’ actions on the UI) to the store for the reducer function to handle.&lt;/p&gt;

&lt;p&gt;Before the arrival of the &lt;em&gt;&lt;strong&gt;useSelector&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;useDispatch&lt;/strong&gt;&lt;/em&gt; hooks in 2019, the &lt;em&gt;&lt;strong&gt;connect()&lt;/strong&gt;&lt;/em&gt; method was used instead to wrap components that need the state/data coming from the Redux store. &lt;em&gt;&lt;strong&gt;mapStateToProps&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;mapDispatchToProps&lt;/strong&gt;&lt;/em&gt; functions were initially fulfilling the functions of &lt;em&gt;&lt;strong&gt;useSelector&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;useDispatch&lt;/strong&gt;&lt;/em&gt; respectively. To drastically reduce the boilerplate code used to connect a component to the Redux store, React-Redux released these hooks to improve developers’ experience.&lt;/p&gt;

&lt;p&gt;Line 6 -12 in the code is initializing the &lt;em&gt;&lt;strong&gt;useDispatch&lt;/strong&gt;&lt;/em&gt; hook for use later, &lt;em&gt;&lt;strong&gt;useSelector&lt;/strong&gt;&lt;/em&gt; is pulling the posts data from the store with &lt;em&gt;&lt;strong&gt;state.posts&lt;/strong&gt;&lt;/em&gt;. The posts data content (&lt;em&gt;&lt;strong&gt;postItems, status, error&lt;/strong&gt;&lt;/em&gt;) are pulled from the posts data we just got from the store via object destructuring.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;useEffect&lt;/strong&gt;&lt;/em&gt; hook is used to handle the side effects as a result of the asynchronous actions dispatched to the store and the Promise returned. We declare a condition to make sure no data fetch is happening before we dispatch the &lt;em&gt;&lt;strong&gt;getPosts&lt;/strong&gt;&lt;/em&gt; action to the store, where the reducer function deals with the fetch request coming in by going through the Promise lifecycles (&lt;em&gt;pending/fulfilled/rejected&lt;/em&gt;) and rendering the appropriate logic for each lifecycle. After the fetch request is resolved or rejected, we clean up our code cancelling any asynchronous tasks before the component unmounts. This prevents any sort of memory leaks.&lt;/p&gt;

&lt;p&gt;Line 30 — 51 in the code above a conditional statement is created to properly handle the actions from Promise lifecycles. When the status state is pending (the data is being fetched) then a loader is shown to the user, then when the data finish loading and it is successfully fetched, the posts are displayed in UI in a reverse chronological order to ensure any newly created post is displayed first on the page. However, if the data was unable to be fetched, then the error message returned by &lt;em&gt;&lt;strong&gt;thunkAPI.rejectWithValue()&lt;/strong&gt;&lt;/em&gt; in the reducer function should be displayed instead which is something like &lt;strong&gt;“Cannot read properties of undefined (reading ‘rejectWithValue’)”&lt;/strong&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%2Ftpzq4hyr1gvd9r92mjxr.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%2Ftpzq4hyr1gvd9r92mjxr.png" alt="Posts list from the API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating New Posts
&lt;/h2&gt;

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


import { useState } from 'react'
import { useDispatch } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import { addPost } from '../features/posts/postsSlice'

const CreatePost = () =&amp;gt; {
  // Set the initial state for the form
  const [title, setTitle] = useState('')
  const [body, setBody] = useState('')
  const [addPostRequestStatus, setAddPostRequestStatus] = useState('idle')

  // Get the dispatch function
  const dispatch = useDispatch()

  // Get the navigate function [replace the history.push() method]
  const navigate = useNavigate()

  // Handle form field value changes
  const onTitleChange = (e) =&amp;gt; setTitle(e.target.value)
  const onBodyChange = (e) =&amp;gt; setBody(e.target.value)

  /* 
    Get the Boolean value based on whether the form is empty or not &amp;amp;&amp;amp; the post request status.
    We use the Boolean value returned to toggle the disbale status submit button
  */
  const canSavePost =
    [title, body].every(Boolean) &amp;amp;&amp;amp; addPostRequestStatus === 'idle'

  // Handle form submission
  const handleAddPost = async (e) =&amp;gt; {
    e.preventDefault()
    const post = { title, body }
    if (canSavePost) {
      try {
        setAddPostRequestStatus('pending')
        await dispatch(addPost(post)).unwrap()
        setTitle('')
        setBody('')

        navigate('/')
      } catch (err) {
        console.error('Unable to create post:', err)
      } finally {
        setAddPostRequestStatus('idle')
      }
    }
  }

  return (
    &amp;lt;div className="create-post"&amp;gt;
      &amp;lt;div className="create-heading"&amp;gt;
        &amp;lt;h1&amp;gt;Create Post&amp;lt;/h1&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div className="form-container"&amp;gt;
        &amp;lt;h2&amp;gt;Add New Post&amp;lt;/h2&amp;gt;
        &amp;lt;form onSubmit={handleAddPost}&amp;gt;
          &amp;lt;div className="form-group"&amp;gt;
            &amp;lt;label htmlFor="title"&amp;gt;Title&amp;lt;/label&amp;gt;
            &amp;lt;input
              type="text"
              id="title"
              name="title"
              onChange={onTitleChange}
              value={title}
            /&amp;gt;

            &amp;lt;label htmlFor="bodyContent"&amp;gt;Content&amp;lt;/label&amp;gt;
            &amp;lt;textarea
              id="bodyContent"
              name="bodyContent"
              cols="30"
              rows="10"
              onChange={onBodyChange}
              value={body}
            /&amp;gt;

            &amp;lt;button type="submit" className="btn" disabled={!canSavePost}&amp;gt;
              Post
            &amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default CreatePost


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

&lt;/div&gt;

&lt;p&gt;We go ahead to import the needed packages to handle dispatch, navigation and local state management. You might be wondering why the useState hook is been used here in this component. Well, the reason is that updating the change of value in HTML form inputs is a local state that is only needed inside the CreatePost component and nowhere else.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;&lt;strong&gt;handleAddPost&lt;/strong&gt;&lt;/em&gt; function deals with what happens when the Post button has been clicked for submission to the backend.&lt;/p&gt;

&lt;p&gt;First, we check if the post can be saved based on whether any of the input is empty or not and if the status is &lt;em&gt;&lt;strong&gt;idle&lt;/strong&gt;&lt;/em&gt;, then the &lt;em&gt;&lt;strong&gt;title&lt;/strong&gt;&lt;/em&gt; and the &lt;em&gt;&lt;strong&gt;body&lt;/strong&gt;&lt;/em&gt; content from the input field is added to a &lt;em&gt;&lt;strong&gt;post&lt;/strong&gt;&lt;/em&gt; variable as an object.&lt;/p&gt;

&lt;p&gt;Afterwards, the &lt;em&gt;&lt;strong&gt;addPosts&lt;/strong&gt;&lt;/em&gt; method imported from the &lt;em&gt;&lt;strong&gt;postSlice.js&lt;/strong&gt;&lt;/em&gt; file earlier is dispatched as an action to the Redux store along with the &lt;em&gt;&lt;strong&gt;post&lt;/strong&gt;&lt;/em&gt; object carrying the &lt;em&gt;&lt;strong&gt;title&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;body&lt;/strong&gt;&lt;/em&gt; content from the form as a payload to be added to the backend.&lt;/p&gt;

&lt;p&gt;When all this is done the &lt;em&gt;&lt;strong&gt;title&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;body&lt;/strong&gt;&lt;/em&gt; input field is cleared by setting the state back to an empty string and the &lt;em&gt;&lt;strong&gt;useNavigate&lt;/strong&gt;&lt;/em&gt; hook is used to take the user to the home page displaying all the posts.&lt;/p&gt;

&lt;p&gt;Subsequently, we handle any possible error that might come up and set the request status back to its initial state, &lt;em&gt;&lt;strong&gt;idle&lt;/strong&gt;&lt;/em&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%2Foiw6j4kkupa604st32ou.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%2Foiw6j4kkupa604st32ou.png" alt="Create Post Interface"&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%2Feyb7rbpkz9h04qa96lvw.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%2Feyb7rbpkz9h04qa96lvw.png" alt="Newly Added Post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A new post has been added to the backend and sent back from the store to be displayed on the UI. Although the newly added post will disappear from UI when the page is reloaded, this lack of persistence of data is because the data was not added to an actual database on the backend.&lt;/p&gt;

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

&lt;p&gt;Redux Toolkit being an improved extension of the Redux state management has made life super easy for developers. The createAsyncThunk API helps you save a lot of time that would otherwise have been wasted in configuring so many boilerplate codes to handle asynchronous requests. That saved time can be better invested in writing code that truly matters. Please let this post be the little nudge you need to start using Redux Toolkit. Trust me you never regret it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PS: You can find the complete code here: &lt;a href="https://github.com/Kola92/redux-toolkit-tutorial" rel="noopener noreferrer"&gt;https://github.com/Kola92/redux-toolkit-tutorial&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>redux</category>
      <category>reduxtoolkit</category>
      <category>react</category>
    </item>
    <item>
      <title>Redux Toolkit: A More Concise Approach To Dealing With State Management</title>
      <dc:creator>Adekola Olawale</dc:creator>
      <pubDate>Mon, 26 Sep 2022 11:46:07 +0000</pubDate>
      <link>https://dev.to/adekolaolawale/redux-toolkit-a-more-concise-approach-to-dealing-with-state-management-254n</link>
      <guid>https://dev.to/adekolaolawale/redux-toolkit-a-more-concise-approach-to-dealing-with-state-management-254n</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hgFOMKR6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lwmx1i7sakwdqe6ucsql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hgFOMKR6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lwmx1i7sakwdqe6ucsql.png" alt="Redux Toolkit logo" width="880" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redux is one of the major state management tools used in efficiently dealing with states through single-page applications. Single Page Applications also known as SPAs have revolutionized the way websites on the internet are now built. These type of applications optimizes website load times, achieved as a result of the dynamic reload of the data from the server instead of a full page reload experience by users in the past.&lt;/p&gt;

&lt;p&gt;JavaScript frameworks and libraries like React, Vue &amp;amp; Angular implement state management for efficient data flow all through the application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Redux &amp;amp; MobX&lt;/strong&gt; are used for &lt;strong&gt;React&lt;/strong&gt; state management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ngrx/store&lt;/strong&gt; for &lt;strong&gt;Angular&lt;/strong&gt; state management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vuex&lt;/strong&gt; for &lt;strong&gt;Vue&lt;/strong&gt; state management&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is State Management?
&lt;/h2&gt;

&lt;p&gt;State Management deals with an efficient way to deal with the state in SPAs. There are only two to work with data in React: state and props. &lt;strong&gt;State&lt;/strong&gt; in React is the current data contained in a component at a certain moment in time in the lifecycle of a React web application. &lt;strong&gt;Props&lt;/strong&gt; provide the way to share data (i.e. state) with another component.&lt;/p&gt;

&lt;p&gt;A web application such as Twitter uses React on the frontend, say you want to search for a person, topic or keyword, and each feature of the app is fragmented into reusable components like the search functionality, so this means the search component is separated from other components like your Twitter home page. Getting the search term from the component that displays your home page would need a sort of communication between the search bar component and the home component so that the search term data can be made available to the home component.&lt;/p&gt;

&lt;p&gt;Analyzing the situation will cause some headaches, though it can be solved by creating a functional component of the search functionality in the home page component, and then lifting the state to the parent component, the home component, but this means the search component won’t be isolated as a reusable component, also solving the problem will create a sort of a busy and inefficient code.&lt;/p&gt;

&lt;p&gt;This is where Redux comes in to ensure a much cleaner code. Redux does this by allowing you to create a global store where changes in data are available all across the application, whether the home, search or any other component. Redux makes it possible for all the components in the codebase to be able to keep up with all the state changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Difference between Redux &amp;amp; Redux Toolkit
&lt;/h2&gt;

&lt;p&gt;The difference between Redux and Redux Toolkit is kinda synonymous with a comparison between vanilla JavaScript and React Vue or Angular. Redux Toolkit helps developers write less Redux logic and also implements minimal packages when configuring the Redux store. It helps developers save time and energy and aids in maximal efficiency.&lt;/p&gt;

&lt;p&gt;In the times past, configuring Redux has always been a hassle for developers especially when productivity is what watchword for projects that need to be built real quick. Redux Thunk is a package that was usually a nightmare for developers to implement, due to the time and effort it takes to get it up and running. It is a middleware that handles asynchronous requests and responses between the action creator function and reducer after an action is dispatched. With the Redux Toolkit, an API called configureStore is used to configure the Redux store and with comes a thunk middleware by default.&lt;/p&gt;

&lt;p&gt;One less package in your codebase helps make up a very lightweight build which in turn optimizes the web application performance for a better user experience.&lt;/p&gt;

&lt;p&gt;In one sentence: Redux Toolkit abstracts away most of the complicated aspects of Redux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Merits of Redux Toolkit
&lt;/h2&gt;

&lt;p&gt;Redux Toolkit comes with a bunch of APIs to ease developers’ workflow. Let’s try to understand the APIs that do most of the heavy lifting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;configureStore():&lt;/strong&gt; we mentioned this one briefly, it wraps around the &lt;strong&gt;createStore&lt;/strong&gt; API for Redux and combines reducers, so instead of using the &lt;strong&gt;combineReducers&lt;/strong&gt; helper function from Redux we just include all our reducers as an argument for the &lt;strong&gt;configureStore&lt;/strong&gt; API to reduce the reducers(see what I did there😎) into one single function. Plus the middleware it provides by default amongst which is the thunk middleware.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;createSlice():&lt;/strong&gt; in addition to the &lt;strong&gt;configureStore&lt;/strong&gt; API, this API is among the most used APIs when developers are implementing Redux Toolkit. It accepts the initial state and reducers object as arguments, inside this reducers object slice reducer function logic can be implemented plus the action types which are by default gotten from the syntax (name/action reducer function name). createSlice will join the &lt;strong&gt;&lt;em&gt;name&lt;/em&gt;&lt;/strong&gt; argument and &lt;strong&gt;&lt;em&gt;slice reducer function&lt;/em&gt;&lt;/strong&gt; in the code below to generate an action type like this: &lt;em&gt;name/action creator function&lt;/em&gt;. In the case of the two creator functions below, their respective action types will be &lt;strong&gt;&lt;em&gt;posts/postAdded&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;posts/postUpdated&lt;/em&gt;&lt;/strong&gt;. Redux Toolkit generates these action types and the action creator functions automatically from the slice reducer function, which saves us the stress of having to implement an action creator function logic and action types.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  import { createSlice, nanoid } from '@reduxjs/toolkit'
  import { sub } from 'date-fns'

  const initialState = [
    {
      id: 1,
      title: 'First Post!',
      content: 'Hello!',
      date: sub(new Date(), { minutes: 10 }).toISOString(), // Add 10 minutes to the new time created
   },
   {
     id: 2,
     title: 'Second Post',
     content: 'Hi there!',
     date: sub(new Date(), { minutes: 5 }).toISOString(), // Add 5 minutes to the new time created
  },
]

const postsSlice = createSlice({
  name: 'posts', // reducer name
  initialState, // initialState
  reducers: { // reducers object
    postAdded(state, action) { // postAdded action creator function
      reducer(state, action) {
        state.push(action.payload)
      },
      prepare(title, content, userId) { // function to prepare the post properties to be added to the backend on dispatching post/postAdded action
        return {
          payload: {
            id: nanoid(),
            date: new Date().toISOString(),
            title,
            content,
            user: userId,
          },
        }
      },
    }, 
    postUpdated(state, action) { // postUpdated action creator function
      const { id, title, content } = action.payload
      const existingPost = state.find((post) =&amp;gt; String(post.id) === id) // Find the specific post that has a post.id match from frontend to the id at the backend
      if (existingPost) { // If the such post was found update the title &amp;amp; content
        existingPost.title = title
        existingPost.content = content
      }
    },
  },
})

export const { postAdded, postUpdated } = postsSlice.actions // Export the actions to be implemented for dispatch from the appropriate component

export default postsSlice.reducer // Export reducer to be added to the redux store

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;createAsyncThunk():&lt;/strong&gt; This API accepts two arguments: an action type string and a payload creator callback function that makes asynchronous AJAX requests to the backend API and then returns a promise containing some data which will be the payload.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  import { createAsyncThunk } from "@redux/toolkit";

  const url = 'https://jsonplaceholder.typicode.com/posts';
  export const addNewPost = createAsyncThunk({
    // Action type string
    'post/addNewPost',
    // Payload creator callback function
    async (initialPosts) =&amp;gt; {
      // Send old data and new data to the backend server
      const response = await fetch(url, {
        method: 'POST',
        body: JSON.stringify({ ...initialPosts }),
        headers: {
          'Content-Type': 'application/json'
        }
      })

      const data = await response.json();
      return data
    }
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aside from the APIs explained, there are more Redux Toolkit APIs that can be used on any of your future projects, like the Redux Toolkit Query which is a great feature in Redux Toolkit that is used for fetching and caching data coming from an API server. Caching of data from the backend helps to optimize the website performance by storing the fetched backend data on the user’s computer memory so that when next they want to access the data it loads immediately without the need for another HTTP GET request to the server.&lt;/p&gt;

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

&lt;p&gt;A lot of developers are already implementing Redux Toolkit in their web applications for maximal efficiency in state management across the entire application. Redux Toolkit is going to get better as time progress, and one thing is for sure it has changed the workflow involving state management for the better.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S:&lt;/em&gt; If you like this post clap, share, or if you want to provide some feedback add it in the comments and I would respond to you as soon as I am able.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reduxtoolkit</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
