<?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: Momin Mahmud</title>
    <description>The latest articles on DEV Community by Momin Mahmud (@mominmahmud).</description>
    <link>https://dev.to/mominmahmud</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%2F1275282%2F5a508a86-9cca-48f8-80f0-605fbc75a867.jpeg</url>
      <title>DEV Community: Momin Mahmud</title>
      <link>https://dev.to/mominmahmud</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mominmahmud"/>
    <language>en</language>
    <item>
      <title>Using React Hook Forms to make handling forms easier</title>
      <dc:creator>Momin Mahmud</dc:creator>
      <pubDate>Tue, 11 Jun 2024 08:11:56 +0000</pubDate>
      <link>https://dev.to/mominmahmud/using-react-hook-forms-to-make-handling-forms-easier-4h7b</link>
      <guid>https://dev.to/mominmahmud/using-react-hook-forms-to-make-handling-forms-easier-4h7b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;React Hook Form is a powerful library for handling forms in React using hooks. It simplifies form management by reducing boilerplate code and providing efficient validation. In this extended blog post, we’ll explore how to use React Hook Form’s useFieldArray to create dynamic forms with ease.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we begin, make sure you have the following installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node.js
npm or yarn (for package management)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Setting Up the Project&lt;/strong&gt;&lt;br&gt;
Create a new React project using create-react-app or any other preferred method.&lt;br&gt;
&lt;strong&gt;Install React Hook Form:&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;npm install react-hook-form
# or
yarn add react-hook-form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a Simple Form
&lt;/h2&gt;

&lt;p&gt;Let’s start with a basic form that collects user information. We’ll create a form with fields for name and email. If any field is empty, we’ll display an error message.&lt;br&gt;
&lt;/p&gt;

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

const SimpleForm = () =&amp;gt; {
  const { register, handleSubmit, errors } = useForm();

  const onSubmit = (data) =&amp;gt; {
    console.log(data); // Handle form submission
  };

  return (
    &amp;lt;form onSubmit={handleSubmit(onSubmit)}&amp;gt;
      &amp;lt;input
        type="text"
        name="name"
        placeholder="Name"
        ref={register({ required: true })}
      /&amp;gt;
      {errors.name &amp;amp;&amp;amp; &amp;lt;p&amp;gt;Name is required&amp;lt;/p&amp;gt;}

      &amp;lt;input
        type="email"
        name="email"
        placeholder="Email"
        ref={register({ required: true, pattern: /^\S+@\S+$/i })}
      /&amp;gt;
      {errors.email &amp;amp;&amp;amp; &amp;lt;p&amp;gt;Valid email is required&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 SimpleForm;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding Dynamic Fields with useFieldArray
&lt;/h2&gt;

&lt;p&gt;Now, let’s enhance our form by allowing users to add multiple ticket details. We’ll use useFieldArray to manage an array of ticket fields dynamically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { useForm, useFieldArray } from 'react-hook-form';

const DynamicForm = () =&amp;gt; {
  const { register, handleSubmit, control } = useForm();
  const { fields, append, remove } = useFieldArray({
    control,
    name: 'tickets',
  });

  const onSubmit = (data) =&amp;gt; {
    console.log(data); // Handle form submission
  };

  return (
    &amp;lt;form onSubmit={handleSubmit(onSubmit)}&amp;gt;
      {fields.map((field, index) =&amp;gt; (
        &amp;lt;div key={field.id}&amp;gt;
          &amp;lt;input
            type="text"
            name={`tickets[${index}].name`}
            placeholder="Ticket Name"
            ref={register()}
          /&amp;gt;
          &amp;lt;input
            type="email"
            name={`tickets[${index}].email`}
            placeholder="Ticket Email"
            ref={register()}
          /&amp;gt;
          &amp;lt;button type="button" onClick={() =&amp;gt; remove(index)}&amp;gt;
            Remove
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      ))}
      &amp;lt;button type="button" onClick={() =&amp;gt; append({ name: '', email: '' })}&amp;gt;
        Add Ticket
      &amp;lt;/button&amp;gt;
      &amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
};

export default DynamicForm;

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

&lt;/div&gt;



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

&lt;p&gt;In this extended blog post, we covered how to create a simple form using React Hook Form and then extended it to handle dynamic fields with useFieldArray. Feel free to explore more features of React Hook Form to enhance your form-building experience!&lt;/p&gt;

&lt;p&gt;Remember to check out the complete example on GitHub and experiment with it yourself. Happy coding! 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>react</category>
    </item>
    <item>
      <title>Unleashing the Power of GraphQL with React and .NET Hot Chocolate</title>
      <dc:creator>Momin Mahmud</dc:creator>
      <pubDate>Sat, 16 Mar 2024 12:55:29 +0000</pubDate>
      <link>https://dev.to/mominmahmud/unleashing-the-power-of-graphql-with-react-and-net-hot-chocolate-13b2</link>
      <guid>https://dev.to/mominmahmud/unleashing-the-power-of-graphql-with-react-and-net-hot-chocolate-13b2</guid>
      <description>&lt;p&gt;In the realm of modern web development, the efficiency of data retrieval and manipulation is paramount. As applications become more complex, the need for a robust and flexible data querying system becomes increasingly evident. In this blog post, we'll delve into how we harnessed the combined power of GraphQL, React, and .NET Hot Chocolate to streamline data management in our web application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding GraphQL Components
&lt;/h2&gt;

&lt;p&gt;Before diving into our implementation, let's grasp the core components of GraphQL with some examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fields
&lt;/h2&gt;

&lt;p&gt;At its essence, GraphQL revolves around querying specific fields on objects. Imagine we're developing an application related to the Star Wars universe. Here's a simple GraphQL query and its corresponding result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
graphql
Copy code
{
  hero {
    name
  }
}
The response would be:

json
Copy code
{
  "data": {
    "hero": {
      "name": "R2-D2"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple query demonstrates how GraphQL precisely delivers the requested fields, ensuring that clients receive exactly what they ask for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Objects and Relationships
&lt;/h2&gt;

&lt;p&gt;GraphQL not only handles scalar fields like strings but also objects and their relationships. For instance, querying for a hero's friends alongside their names:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graphql
{
  hero {
    name
    friends {
      name
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resulting in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;json
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {"name": "Luke Skywalker"},
        {"name": "Han Solo"},
        {"name": "Leia Organa"}
      ]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Arguments
&lt;/h2&gt;

&lt;p&gt;GraphQL also supports passing arguments to fields, enabling dynamic data retrieval. For example, fetching details about a human character with a specific ID:&lt;br&gt;
&lt;/p&gt;

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

{
  human(id: "1000") {
    name
    height
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resulting in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;json
{
  "data": {
    "human": {
      "name": "Luke Skywalker",
      "height": 1.72
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Aliases
&lt;/h2&gt;

&lt;p&gt;To handle scenarios where querying the same field with different arguments is needed, GraphQL employs aliases. This allows renaming the result of a field, preventing conflicts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graphql
{
  empireHero: hero(episode: EMPIRE) {
    name
  }
  jediHero: hero(episode: JEDI) {
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fragments
&lt;/h2&gt;

&lt;p&gt;Fragments are reusable units in GraphQL, particularly useful for structuring complex queries efficiently. They enable the construction of sets of fields that can be included wherever needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graphql
{
  leftComparison: hero(episode: EMPIRE) {
    ...comparisonFields
  }
  rightComparison: hero(episode: JEDI) {
    ...comparisonFields
  }
}

fragment comparisonFields on Character {
  name
  appearsIn
  friends {
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using GraphQL with React and .NET Hot Chocolate
&lt;/h2&gt;

&lt;p&gt;Now that we understand the fundamental components of GraphQL, let's explore how we integrated it into our web application using React on the frontend and .NET Hot Chocolate on the backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting up GraphQL Server with .NET Hot Chocolate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We began by setting up a GraphQL server using .NET Hot Chocolate, a GraphQL server implementation for .NET. Hot Chocolate simplifies the process of creating GraphQL APIs in .NET, offering features like schema-first development, automatic resolver generation, and built-in support for subscriptions.&lt;/p&gt;

&lt;p&gt;First, we defined our GraphQL schema, specifying the types, queries, mutations, and subscriptions our API would support. With Hot Chocolate's schema-first approach, this was straightforward and intuitive.&lt;/p&gt;

&lt;p&gt;Next, we implemented resolvers to handle the execution of GraphQL queries and mutations. These resolvers interact with our existing data sources, fetching and manipulating data as needed before returning it to the client.&lt;/p&gt;

&lt;p&gt;Once our GraphQL server was up and running, we could start querying and mutating data using GraphQL queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integrating GraphQL with React&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On the front end, we integrated GraphQL into our React application using Apollo Client, a powerful GraphQL client for React applications. Apollo Client simplifies the process of fetching and managing data with GraphQL in React, providing features like caching, query batching, and real-time data updates.&lt;/p&gt;

&lt;p&gt;We began by configuring Apollo Client to connect to our GraphQL server. Then, we used Apollo Client's useQuery and useMutation hooks to execute GraphQL queries and mutations respectively.&lt;/p&gt;

&lt;p&gt;With Apollo Client, managing data in our React components became straightforward. We could simply define GraphQL queries and mutations using gql templates, execute them using Apollo Client's hooks, and render the results in our components.&lt;/p&gt;

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

&lt;p&gt;In conclusion, leveraging GraphQL with React and .NET Hot Chocolate has significantly improved the efficiency and flexibility of data management in our web application. With GraphQL's intuitive querying capabilities, React's powerful component-based architecture, and .NET Hot Chocolate's seamless GraphQL server implementation, we've been able to build a modern, performant, and scalable web application that meets the needs of our users.&lt;/p&gt;

&lt;p&gt;By understanding and harnessing the core components of GraphQL, we've unlocked a new level of data querying and manipulation that has revolutionized our development process. As we continue to iterate and improve our application, GraphQL will remain a cornerstone of our technology stack, enabling us to deliver dynamic and engaging user experiences.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Implementing Stripe Payments in a React App and on Stripe Hosted Page: A Step-by-Step Guide</title>
      <dc:creator>Momin Mahmud</dc:creator>
      <pubDate>Thu, 29 Feb 2024 14:39:48 +0000</pubDate>
      <link>https://dev.to/mominmahmud/implementing-stripe-payments-in-a-react-app-a-step-by-step-guide-4dd9</link>
      <guid>https://dev.to/mominmahmud/implementing-stripe-payments-in-a-react-app-a-step-by-step-guide-4dd9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;In this blog post, I will walk you through the process of integrating Stripe payments into a React application. Stripe offers a seamless way to accept payments online, and with their Payment Element and React Stripe.js library, it becomes even easier to implement within your React projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Set up Stripe
&lt;/h2&gt;

&lt;p&gt;First, you'll need to set up your Stripe account and obtain your publishable key. This key will be used to connect your React application with Stripe's API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Install Dependencies
&lt;/h2&gt;

&lt;p&gt;Using npm or yarn, install the necessary dependencies for integrating Stripe into your React application. This includes @stripe/react-stripe-js and @stripe/stripe-js packages.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save @stripe/react-stripe-js @stripe/stripe-js&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Configure Stripe Elements Provider
&lt;/h2&gt;

&lt;p&gt;In your React application, wrap your checkout page component with the Elements provider from @stripe/react-stripe-js. Use the loadStripe function to load your Stripe instance with your publishable key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Add Payment Element Component
&lt;/h2&gt;

&lt;p&gt;Create a checkout form component where you'll include the PaymentElement component provided by Stripe. This component handles the collection of payment details from the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import ReactDOM from 'react-dom';
import {Elements} from '@stripe/react-stripe-js';
import {loadStripe} from '@stripe/stripe-js';

import CheckoutForm from './CheckoutForm';

// Make sure to call `loadStripe` outside of a component’s render to avoid
// recreating the `Stripe` object on every render.
const stripePromise = loadStripe('pk_test_51Oms7lDHd6wvkNXn2q0ORqQYjpQlJW2zpR36LTnmtkrTS3TCRUKpyXPXt9bkc8ZJ0pkwAxpWODvvynMoABsERAZQ00JXOBTvLk');

function App() {
  const options = {
    mode: 'payment',
    amount: 1099,
    currency: 'usd',
    // Fully customizable with appearance API.
    appearance: {/*...*/},
  };

  return (
    &amp;lt;Elements stripe={stripePromise} options={options}&amp;gt;
      &amp;lt;CheckoutForm /&amp;gt;
    &amp;lt;/Elements&amp;gt;
  );
};

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

import React from 'react';
import {PaymentElement} from '@stripe/react-stripe-js';

const CheckoutForm = () =&amp;gt; {
  return (
    &amp;lt;form&amp;gt;
      &amp;lt;PaymentElement /&amp;gt;
      &amp;lt;button&amp;gt;Submit&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Create PaymentIntent on Server
&lt;/h2&gt;

&lt;p&gt;On the server side, use a backend framework (e.g., Node.js with Express) to create a route for creating a PaymentIntent. This involves using the Stripe API to create a PaymentIntent with the desired amount and currency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using Microsoft.AspNetCore.Mvc;
using Stripe;

namespace StripeExampleApi.Controllers
{
  [Route("create-intent")]
  [ApiController]
  public class CheckoutApiController : Controller
  {
    public CheckoutApiController()
    {
      StripeConfiguration.ApiKey = "sk_test_51Oms7lDHd6wvkNXnWTQ2NMtzJOtXij2UtdyW9FAKS4HZOnSWonZMeaPGXMoqcTiSYFokhK3BIvolPTcwthggS4TS00LL9O97bC"
    }

    [HttpPost]
    public ActionResult Post()
    {
      var options = new PaymentIntentCreateOptions
      {
          Amount = 1099,
          Currency = "usd",
          // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
          AutomaticPaymentMethods = new PaymentIntentAutomaticPaymentMethodsOptions
          {
              Enabled = true,
          },
      };
      var service = new PaymentIntentService();
      PaymentIntent intent = service.Create(options);
      return Json(new {client_secret = intent.ClientSecret});
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Submit Payment to Stripe
&lt;/h2&gt;

&lt;p&gt;Back in your React application, handle form submission by calling the handleSubmit function. Inside this function, trigger form validation and wallet collection with elements.submit(). Then, fetch the client secret from your server and confirm the PaymentIntent using stripe.confirmPayment().&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Handle Payment Confirmation
&lt;/h2&gt;

&lt;p&gt;After confirming the PaymentIntent, handle any errors that may occur during the payment process. If successful, your customer will be redirected to the specified return URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, {useState} from 'react';
import {useStripe, useElements, PaymentElement} from '@stripe/react-stripe-js';

export default function CheckoutForm() {
  const stripe = useStripe();
  const elements = useElements();

  const [errorMessage, setErrorMessage] = useState();
  const [loading, setLoading] = useState(false);

  const handleError = (error) =&amp;gt; {
    setLoading(false);
    setErrorMessage(error.message);
  }

  const handleSubmit = async (event) =&amp;gt; {
    // We don't want to let default form submission happen here,
    // which would refresh the page.
    event.preventDefault();

    if (!stripe) {
      // Stripe.js hasn't yet loaded.
      // Make sure to disable form submission until Stripe.js has loaded.
      return;
    }

    setLoading(true);

    // Trigger form validation and wallet collection
    const {error: submitError} = await elements.submit();
    if (submitError) {
      handleError(submitError);
      return;
    }

    // Create the PaymentIntent and obtain clientSecret
    const res = await fetch("/create-intent", {
      method: "POST",
    });

    const {client_secret: clientSecret} = await res.json();

    // Confirm the PaymentIntent using the details collected by the Payment Element
    const {error} = await stripe.confirmPayment({
      elements,
      clientSecret,
      confirmParams: {
        return_url: 'https://example.com/order/123/complete',
      },
    });

    if (error) {
      // This point is only reached if there's an immediate error when
      // confirming the payment. Show the error to your customer (for example, payment details incomplete)
      handleError(error);
    } else {
      // Your customer is redirected to your `return_url`. For some payment
      // methods like iDEAL, your customer is redirected to an intermediate
      // site first to authorize the payment, then redirected to the `return_url`.
    }
  };

  return (
    &amp;lt;form onSubmit={handleSubmit}&amp;gt;
      &amp;lt;PaymentElement /&amp;gt;
      &amp;lt;button type="submit" disabled={!stripe || loading}&amp;gt;
        Submit Payment
      &amp;lt;/button&amp;gt;
      {errorMessage &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{errorMessage}&amp;lt;/div&amp;gt;}
    &amp;lt;/form&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Change Request
&lt;/h2&gt;

&lt;p&gt;So, my client recently approached me with some concerns regarding our current implementation of Stripe payments within our React application. They emphasized the importance of compliance with industry regulations and the need to address potential security vulnerabilities. After a thorough discussion, we collectively decided that it would be best to modify our approach. Specifically, we agreed to transition the payment process to an external page. This decision was made to enhance security by isolating the payment transaction from our main application environment, thus reducing the risk of unauthorized access to sensitive payment information. By moving to an external page for payment processing, we aim to bolster our data protection measures and ensure strict adherence to regulatory requirements. This adjustment demonstrates our unwavering commitment to maintaining the highest standards of security and compliance throughout our payment ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Payment on Stripe Hosted Page
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Step 1: Install Stripe.NET Package
&lt;/h2&gt;

&lt;p&gt;Begin by installing the Stripe.NET package using either the dotnet CLI or NuGet package manager. This package provides access to the Stripe API from your .NET Core application, enabling seamless integration with Stripe Checkout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Install with dotnet
dotnet add package Stripe.net
dotnet restore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Add Checkout Button to Your Website
&lt;/h2&gt;

&lt;p&gt;In your HTML page, add a checkout button that calls a server-side endpoint to create a Checkout Session. This session represents what your customer sees when redirected to the payment form and can be configured with line items, currencies, success URL, and cancel URL.&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;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Buy cool new product&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;!-- Use action="/create-checkout-session.php" if your server is PHP based. --&amp;gt;
    &amp;lt;form action="/create-checkout-session" method="POST"&amp;gt;
      &amp;lt;button type="submit"&amp;gt;Checkout&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Configure Server-Side Endpoint
&lt;/h2&gt;

&lt;p&gt;Set up a server-side endpoint using ASP.NET MVC framework to handle the creation of a Checkout Session. Utilize the Stripe.NET library to create a session with the desired line items, currency, success URL, and cancel URL. Upon creation, redirect the customer to the session URL returned by Stripe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This example sets up an endpoint using the ASP.NET MVC framework.
// Watch this video to get started: https://youtu.be/2-mMOB8MhmE.

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Stripe;
using Stripe.Checkout;

namespace server.Controllers
{
  public class PaymentsController : Controller
  {
    public PaymentsController()
    {
      StripeConfiguration.ApiKey = "sk_test_51Oms7lDHd6wvkNXnWTQ2NMtzJOtXij2UtdyW9FAKS4HZOnSWonZMeaPGXMoqcTiSYFokhK3BIvolPTcwthggS4TS00LL9O97bC";
    }

    [HttpPost("create-checkout-session")]
    public ActionResult CreateCheckoutSession()
    {
      var options = new SessionCreateOptions
      {
        LineItems = new List&amp;lt;SessionLineItemOptions&amp;gt;
        {
          new SessionLineItemOptions
          {
            PriceData = new SessionLineItemPriceDataOptions
            {
              UnitAmount = 2000,
              Currency = "usd",
              ProductData = new SessionLineItemPriceDataProductDataOptions
              {
                Name = "T-shirt",
              },
            },
            Quantity = 1,
          },
        },
        Mode = "payment",
        SuccessUrl = "http://localhost:4242/success",
        CancelUrl = "http://localhost:4242/cancel",
      };

      var service = new SessionService();
      Session session = service.Create(options);

      Response.Headers.Add("Location", session.Url);
      return new StatusCodeResult(303);
    }
  }
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Create a Success Page
&lt;/h2&gt;

&lt;p&gt;Create a minimal success page to display to the customer after a successful payment submission. This page should convey gratitude for the order and provide contact information for further inquiries.&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;html&amp;gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Thanks for your order!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Thanks for your order!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;
      We appreciate your business!
      If you have any questions, please email
      &amp;lt;a href="mailto:orders@example.com"&amp;gt;orders@example.com&amp;lt;/a&amp;gt;.
    &amp;lt;/p&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Test Your Integration
&lt;/h2&gt;

&lt;p&gt;Test your Stripe-hosted payment form integration by creating a Checkout Session and filling out payment details with test card information. Verify successful payment redirection to the designated success URL and check the payment details in the Stripe Dashboard.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Click your checkout button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill out the payment details with the test card information:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter 4242 4242 4242 4242 as the card number.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter any future date for card expiry.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter any 3-digit number for CVC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter any billing postal code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click Pay.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You’re redirected to your new success page.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Implementing Stripe payments in your React application is made simple with the Stripe Payment Element and React Stripe.js library. By following these steps, you can securely accept payments from your users while providing a seamless checkout experience.&lt;/p&gt;

&lt;p&gt;With this guide, you can enhance your e-commerce or subscription-based application by integrating Stripe payments, empowering you to monetize your services with ease.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How Tanstack improved my React App's performance and user experience.</title>
      <dc:creator>Momin Mahmud</dc:creator>
      <pubDate>Mon, 12 Feb 2024 16:18:41 +0000</pubDate>
      <link>https://dev.to/mominmahmud/how-tanstack-improved-my-react-apps-performance-and-user-experience-3gfh</link>
      <guid>https://dev.to/mominmahmud/how-tanstack-improved-my-react-apps-performance-and-user-experience-3gfh</guid>
      <description>&lt;p&gt;React is a great framework for building fast and interactive web applications, but it also comes with some challenges when it comes to data fetching and caching. How do we avoid unnecessary requests, stale data, loading states, and error handling? How do we optimize our app for performance and user experience?&lt;/p&gt;

&lt;p&gt;That's where TanStack comes in. TanStack is a collection of open-source libraries that help you manage your application state with ease. In this blog post, I will share how I used three of TanStack's libraries - Query, Mutation, and Infinite Query - to improve my React app's performance and user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query
&lt;/h2&gt;

&lt;p&gt;Query is a library that lets you fetch, cache, and update data in your React components with minimal code. It handles all the complex logic of data fetching, such as deduping, caching, refetching, background updates, and more. It also provides hooks to access the data and its status, such as loading, error, and success.&lt;/p&gt;

&lt;p&gt;I used Query to fetch data from my API using the &lt;code&gt;useQuery&lt;/code&gt; hook. This hook accepts a query key and a fetch function, and returns an object with the data and the status. For example, here is how I fetched a list of posts from my API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useQuery } from '@tanstack/query'

function Posts() {
  const { data, status } = useQuery('posts', () =&amp;gt; fetch('/api/posts').then(res =&amp;gt; res.json()))

  if (status === 'loading') {
    return &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;
  }

  if (status === 'error') {
    return &amp;lt;div&amp;gt;Error!&amp;lt;/div&amp;gt;
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Posts&amp;lt;/h1&amp;gt;
      &amp;lt;ul&amp;gt;
        {data.map(post =&amp;gt; (
          &amp;lt;li key={post.id}&amp;gt;{post.title}&amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, Query makes it easy to fetch and display data in a declarative way. It also automatically caches the data, so if I navigate away from the Posts component and come back, it will show the cached data instantly, while also refetching the data in the background to keep it fresh. This improves the performance and user experience of my app, as the user doesn’t have to wait for the data to load every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mutation
&lt;/h2&gt;

&lt;p&gt;Mutation is a component that lets you perform mutations, such as creating, updating, or deleting data, in your React components. It handles all the complex logic of mutations, such as optimistic updates, error handling, and invalidation. It also provides hooks to access the mutation status and data, such as loading, error, and success.&lt;/p&gt;

&lt;p&gt;I used Mutation to perform mutations on my data using the useMutation hook. This hook accepts a mutation function and returns an object with the mutation status and data, as well as a function to trigger the mutation. For example, here is how I created a new post using my API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useMutation, useQueryClient } from '@tanstack/mutation'

function CreatePost() {
  const [title, setTitle] = useState('')
  const queryClient = useQueryClient()
  const { mutate, status } = useMutation(
    title =&amp;gt; fetch('/api/posts', {
      method: 'POST',
      body: JSON.stringify({ title }),
      headers: {
        'Content-Type': 'application/json'
      }
    }).then(res =&amp;gt; res.json()),
    {
      // Optimistically update the cache with the new post
      onMutate: newPost =&amp;gt; {
        queryClient.setQueryData('posts', oldPosts =&amp;gt; [...oldPosts, newPost])
      },
      // Invalidate the posts query to refetch the data
      onSuccess: () =&amp;gt; {
        queryClient.invalidateQueries('posts')
      }
    }
  )

  const handleSubmit = e =&amp;gt; {
    e.preventDefault()
    mutate(title)
    setTitle('')
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Create Post&amp;lt;/h1&amp;gt;
      &amp;lt;form onSubmit={handleSubmit}&amp;gt;
        &amp;lt;input
          type="text"
          value={title}
          onChange={e =&amp;gt; setTitle(e.target.value)}
        /&amp;gt;
        &amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;
      &amp;lt;/form&amp;gt;
      {status === 'loading' &amp;amp;&amp;amp; &amp;lt;div&amp;gt;Creating post...&amp;lt;/div&amp;gt;}
      {status === 'error' &amp;amp;&amp;amp; &amp;lt;div&amp;gt;Error!&amp;lt;/div&amp;gt;}
      {status === 'success' &amp;amp;&amp;amp; &amp;lt;div&amp;gt;Post created!&amp;lt;/div&amp;gt;}
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, Mutation makes it easy to perform and display mutations in a declarative way. It also allows me to optimistically update the cache with the new post, so the user can see the result immediately, while also invalidating the posts query to refetch the data from the server. This improves the performance and user experience of my app, as the user doesn’t have to wait for the mutation to complete to see the effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Infinite Query
&lt;/h2&gt;

&lt;p&gt;Infinite Query is a component that lets you fetch and display paginated or infinite data in your React components. It handles all the complex logic of pagination, such as fetching more data, scrolling, and caching. It also provides hooks to access the data and its status, such as loading, error, and success.&lt;/p&gt;

&lt;p&gt;I used Infinite Query to fetch and display infinite data from my API using the useInfiniteQuery hook. This hook accepts a query key and a fetch function, and returns an object with the data and the status, as well as functions to fetch more data and reset the data. For example, here is how I fetched and displayed an infinite list of comments from my API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import { useInfiniteQuery } from '@tanstack/infinite-query'

function Comments() {
  const { data, status, fetchNextPage, hasNextPage, reset } = useInfiniteQuery(
    'comments',
    ({ pageParam = 0 }) =&amp;gt; fetch(`/api/comments?page=${pageParam}`).then(res =&amp;gt; res.json()),
    {
      // Get the next page parameter from the last page
      getNextPageParam: lastPage =&amp;gt; lastPage.nextPage
    }
  )

  const handleScroll = e =&amp;gt; {
    // Check if the user has scrolled to the bottom of the container
    const { scrollTop, scrollHeight, clientHeight } = e.target
    if (scrollTop + clientHeight &amp;gt;= scrollHeight) {
      // Fetch the next page if it exists
      if (hasNextPage) {
        fetchNextPage()
      }
    }
  }

  const handleReset = () =&amp;gt; {
    // Reset the data to the first page
    reset()
  }

  if (status === 'loading') {
    return &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;
  }

  if (status === 'error') {
    return &amp;lt;div&amp;gt;Error!&amp;lt;/div&amp;gt;
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Comments&amp;lt;/h1&amp;gt;
      &amp;lt;div style={{ height: '300px', overflow: 'auto' }} onScroll={handleScroll}&amp;gt;
        {data.pages.map(page =&amp;gt; (
          &amp;lt;ul key={page.page}&amp;gt;
            {page.comments.map(comment =&amp;gt; (
              &amp;lt;li key={comment.id}&amp;gt;{comment.text}&amp;lt;/li&amp;gt;
            ))}
          &amp;lt;/ul&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
      &amp;lt;button onClick={handleReset}&amp;gt;Reset&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, Infinite Query makes it easy to fetch and display infinite data in a declarative way. It also automatically caches the data, so if I navigate away from the Comments component and come back, it will show the cached data instantly, while also re-fetching the data in the background to keep it fresh. It also provides a way to fetch more data when the user scrolls to the bottom of the container and to reset the data to the first page. This improves the performance and user experience of my app, as the user can access the data in a fast and intuitive way.&lt;/p&gt;

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

&lt;p&gt;In this blog post, I showed how I used TanStack to improve my React app’s performance and user experience. TanStack is a powerful and easy-to-use solution for data fetching and caching in React. It offers many features and benefits, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Declarative and minimal code&lt;/li&gt;
&lt;li&gt;Automatic and smart caching&lt;/li&gt;
&lt;li&gt;Background updates and refetching&lt;/li&gt;
&lt;li&gt;Optimistic updates and invalidation&lt;/li&gt;
&lt;li&gt;Pagination and infinite data&lt;/li&gt;
&lt;li&gt;Loading, error, and success states&lt;/li&gt;
&lt;li&gt;And more!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>tanstack</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>React Firebase Auth with Redux deployed on Vercel</title>
      <dc:creator>Momin Mahmud</dc:creator>
      <pubDate>Wed, 07 Feb 2024 12:33:22 +0000</pubDate>
      <link>https://dev.to/mominmahmud/react-firebase-auth-with-redux-deployed-on-verce-1g33</link>
      <guid>https://dev.to/mominmahmud/react-firebase-auth-with-redux-deployed-on-verce-1g33</guid>
      <description>&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Temporarily, I'm a full-time front-end developer for a project. It utilizes Redux, but when I started, I lacked both React and Redux experience. While I've been on this project for three months now, I've primarily relied on existing code to implement Redux functionalities without grasping the core concepts. Understanding the intricacies of the Redux store and its inner workings remained elusive. Thankfully, with guidance from senior colleagues and Stack Overflow, I've managed to navigate runtime issues.&lt;/p&gt;

&lt;p&gt;However, I'm determined to delve deeper and solidify my understanding of Redux from the ground up. This way, I can troubleshoot problems with confidence and rely less on external resources for minor challenges.&lt;/p&gt;

&lt;p&gt;To efficiently learn two technologies simultaneously, I decided to implement Firebase Authentication while storing user metadata and auth tokens using Redux.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setup (Firebase)
&lt;/h2&gt;

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

&lt;p&gt;Go to the Firebase console (&lt;a href="https://console.firebase.google.com/"&gt;https://console.firebase.google.com/&lt;/a&gt;) and create a new project.&lt;br&gt;
Give your project a name and enable billing if necessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Register your app&lt;/strong&gt;:&lt;/p&gt;

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

&lt;p&gt;Select the platform you're developing for (web, Android, iOS, etc.) and follow the specific instructions for registering your app.&lt;br&gt;
This will give you a configuration file or snippet that you need to add to your project.&lt;br&gt;
** Install the Firebase SDK:**&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxx01yjd4ixsvnkef61h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxx01yjd4ixsvnkef61h.png" alt="Image description" width="800" height="433"&gt;&lt;/a&gt;&lt;br&gt;
Use the package manager for your platform (npm for JavaScript, CocoaPods for iOS, etc.) to install the required Firebase SDK libraries.&lt;br&gt;
 &lt;strong&gt;Initialize Firebase in your app:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the configuration file or snippet you obtained earlier to initialize Firebase in your app.&lt;br&gt;
This will enable you to use Firebase services in your code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Register Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Notice, I the code I also have sent another call to &lt;code&gt;sendEmailVerification&lt;/code&gt; so user cannot register with a bogus email&lt;/em&gt;&lt;/p&gt;




&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Register = () =&amp;gt; {
  const navigate = useNavigate();
  const [loading, setLoading] = useState(false);
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  const register = async () =&amp;gt; {
    setLoading(true);
      await createUserWithEmailAndPassword(auth, email, password)
        .then(async (userCredential: any) =&amp;gt; {
          await sendEmailVerification(userCredential.user);
          navigate(RouteEnums.VERIFICATION_NOTICE, { state : userCredential.user.email });
        })
        .catch((error: any) =&amp;gt; {
          toast.error(error.message);
        }).finally(()=&amp;gt; {
          setLoading(false)
        });
  };

  return (
    &amp;lt;&amp;gt;
      {loading ? &amp;lt;Spinner /&amp;gt; : (
           &amp;lt;div className="flex min-h-full flex-1 flex-col justify-center w-[400px] px-6 py-12 lg:px-8"&amp;gt;
           &amp;lt;div className="sm:mx-auto sm:w-full sm:max-w-sm"&amp;gt;
             &amp;lt;img
               className="mx-auto h-10 w-auto"
               src="https://tailwindui.com/img/logos/mark.svg?color=indigo&amp;amp;shade=600"
               alt="Your Company"
             /&amp;gt;
             &amp;lt;h2 className="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900"&amp;gt;
               Register a new account
             &amp;lt;/h2&amp;gt;
           &amp;lt;/div&amp;gt;

           &amp;lt;div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm"&amp;gt;
             &amp;lt;div&amp;gt;
               &amp;lt;label
                 htmlFor="email"
                 className="block text-sm font-medium leading-6 text-gray-900"
               &amp;gt;
                 Email address
               &amp;lt;/label&amp;gt;
               &amp;lt;div className="mt-2"&amp;gt;
                 &amp;lt;input
                   onChange={(e) =&amp;gt; setEmail(e.target.value)}
                   id="email"
                   name="email"
                   type="email"
                   autoComplete="email"
                   required
                   className="block w-full rounded-md border-0 p-1.5 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
                 /&amp;gt;
               &amp;lt;/div&amp;gt;
             &amp;lt;/div&amp;gt;

             &amp;lt;div className="my-5"&amp;gt;
               &amp;lt;div className="flex items-center justify-between"&amp;gt;
                 &amp;lt;label
                   htmlFor="password"
                   className="block text-sm font-medium leading-6 text-gray-900"
                 &amp;gt;
                   Password
                 &amp;lt;/label&amp;gt;
                 &amp;lt;div className="text-sm"&amp;gt;
                   &amp;lt;a className="font-semibold text-indigo-600 hover:text-indigo-500"&amp;gt;
                     Forgot password?
                   &amp;lt;/a&amp;gt;
                 &amp;lt;/div&amp;gt;
               &amp;lt;/div&amp;gt;
               &amp;lt;div className="mt-2"&amp;gt;
                 &amp;lt;input
                   onChange={(e) =&amp;gt; setPassword(e.target.value)}
                   id="password"
                   name="password"
                   type="password"
                   autoComplete="current-password"
                   required
                   className="block w-full rounded-md border-0 p-1.5  shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
                 /&amp;gt;
               &amp;lt;/div&amp;gt;
             &amp;lt;/div&amp;gt;

             &amp;lt;div&amp;gt;
               &amp;lt;button
                 onClick={register}
                 type="submit"
                 className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
               &amp;gt;
                 Register
               &amp;lt;/button&amp;gt;
             &amp;lt;/div&amp;gt;
           &amp;lt;/div&amp;gt;
         &amp;lt;/div&amp;gt;
      )}

    &amp;lt;/&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Verify the Register Function&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If your configuration was successful your user would appear in the &lt;code&gt;Authentication &amp;gt; Users&lt;/code&gt;section on the firebase console&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Create Login component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Notice I have only let user into my application if the user's email is verified&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Login = () =&amp;gt; {
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const [loading, setLoading] = useState(false);

useEffect(() =&amp;gt; {
  console.log(loading)
},[loading])

  const checkEmailVerified = (userCredential: any) =&amp;gt; {
    if (!userCredential.user.emailVerified) {
      console.error("User email is not verified.");
      toast.error("Please verify your email address to continue.");
    } else {
      dispatch(saveUser(userCredential.user));
      dispatch(saveToken(userCredential.user.accessToken));
      navigate(RouteEnums.HOME);
    }
  };
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const login = () =&amp;gt; {
    setLoading(true);
      signInWithEmailAndPassword(auth, email, password)
        .then((userCredential: any) =&amp;gt; {
          checkEmailVerified(userCredential);
        })
        .catch((error: any) =&amp;gt; {
          toast.error(error.message);
        }).finally(()=&amp;gt; {
          setLoading(false)
        });
  };

  return (
    &amp;lt;&amp;gt;
      {loading ? &amp;lt;Spinner /&amp;gt; : (
              &amp;lt;div className="flex min-h-full flex-1 flex-col justify-center w-[400px] py-12 lg:px-8"&amp;gt;
              &amp;lt;div className="sm:mx-auto sm:w-full sm:max-w-sm"&amp;gt;
                &amp;lt;img
                  className="mx-auto h-10 w-auto"
                  src="https://tailwindui.com/img/logos/mark.svg?color=indigo&amp;amp;shade=600"
                  alt="Your Company"
                /&amp;gt;
                &amp;lt;h2 className="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900"&amp;gt;
                  Login
                &amp;lt;/h2&amp;gt;
              &amp;lt;/div&amp;gt;

              &amp;lt;div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm"&amp;gt;
                &amp;lt;div&amp;gt;
                  &amp;lt;label
                    htmlFor="email"
                    className="block text-sm font-medium leading-6 text-gray-900"
                  &amp;gt;
                    Email address
                  &amp;lt;/label&amp;gt;
                  &amp;lt;div className="mt-2"&amp;gt;
                    &amp;lt;input
                      onChange={(e) =&amp;gt; setEmail(e.target.value)}
                      id="email"
                      name="email"
                      type="email"
                      autoComplete="email"
                      required
                      className="block w-full rounded-md border-0 p-1.5 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
                    /&amp;gt;
                  &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;div className="my-5"&amp;gt;
                  &amp;lt;div className="flex items-center justify-between"&amp;gt;
                    &amp;lt;label
                      htmlFor="password"
                      className="block text-sm font-medium leading-6 text-gray-900"
                    &amp;gt;
                      Password
                    &amp;lt;/label&amp;gt;
                    &amp;lt;div className="text-sm"&amp;gt;
                      &amp;lt;a className="font-semibold text-indigo-600 hover:text-indigo-500"&amp;gt;
                        Forgot password?
                      &amp;lt;/a&amp;gt;
                    &amp;lt;/div&amp;gt;
                  &amp;lt;/div&amp;gt;
                  &amp;lt;div className="mt-2"&amp;gt;
                    &amp;lt;input
                      onChange={(e) =&amp;gt; setPassword(e.target.value)}
                      id="password"
                      name="password"
                      type="password"
                      autoComplete="current-password"
                      required
                      className="block w-full rounded-md border-0 p-1.5  shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
                    /&amp;gt;
                  &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;div&amp;gt;
                  &amp;lt;button
                    onClick={() =&amp;gt; login()}
                    type="submit"
                    className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
                  &amp;gt;
                    Login
                  &amp;lt;/button&amp;gt;
                &amp;lt;/div&amp;gt;
              &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
      )}

    &amp;lt;/&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎉 Congratulations 🎉 you have implemented Auth using Firebase in your React app&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Now Lets save the response from firebase in the Redux Store&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Install the required packages:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Bash&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @reduxjs/toolkit react-redux @types/react-redux @types/react-router-dom (if using routing)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store Setup:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a store.ts file to define your Redux store:&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;`import { configureStore } from "@reduxjs/toolkit";
import authReducer from "../reducer/user/userAuthSlice"


export const store = configureStore({
    reducer: {
        auth: authReducer,
        }
})

export type RootState = ReturnType&amp;lt;typeof store.getState&amp;gt;
export type AppDispatch = typeof store.dispatch`

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configure Reducers&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;import { createSlice } from "@reduxjs/toolkit"

const initialState: any = {
    user: null,
    authToken : null
}
const userAuthSlice = createSlice({
    name : "auth",
    initialState,
    reducers: {
        saveUser(state :any, action:any){
            state.user = action.payload
        },
        saveToken(state :any, action:any){
            state.authToken = action.payload
        }
    }
},
)


export const { saveUser , saveToken } : any = userAuthSlice.actions


export default userAuthSlice.reducer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Store the user Data and token in stores on successful login&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;      dispatch(saveUser(userCredential.user));
      dispatch(saveToken(userCredential.user.accessToken));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;To protect the application create a guard to only allow authenticated user to login&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;const Router = () =&amp;gt; {
  const GUARD_ROUTE = (props: any) =&amp;gt; {
    const { children } = props;
    const authToken: any = useSelector((state: any) =&amp;gt; state.auth.authToken);
    if (authToken) {
      return &amp;lt;React.Fragment&amp;gt;{children}&amp;lt;/React.Fragment&amp;gt;;
    } 
    if (!authToken) {
      toast.dismiss()
      toast.error("Please Login First");
    }
    return &amp;lt;Navigate to={RouteEnums.LANDING} /&amp;gt;;
  };
  return (
    &amp;lt;BrowserRouter&amp;gt;
      &amp;lt;Routes&amp;gt;
        &amp;lt;Route path="/" element={&amp;lt;Landing /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="/login" element={&amp;lt;Login /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="/register" element={&amp;lt;Register /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="/verification-sent" element={&amp;lt;VerificationNotice /&amp;gt;} /&amp;gt;
        &amp;lt;Route
          path="/home"
          element={
            &amp;lt;GUARD_ROUTE&amp;gt;
              &amp;lt;Home /&amp;gt;
            &amp;lt;/GUARD_ROUTE&amp;gt;
          }
        /&amp;gt;
      &amp;lt;/Routes&amp;gt;
    &amp;lt;/BrowserRouter&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;🎉 Congratulations you have implemented Redux as well 🎉 &lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;I used Vercel as it is the easiest and quickest option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Push your app to a Git repository:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you don't have one, create a new repository on GitHub, GitLab, or Bitbucket.&lt;br&gt;
Push your local React app files to the remote repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Import your repository into Vercel:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://vercel.com/dashboard"&gt;https://vercel.com/dashboard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click "New Project" and select "From Git repository".&lt;/li&gt;
&lt;li&gt;Choose your Git provider and authorize Vercel to access your repositories.&lt;/li&gt;
&lt;li&gt;Select your repository and click "Import".&lt;/li&gt;
&lt;li&gt;Vercel will automatically detect your React app and deploy it. &lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;You'll receive a deployment URL upon completion.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>firebase</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
