<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Prithviraj Mazumder on Medium]]></title>
        <description><![CDATA[Stories by Prithviraj Mazumder on Medium]]></description>
        <link>https://medium.com/@prithirajmajumder8?source=rss-8b81d7c232af------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*_xUK6ZB0Zd0H57jQ</url>
            <title>Stories by Prithviraj Mazumder on Medium</title>
            <link>https://medium.com/@prithirajmajumder8?source=rss-8b81d7c232af------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 27 May 2026 00:33:07 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@prithirajmajumder8/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[ A simple implementation of a Loader in React ⚛️ using [ContextAPI, Custom Hook, and TypeScript]]]></title>
            <link>https://medium.com/techverito/a-simple-implementation-of-a-loader-in-react-%EF%B8%8F-using-contextapi-custom-hook-and-typescript-5bc36a277e29?source=rss-8b81d7c232af------2</link>
            <guid isPermaLink="false">https://medium.com/p/5bc36a277e29</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[custom-hook]]></category>
            <category><![CDATA[context-api]]></category>
            <category><![CDATA[components]]></category>
            <category><![CDATA[typescript-with-react]]></category>
            <dc:creator><![CDATA[Prithviraj Mazumder]]></dc:creator>
            <pubDate>Mon, 22 Apr 2024 13:03:57 GMT</pubDate>
            <atom:updated>2024-04-24T11:35:05.340Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*jF48CCdBEm8r1e8X" /><figcaption>Photo by <a href="https://unsplash.com/@mettyunuabona?utm_source=medium&amp;utm_medium=referral">Ehimetalor Akhere Unuabona</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>TLDR 👀</h3><p>If you are a <em>PRO </em>and<em> </em>only interested in implementation then in this <a href="https://github.com/PrithvirajMazumder/blog-simple-react-loader"><strong><em>Github Repository</em></strong></a><strong><em> </em></strong>you can find the code.</p><p>First of all forget that you are a <strong>&lt;Developer /&gt;<br></strong>Instead you are an <strong><em>End-User </em></strong>👩‍💻 of an Application and you have clicked a <strong><em>Button</em></strong><em> </em>in the UI and nothing happened for a while and suddenly a new element popups up in the screen.</p><p>You will have to work your brain 🧠 for some seconds to figure out what happened. Just like the below image👇</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/968/1*HClkzlx3lGdVQVScOnnaEg.gif" /></figure><blockquote>You definitely don’t want your Users to <strong>work their brain out</strong> to use your Application.</blockquote><blockquote>You should have a Loader/Spinner to indicate your users that something is happening behind the UI that they can’t see</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JRq7Ha_MWfg7Red_fBnwzw.gif" /></figure><h4>So there is nothing new in this</h4><blockquote>Majority of you guys knew this. But then also we sometimes forget to add loading state in our applications, or feel lazy to<strong> </strong>add <strong>multiple loading state </strong>in our components</blockquote><h3>In React ⚛️ we generally have this👇 mess of (<em>useState</em>)s when we implement multiple pending state UI in a component</h3><pre>import { useState } from &#39;react&#39;<br><br>export const SomeComponent = () =&gt; {<br>  const [isCarsLoading, setIsCarsLoading] = useState(false)<br>  const [isEngineLoading, setIsEngineLoading] = useState(false)<br>  <br>  const fetchCars = () =&gt; {<br>    try {<br>      setIsCarsLoading(true)<br>      ...<br>    } catch (error) {<br>      ...<br>    } finally {<br>      setIsCarsLoading(false)      <br>    }<br>  }<br>  <br>  const fetchEngineByCarModel = (carModel: string) =&gt; {<br>    try {<br>      setIsEngineLoading(true)<br>      ...<br>    } catch (error) {<br>      ...<br>    } finally {<br>      setIsEngineLoading(false)      <br>    }<br>  }</pre><blockquote>By this above implementation we need to always declare a separate loading state and conditionally render a <strong>Loader/Spinner</strong> for the showing pending state in UI</blockquote><h4>I think it will be great ✨ if we have some function to Start/Stop a Loader from any where in the Component Tree and it will show a generic loader.</h4><blockquote>And if we want something other than the generic loader then only we will add a separate loading states in components</blockquote><p>So our implementation of the Generic Global Loader’s Architechture will look like this 👇</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WJUqxdGa4xkPF4bWo-qQOA.png" /><figcaption>Loader Context Architecture</figcaption></figure><h3><em>Let’s try to code this &lt;/&gt;</em></h3><blockquote>Step 1: At first create the <strong>LoaderContext</strong> and it’s Type</blockquote><pre>//LoaderProvider.ts<br><br>export type LoaderContextProps = {<br>  isLoading: boolean<br>  start: () =&gt; void<br>  stop: () =&gt; void<br>}<br><br>export const LoaderContext = createContext&lt;LoaderContextProps&gt;({} as LoaderContextProps)</pre><blockquote>Step 2: Now let’s create a <strong>Provider</strong> for this <strong>Context</strong></blockquote><pre>//LoaderProvider.ts<br><br>export const LoaderProvider = ({ children }: { children: ReactNode }) =&gt; {<br>  const [isLoading, setIsLoading] = useState(false)<br>  const [loaderText, setLoaderText] = useState(&#39;&#39;)<br><br>  const start = (loaderText = &#39;Loader...&#39;) =&gt; {<br>    setLoaderText(loaderText)<br>    setIsLoading(true)<br>  }<br><br>  const stop = () =&gt; setIsLoading(false)<br><br>  return (<br>    &lt;LoaderContext.Provider<br>      value={{<br>        isLoading,<br>        start,<br>        stop,<br>        loaderText<br>      }}<br>    &gt;<br>      {children}<br>    &lt;/LoaderContext.Provider&gt;<br>  )<br>}</pre><p><strong>In this Context we have</strong></p><ul><li><strong><em>isLoading → </em></strong>(this is a state which trigger the loading state)</li><li><strong><em>start </em>→ </strong>(function that will take a loader text optionally and will <em>setIsLoading to true</em>)</li><li><strong><em>stop → </em></strong>(function that will setIsLoading to true)</li><li><strong>loaderText → </strong>(this is a state which stores the <em>LoaderText</em>)</li></ul><blockquote>Step 3: Create a helper <strong>Custom Hook</strong> for this context</blockquote><pre>//LoaderProvider.ts<br><br>export const useLoader = () =&gt; {<br>  const loaderContext = useContext(LoaderContext)<br><br>  if (!loaderContext) {<br>    throw new Error(&#39;Please use useLoader inside the context of LoaderProvider&#39;)<br>  }<br><br>  return {<br>    start: loaderContext.start,<br>    stop: loaderContext.stop<br>  }<br>}</pre><blockquote>Step 4: Now let’s create a <strong>&lt;Loader /&gt; Component</strong> which will listen to the <strong>isLoading</strong> State of <strong>&lt;Loader/&gt; Context</strong></blockquote><pre>//Loader.tsx<br><br>import { useContext } from &#39;react&#39;<br>import { LoaderContext } from &#39;@/stores/LoaderProvider.tsx&#39;<br>export const Loader = () =&gt; {<br>  const { isLoading, loaderText } = useContext(LoaderContext)<br>  return (<br>    &lt;&gt;<br>      {isLoading ? (<br>        &lt;div className=&quot;h-full w-full fixed top-0 left-0 bg-black/20 z-[99999]&quot;&gt;<br>          &lt;div className=&quot;fixed top-1/2 -translate-x-1/2 left-1/2 -translate-y-1/2 flex flex-col items-center gap-4&quot;&gt;<br>            &lt;span className=&quot;loading loading-spinner loading-lg text-primary&quot; /&gt;<br>            &lt;span className=&quot;text&quot;&gt;{loaderText}&lt;/span&gt;<br>          &lt;/div&gt;<br>        &lt;/div&gt;<br>      ) : null}<br>    &lt;/&gt;<br>  )<br>}</pre><blockquote><strong>Now Let’s implement this Global &lt;Loader/&gt; Component on a Page</strong></blockquote><pre>// Employees.tsx<br><br>import { useLoader } from &#39;@/stores/LoaderProvider.tsx&#39;<br>import { useEffect, useState } from &#39;react&#39;<br>import { Employee } from &#39;@/constants/employees.ts&#39;<br>import { fetchEmployees } from &#39;@/apis/employees.ts&#39;<br><br>export const EmployeesList = () =&gt; {<br>  const [employees, setEmployees] = useState&lt;Array&lt;Employee&gt;&gt;([])<br>  const loader = useLoader()<br>  const getEmployees = async () =&gt; {<br>    try {<br>      loader.start()<br>      const employees = await fetchEmployees()<br>      setEmployees(employees)<br>    } catch (e) {<br>      alert(&#39;Employees cannot be fetched!&#39;)<br>    } finally {<br>      loader.stop()<br>    }<br>  }<br>  useEffect(() =&gt; {<br>    void getEmployees()<br>  }, [])<br>  if (!employees?.length) {<br>    return &lt;&gt;&lt;/&gt;<br>  }<br>  return (<br>    &lt;&gt;<br>      &lt;h1 className=&quot;text-3xl font-bold mb-4&quot;&gt;Employees&lt;/h1&gt;<br>      &lt;button className=&quot;btn btn-primary btn-sm&quot; onClick={getEmployees}&gt;<br>        Re-fetch<br>      &lt;/button&gt;<br>      &lt;div className=&quot;overflow-x-auto mt-8&quot;&gt;<br>        &lt;table className=&quot;table w-full&quot;&gt;<br>          &lt;thead&gt;<br>            &lt;tr&gt;<br>              &lt;th&gt;&lt;/th&gt;<br>              &lt;th&gt;Name&lt;/th&gt;<br>              &lt;th&gt;Email&lt;/th&gt;<br>              &lt;th&gt;Phone&lt;/th&gt;<br>            &lt;/tr&gt;<br>          &lt;/thead&gt;<br>          &lt;tbody&gt;<br>            {employees.map((employee, index) =&gt; (<br>              &lt;tr key={employee.id}&gt;<br>                &lt;th&gt;{index + 1}&lt;/th&gt;<br>                &lt;td&gt;{employee.name}&lt;/td&gt;<br>                &lt;td&gt;{employee.email}&lt;/td&gt;<br>                &lt;td&gt;{employee.phone}&lt;/td&gt;<br>              &lt;/tr&gt;<br>            ))}<br>          &lt;/tbody&gt;<br>        &lt;/table&gt;<br>      &lt;/div&gt;<br>    &lt;/&gt;<br>  )<br>}</pre><h4><em>Voila </em>🌟, now <em>we can have loader state which we can trigger from anywhere without any extra loading state in your component</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ujILWeq1n9REvDZeyPemAg.gif" /></figure><h4>But we have a problem with this implementation 😢</h4><p>Since we have a single <strong>Loading State</strong> in the Context and multiple components will toggle this loader text</p><p>There will be a situation where a request named <strong><em>requestA</em></strong> that takes <strong>300ms </strong>to<strong> </strong>execute<br>And simultaneously we have another request named <strong><em>requestB</em></strong> which takes <strong>200ms</strong> to execute</p><p>And if both the requests calls <strong>loader.start() </strong>at start of execution then the loader will start at same time <br>but will stop when the <strong>requestB</strong> stops executing while <strong>requestA</strong> is still in the progress of execution.</p><p>So we won’t have a spinner for the entire execution time of <strong>requestA</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XTvZB0faR5gnF2zrwzItvw.png" /></figure><h4>Solution 🌟</h4><p>We will introduce a loader stack where <strong><em>loader.start()</em></strong> will insert a value in the stack and <strong><em>loader.stop()</em></strong> will delete a value from the stack</p><ul><li>So if the <strong>stack is not empty</strong> then the value of <strong><em>isLoading</em></strong> will be <strong>true</strong></li><li>And if the <strong>stack is empty</strong> then the value of <strong><em>isLoading</em></strong> will be <strong>false</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*I76ehGrbXc7FNM_ojt1zoQ.png" /><figcaption>Loader Stack</figcaption></figure><p>Now let’s change the implementation in <strong>ContextProvider</strong></p><pre>// LoaderProvider.ts<br><br>import { createContext, ReactNode, useContext, useEffect, useState } from &#39;react&#39;<br><br>export type LoaderContextProps = {<br>  isLoading: boolean<br>  loaderText: string<br>  start: (loaderText?: string) =&gt; void<br>  stop: () =&gt; void<br>}<br><br>export const LoaderContext = createContext&lt;LoaderContextProps&gt;({} as LoaderContextProps)<br><br>export const LoaderProvider = ({ children }: { children: ReactNode }) =&gt; {<br>  const [isLoading, setIsLoading] = useState(false)<br>  const [loaderText, setLoaderText] = useState(&#39;&#39;)<br>  const [loaderStack, setLoaderStack] = useState&lt;Array&lt;boolean&gt;&gt;([])<br><br>  const start = (loaderText = &#39;Loader...&#39;) =&gt; {<br>    setLoaderText(loaderText)<br>    setLoaderStack([...loaderStack, true])<br>  }<br><br>  const stop = () =&gt; setLoaderStack([...loaderStack.slice(1)])<br><br>  useEffect(() =&gt; {<br>    if (!loaderStack.length) {<br>      setIsLoading(false)<br>      return<br>    }<br>    setIsLoading(true)<br>  }, [loaderStack, start, stop])<br><br>  return (<br>    &lt;LoaderContext.Provider<br>      value={{<br>        isLoading,<br>        start,<br>        stop,<br>        loaderText<br>      }}<br>    &gt;<br>      {children}<br>    &lt;/LoaderContext.Provider&gt;<br>  )<br>}<br><br>export const useLoader = () =&gt; {<br>  const loaderContext = useContext(LoaderContext)<br><br>  if (!loaderContext) {<br>    throw new Error(&#39;Please use useLoader inside the context of LoaderProvider&#39;)<br>  }<br><br>  return {<br>    start: loaderContext.start,<br>    stop: loaderContext.stop<br>  }<br>}</pre><h3>Wrapping Up</h3><p>Building scalable and easy-to-use components is every developer’s dream. Feel free to use and tweak them in your projects, and remember happy coding, React developers! 😎✨</p><h3>Feedback ✉️</h3><p>Please let me know if you have some suggestions on it and feel free to fork it from this <a href="https://medium.com/r?url=https%3A%2F%2Fgithub.com%2FPrithvirajMazumder%2Fblog-simple-react-loader">repo</a> and change it however you want.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5bc36a277e29" width="1" height="1" alt=""><hr><p><a href="https://medium.com/techverito/a-simple-implementation-of-a-loader-in-react-%EF%B8%8F-using-contextapi-custom-hook-and-typescript-5bc36a277e29">🚀 A simple implementation of a Loader in React ⚛️ using [ContextAPI, Custom Hook, and TypeScript]</a> was originally published in <a href="https://medium.com/techverito">TechVerito</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ Building Scalable React Modal Component with Custom Hook ️ [TailwindCSS, DaisyUI, and…]]></title>
            <link>https://medium.com/techverito/building-scalable-react-modal-component-with-custom-hook-%EF%B8%8F-tailwindcss-daisyui-and-ae12fbd7521c?source=rss-8b81d7c232af------2</link>
            <guid isPermaLink="false">https://medium.com/p/ae12fbd7521c</guid>
            <category><![CDATA[react-hook]]></category>
            <category><![CDATA[tailwind-css]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[components]]></category>
            <dc:creator><![CDATA[Prithviraj Mazumder]]></dc:creator>
            <pubDate>Mon, 15 Jan 2024 12:42:58 GMT</pubDate>
            <atom:updated>2024-01-17T13:33:57.208Z</atom:updated>
            <content:encoded><![CDATA[<h3>🚀 Building Scalable React Modal Component with Custom Hook 🛠️ [TailwindCSS, DaisyUI, and TypeScript]</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*msHPMjNtyxooOF3F" /><figcaption>Photo by <a href="https://unsplash.com/@lautaroandreani?utm_source=medium&amp;utm_medium=referral">Lautaro Andreani</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>As front-end developers, we often find ourselves grappling with the challenge of creating reusable and scalable UI components. Consider this an attempt to create a reusable <strong><em>&lt;Modal /&gt;</em></strong> component for React.</p><h3>TLDR 👀</h3><p>If you are a <em>PRO </em>and<em> </em>only interested in implementation then in this <a href="https://github.com/PrithvirajMazumder/use-modal"><strong><em>Github Repository</em></strong></a><strong><em> </em></strong>you can find the code.</p><blockquote>✨ <strong>Inspiration</strong></blockquote><blockquote>I was onboarded on a project where I was assigned to build a component library from scratch. <br>Modal component was one of them, <br>and <a href="https://tailwindcss.com/"><strong>TailwindCSS</strong></a> and <a href="https://daisyui.com/"><strong>DaisyUI</strong></a> was chosen because those were aligning with our project’s styling needs.</blockquote><h3>Problem 🤔</h3><p>While browsing <a href="https://daisyui.com">DaisyUI</a>’s <a href="https://daisyui.com/components/modal/">Modal</a> documentation, I was wondering how to create a <strong>reusable </strong>React component without…</p><pre>const [isModalOpen, setIsModalOpen] = useState&lt;boolean&gt;(false)<br><br>return (<br>  &lt;&gt;<br>    &lt;Modal isOpen={isModalOpen}&gt;<br>      ...modal content<br>      &lt;button onClick({() =&gt; setIsModalOpen(false)})&gt;<br>        Okay<br>      &lt;/button&gt;<br>    &lt;/Modal&gt;<br>    <br>    &lt;button onClick({() =&gt; setIsModalOpen(true)})&gt;<br>      Open Dialog<br>    &lt;/button&gt;<br>  &lt;/&gt;<br>)</pre><p>maintaining a state for opening and closing.</p><blockquote>As we can see, the problem <em>🤔</em> is that we have to maintain a state [isModalOpen] for displaying the modal every time where we want to use it. <em>🔄</em></blockquote><p>This solution is not:</p><ul><li>Clean ❌</li><li>Readable ❌</li><li>Developer friendly ❌</li></ul><h3>Solution</h3><blockquote>All of these code are in this <a href="https://github.com/PrithvirajMazumder/use-modal">Github Repository</a></blockquote><ol><li>At first, we will create a Custom <strong>&lt;Modal /&gt;</strong> Component which will contain the: <br>+ HTML Dialog element<br>+ The backdrop for the modal<br>+ And all the necessary styles</li></ol><p>2. Then we will introduce a Custom <strong>useModal</strong> Hook which builds this <strong>Modal</strong> component with necessary props 🛠️ and will provide functions that will toggle the <strong>Popup/Dialog</strong> in the UI ✨</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0-jkJJqLRWiqzSWCmZHJjA.png" /></figure><h3>Let’s build the &lt;Modal /&gt; Component</h3><p>Here is the code of the component</p><pre>import { forwardRef, ReactNode } from &#39;react&#39;<br><br>export type ModalProps = {<br>  children?: ReactNode<br>  onBackdropClick?: () =&gt; void<br>  modalBoxClassName?: string<br>  // you can add more classNames as per your level of customisation needs<br>}<br><br>export const Modal = forwardRef&lt;HTMLDialogElement, ModalProps&gt;(<br>  ({ children, modalBoxClassName, onBackdropClick }, ref) =&gt; {<br>    return (<br>      &lt;dialog ref={ref} className=&quot;modal&quot;&gt;<br>        &lt;div className={`modal-box ${modalBoxClassName ?? &#39;&#39;}`}&gt;{children}&lt;/div&gt;<br>        &lt;form method=&quot;dialog&quot; className=&quot;modal-backdrop&quot;&gt;<br>          &lt;button<br>            type=&quot;button&quot;<br>            onClick={() =&gt; {<br>              onBackdropClick &amp;&amp; onBackdropClick()<br>            }}<br>          &gt;<br>            close<br>          &lt;/button&gt;<br>        &lt;/form&gt;<br>      &lt;/dialog&gt;<br>    )<br>  }<br>)</pre><h4>Props</h4><ol><li><strong>children: </strong>this will be used to render content inside the modal</li><li><strong>ref: (important) </strong>It will take an HTMLDialogRef to toggle the modal open state</li><li><strong>onBackdropClick: </strong>(optional) will take a function in case we need to close the modal on click of the modal backdrop</li><li><strong>modalBoxClassName: </strong>(optional) will take CSS classes to modify the styles in case we need a different style for the modal container.</li></ol><h4>Usage</h4><blockquote>If we want to use this component without the <strong>hook</strong> then we have to <strong>declare a ref [with a type of &lt;HTMLDialogElement&gt;]</strong> everywhere we want to use this component</blockquote><pre>const modalRef = useRef&lt;HTMLDialogElement&gt;(null)<br><br>return (<br>  &lt;div&gt;<br>   &lt;Modal ref={modalRef}&gt;<br>    &lt;h1 className=&quot;text-2xl font-bold&quot;&gt;I am your modal&#39;s title&lt;/h1&gt;<br>      &lt;div className=&quot;py-4&quot;&gt;<br>        &lt;p className=&quot;text-lg&quot;&gt;I am you modal&#39;s content&lt;/p&gt;<br>      &lt;/div&gt;<br>      &lt;div className=&quot;flex items-center w-full&quot;&gt;<br>      &lt;button className=&quot;btn ml-auto&quot; onClick={() =&gt; modalRef?.current?.close()}&gt;<br>        Close<br>      &lt;/button&gt;<br>    &lt;/div&gt;<br>   &lt;/Modal&gt;    <br>   &lt;button className=&quot;btn ml-auto&quot; onClick={() =&gt; modalRef?.current?.showModal()}&gt;<br>     Close<br>   &lt;/button&gt;<br>  &lt;/div&gt;<br>)</pre><p>Declaring a <strong>ref</strong> 👆 every time is a pain, <strong>So let’s improve this implementation!</strong></p><h3>Let’s make it better with useModal custom hook</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/650/1*XBvjQdhGp2IXDlWbg8JirQ.png" /><figcaption>Usage flow while using useModal hook</figcaption></figure><blockquote>Instead of directly using the &lt;Modal /&gt; Component we will now access it via <strong><em>useModal </em></strong>Custom Hook</blockquote><pre>import { ReactNode, useRef } from &#39;react&#39;<br>import { Modal, ModalProps } from &#39;../components/Modal.tsx&#39;<br><br>export type UseModalResp = {<br>  modal: ReactNode<br>  closeModal: () =&gt; void<br>  openModal: () =&gt; void<br>  modalBoxClassName?: string<br>}<br><br>export type UseModalProps = Omit&lt;ModalProps, &#39;onBackdropClick&#39;&gt; &amp; {<br>  shouldAllowBackdropClick?: boolean //if it is true then modal can be closed<br>  onModalOpen?: () =&gt; void //this function will be called on calling of openModal<br>  onModalClose?: () =&gt; void //this function will be called on calling of closeModal<br>}<br><br>export const useModal = ({<br>  children,<br>  modalBoxClassName,<br>  shouldAllowBackdropClick = true,<br>  onModalClose,<br>  onModalOpen<br>}: UseModalProps): UseModalResp =&gt; {<br>  const ref = useRef&lt;HTMLDialogElement | null&gt;(null)<br><br>const closeModal = () =&gt; {<br>    onModalClose &amp;&amp; onModalClose()<br>    ref.current?.close()<br>  }<br><br>const openModal = () =&gt; {<br>    onModalOpen &amp;&amp; onModalOpen()<br>    ref.current?.showModal()<br>  }<br><br>const modal: ReactNode = (<br>    &lt;Modal<br>      onBackdropClick={() =&gt; {<br>        if (shouldAllowBackdropClick) {<br>          closeModal()<br>        }<br>      }}<br>      ref={ref}<br>      modalBoxClassName={modalBoxClassName}<br>    &gt;<br>      {children}<br>    &lt;/Modal&gt;<br>  )<br><br>return {<br>    closeModal,<br>    openModal,<br>    modal<br>  }<br>}</pre><h4>Props</h4><ul><li><strong>children: </strong>this will be used to render content inside the modal</li><li><strong>modalBoxClassName: </strong>(optional) will take CSS classes to modify the styles in case we need a different style for the modal container.</li><li><strong>shouldAllowBackdropClick: </strong>(optional) If passed then this flag determines whether the modal will close on click of backdrop</li><li><strong>onModalOpen: </strong>(optional) If passed then this function will be called while opening the modal</li><li><strong>onModalClose: </strong>(optional) If passed then this function will be called while closing the modal</li></ul><h4>Returns</h4><ol><li><strong>modalComponent: </strong>this will contain the complete modal with children passed to it that we wanted to render.</li><li><strong>openModal: </strong>this is the function that we will call to open the modal</li><li><strong>close modal:</strong> this is the function that we will call to close the modal</li></ol><h3>Why do we need this hook? 🪝</h3><pre>const App = () =&gt; {<br>  const { modal, openModal, closeModal } = useModal({<br>    children: (<br>      &lt;&gt;<br>        &lt;h1 className=&quot;text-2xl font-bold&quot;&gt;I am your modal&#39;s&lt;/h1&gt;<br>        &lt;div className=&quot;py-4&quot;&gt;<br>          &lt;p className=&quot;text-lg&quot;&gt;I am your modal&#39;s content&lt;/p&gt;<br>        &lt;/div&gt;<br>        &lt;div className=&quot;flex items-center w-full&quot;&gt;<br>          &lt;button className=&quot;btn ml-auto&quot; onClick={() =&gt; closeModal() //closing the modal}&gt;<br>            Close<br>          &lt;/button&gt;<br>        &lt;/div&gt;<br>      &lt;/&gt;<br>    )<br>  })<br><br>return (<br>    &lt;div className=&quot;bg-base-100 w-[100svw] h-[100svh] flex flex-col items-center justify-center&quot;&gt;<br>      {modal} {/*.  &lt;---- rendering the modal component*/}<br>      &lt;button className=&quot;btn btn-primary&quot; onClick={() =&gt; openModal() //opening the modal}&gt;<br>        Open Modal<br>      &lt;/button&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*4clt8ATzhGwSF3KMBsN_vA.gif" /><figcaption>A working example of the modal component using useModal hook</figcaption></figure><p>This solution is</p><ul><li>Clean ✅</li><li>Readable ✅</li><li>Developer friendly ✅</li></ul><ol><li><strong>We don’t need to maintain a state whenever we want to use a modal</strong></li><li><strong>Neither we need to use a ref to show and close a modal</strong></li></ol><p>If we don’t want to add <strong>JSX </strong>above the return statement then we can extract it to a different component</p><pre>&lt;&gt;<br>  &lt;h1 className=&quot;text-2xl font-bold&quot;&gt;I am your modal&#39;s&lt;/h1&gt;<br>  &lt;div className=&quot;py-4&quot;&gt;<br>    &lt;p className=&quot;text-lg&quot;&gt;I am your modal&#39;s content&lt;/p&gt;<br>  &lt;/div&gt;<br>  &lt;div className=&quot;flex items-center w-full&quot;&gt;<br>     &lt;button className=&quot;btn ml-auto&quot; onClick={() =&gt; closeModal() //closing the modal}&gt;<br>      Close<br>    &lt;/button&gt;<br>  &lt;/div&gt;<br>&lt;/&gt;</pre><p>Then our code will look like this 👇</p><pre>const App = () =&gt; {<br>  const { modal, openModal, closeModal } = useModal({<br>    children: &lt;MyDummyModal closeModal={() =&gt; closeModal} /&gt;<br>  })<br><br>return (<br>    &lt;div className=&quot;bg-base-100 w-[100svw] h-[100svh] flex flex-col items-center justify-center&quot;&gt;<br>      {modal} {/*rendering the modal component*/}<br>      &lt;button className=&quot;btn btn-primary&quot; onClick={() =&gt; openModal()}&gt;<br>        Open Modal<br>      &lt;/button&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>And voilà! With just a few lines of code, your modal is ready. The Component illustrates how effortlessly you can integrate this modal into your project 👍.</p><h3>Wrapping Up</h3><p>Building scalable and easy-to-use components is every developer’s dream. Feel free to use and tweak them in your projects, and remember happy coding, React developers! 😎✨</p><h3>Feedback ✉️</h3><p>Please let me know if you have some suggestions on it and feel free to fork it from this <a href="https://github.com/PrithvirajMazumder/use-modal">repo</a> and change it however you want.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ae12fbd7521c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/techverito/building-scalable-react-modal-component-with-custom-hook-%EF%B8%8F-tailwindcss-daisyui-and-ae12fbd7521c">🚀 Building Scalable React Modal Component with Custom Hook 🛠️ [TailwindCSS, DaisyUI, and…</a> was originally published in <a href="https://medium.com/techverito">TechVerito</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>