<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Bilkan</title>
    <description>The latest articles on Forem by Bilkan (@bilkn).</description>
    <link>https://forem.com/bilkn</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%2F583017%2F35fa1cc3-50c5-461b-9898-48cc5017c137.png</url>
      <title>Forem: Bilkan</title>
      <link>https://forem.com/bilkn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bilkn"/>
    <language>en</language>
    <item>
      <title>Building Reusable React Dialog Component</title>
      <dc:creator>Bilkan</dc:creator>
      <pubDate>Sun, 27 Jun 2021 09:22:04 +0000</pubDate>
      <link>https://forem.com/bilkn/building-reusable-react-dialog-component-1l8c</link>
      <guid>https://forem.com/bilkn/building-reusable-react-dialog-component-1l8c</guid>
      <description>&lt;p&gt;In this tutorial, we will build a reusable &lt;code&gt;Dialog&lt;/code&gt; Component using React Hooks, Context API, and Styled Components.&lt;/p&gt;




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

&lt;p&gt;Using a &lt;code&gt;Dialog&lt;/code&gt; component can violate the DRY (Don't Repeat Yourself) principle, especially if our App has many pages that have &lt;code&gt;Dialog&lt;/code&gt; required interactions. &lt;/p&gt;

&lt;p&gt;By using React Hooks and Context API, we will try to decrease the code repetition as much as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Before we jump into building our component, we should install the tools and libraries that we will use. &lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a new React App
&lt;/h3&gt;

&lt;p&gt;First we create a new React App using &lt;a href="https://create-react-app.dev/" rel="noopener noreferrer"&gt;Create React App&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app reusable-dialog
cd reusable-dialog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;npx create-react-app reusable-dialog&lt;/code&gt; command will install React, testing libraries, and several other libraries/tools to build a basic modern web app.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd&lt;/code&gt; is the command for "change directory", it will change the working directory from the current directory to "reusable-dialog". &lt;/p&gt;




&lt;h3&gt;
  
  
  Installing Styled Components (Optional)
&lt;/h3&gt;

&lt;p&gt;After creating our React App, we install &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;Styled Components&lt;/a&gt; to style our &lt;code&gt;Dialog&lt;/code&gt; component.&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 --save styled-components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Building the Dialog Component
&lt;/h3&gt;

&lt;p&gt;Firstly, we create a file for global styles and export it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createGlobalStyle } from "styled-components";

export const GlobalStyles = createGlobalStyle`
*, *::before, *::after {
    box-sizing: border-box;
    margin:0;
    padding: 0;
} 
html, 
body {  
        background: #F3F5FB;
        color: #333;
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        font-size: 16px;
        -moz-osx-font-smoothing: grayscale;
        -webkit-font-smoothing: antialiased;
        -webkit-overflow-scrolling: touch;
    }

    button {
        border: none;
        cursor: pointer;
    }

    p {
        line-height: 1.4em;
    }
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, import the &lt;code&gt;GlobalStyles&lt;/code&gt; from &lt;code&gt;index.js&lt;/code&gt; and add it to the &lt;code&gt;ReactDOM.render&lt;/code&gt; method as a component. &lt;/p&gt;

&lt;p&gt;This is a wrapper for global styles that we will use globally in our app.&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 App from './App';
import {GlobalStyles} from "./styles/global-styles";

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

&lt;/div&gt;



&lt;p&gt;Next, we start to code our &lt;code&gt;Dialog&lt;/code&gt; using Styled Components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import styled from "styled-components/macro";

export const Container = styled.div`
  background: #f7f9fa;
  border-radius: 10px;
  box-shadow: rgb(100 100 111 / 20%) 0px 7px 29px 0px;
  left: 50%;
  max-width: 330px;
  padding: 1.25em 1.5em;
  position: fixed;
  transform: translate(-50%, -50%);
  top: 50%;
`;

export const Box = styled.div`
  display: flex;
  justify-content: center;
  &amp;amp; button:first-child {
    margin-right: 2em;
  }
`;

export const Text = styled.p`
  color: black;
  font-size: 1.1rem;
  margin-bottom: 1.5em;
  text-align: center;
`;

export const Button = styled.button`
  background: ${({variant = "white"})=&amp;gt; variant === "red" ? "#d2342a" :"#f7f9fa"};
  border-radius: 20px;
  box-shadow: 0 3px 6px rgba(241, 85, 76, 0.25);
  color: ${({variant = "white"})=&amp;gt; variant === "red" ? "white" :"#d2342a"};
  font-size: 1.2rem;
  padding: 0.3em 0;
  text-align: center;
  transition: background-color 100ms;
  width: 100px;
  &amp;amp;:hover {
    background: ${({variant = "white"})=&amp;gt; variant === "red" ? "#d82d22" :"#f1f1f1"};
  }
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I imported the "styled-components/macro" for convenience. Otherwise, you have to deal with the randomly generated class names.&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%2Fqm3bh2bogtv370i9ej2o.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%2Fqm3bh2bogtv370i9ej2o.png" alt="HTML Elements with the generated class names by styled components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before building our &lt;code&gt;Dialog&lt;/code&gt; component we create a div element in &lt;code&gt;index.html&lt;/code&gt; to create a portal to render the &lt;code&gt;Dialog&lt;/code&gt;. In this way, our &lt;code&gt;Dialog&lt;/code&gt; component can exist outside of the DOM hierarchy of the parent component, so it will be much easier to use it and customize it.&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;body&amp;gt;
    &amp;lt;noscript&amp;gt;You need to enable JavaScript to run this app.&amp;lt;/noscript&amp;gt;
    &amp;lt;div id="root"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div id="portal"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we import styled components that we created for our &lt;code&gt;Dialog&lt;/code&gt; and add them to build React component and return it using &lt;code&gt;ReactDom.createPortal()&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;import React, { useContext } from "react";
import ReactDOM from "react-dom";
import DialogContext from "../../context/dialog";
import { Container, Box, Text, Button } from "./styles/dialog";

function Dialog({ children, ...rest }) {
  const { dialog, setDialog } = useContext(DialogContext);
  const { isOpen, text, handler, noBtnText, yesBtnText } = dialog;

  return ReactDOM.createPortal(
    &amp;lt;Container {...rest}&amp;gt;
      &amp;lt;Text&amp;gt;Are you really want to do it?&amp;lt;/Text&amp;gt;
      &amp;lt;Box&amp;gt;
        {children}
        &amp;lt;Button variant="red"&amp;gt;No&amp;lt;/Button&amp;gt;
        &amp;lt;Button&amp;gt;Yes&amp;lt;/Button&amp;gt;
      &amp;lt;/Box&amp;gt;
    &amp;lt;/Container&amp;gt;,
    document.getElementById("portal")
  );
}

export default Dialog;

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

&lt;/div&gt;



&lt;p&gt;This is the final look of our &lt;code&gt;Dialog&lt;/code&gt; component.&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%2F69me6khvibnp77xregvu.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%2F69me6khvibnp77xregvu.png" alt="Dialog Component"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Building the Logic
&lt;/h3&gt;

&lt;p&gt;In order to build Dialog logic, we will use Context API.&lt;/p&gt;

&lt;p&gt;First, we create our &lt;code&gt;DialogContext&lt;/code&gt; and export it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createContext } from "react";
const DialogContext = createContext(null);
export default DialogContext;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we create &lt;code&gt;DialogProvider&lt;/code&gt; to share the logic between components without having to pass props down manually at every level.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from "react";
import DialogContext from "../context/dialog";

function DialogProvider({ children, ...props }) {
  const [dialog, setDialog] = useState({
    isOpen: false,
    text: "",
    handler: null,
    noBtnText: "",
    yesBtnText:""
  });

  return (
    &amp;lt;DialogContext.Provider value={{ dialog, setDialog }} {...props}&amp;gt;
      {children}
    &amp;lt;/DialogContext.Provider&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;Dialog&lt;/code&gt; will use the dialog state which includes several state variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;isOpen&lt;/code&gt; is for showing or not showing the &lt;code&gt;Dialog&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;text&lt;/code&gt; is for the text that we show to the user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;handler&lt;/code&gt; is for the handler function that will be called after clicking the "yes" or similar acceptance button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;noBtnText&lt;/code&gt; and &lt;code&gt;yesBtnText&lt;/code&gt; are the texts of the &lt;code&gt;Dialog&lt;/code&gt; buttons.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After creating &lt;code&gt;DialogProvider&lt;/code&gt;, we wrap our &lt;code&gt;Dialog&lt;/code&gt; component with the &lt;code&gt;DialogProvider&lt;/code&gt; to access the &lt;code&gt;dialog&lt;/code&gt; state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Dialog from "./components/dialog";
import DialogProvider from "./providers/dialog";
function App() {
  return (
    &amp;lt;DialogProvider&amp;gt;
      &amp;lt;Dialog /&amp;gt;
    &amp;lt;/DialogProvider&amp;gt;
  );
}

export default App;

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

&lt;/div&gt;



&lt;p&gt;Now, we can use the &lt;code&gt;dialog&lt;/code&gt; state variables inside of our &lt;code&gt;Dialog&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;We add handlers to handle the &lt;code&gt;Dialog&lt;/code&gt; button clicks and make the button texts customizable.&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, { useContext, useRef } from "react";
import ReactDOM from "react-dom";
import DialogContext from "../../context/dialog";
import { Container, Box, Text, Button } from "./styles/dialog";

function Dialog({ children, ...rest }) {
  const { dialog, setDialog } = useContext(DialogContext);
  const { isOpen, text, handler, noBtnText, yesBtnText } = dialog;

  const resetDialog = () =&amp;gt; {
    setDialog({ isOpen: false, text: "", handler: null });
  };

  const handleYesClick = () =&amp;gt; {
    handler();
    resetDialog();
  };

  const handleNoClick = () =&amp;gt; {
    resetDialog();
  };

  if (!isOpen) return null;

  return ReactDOM.createPortal(
    &amp;lt;Container {...rest}&amp;gt;
      &amp;lt;Text&amp;gt;{text}&amp;lt;/Text&amp;gt;
      &amp;lt;Box&amp;gt;
        {children}
        &amp;lt;Button onClick={handleNoClick} variant="red"&amp;gt;
          {noBtnText}
        &amp;lt;/Button&amp;gt;
        &amp;lt;Button onClick={handleYesClick}&amp;gt;{yesBtnText}&amp;lt;/Button&amp;gt;
      &amp;lt;/Box&amp;gt;
    &amp;lt;/Container&amp;gt;,
    document.getElementById("portal")
  );
}

export default Dialog;


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

&lt;/div&gt;






&lt;h3&gt;
  
  
  Improving the Accessibility
&lt;/h3&gt;

&lt;p&gt;In order to improve our &lt;code&gt;Dialog&lt;/code&gt;'s accessibility, we should add several things to it.&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, { useCallback, useContext, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
import DialogContext from "../../context/dialog";
import { Container, Box, Text, Button } from "./styles/dialog";

function Dialog({ children, ...rest }) {
  const { dialog, setDialog } = useContext(DialogContext);
  const { isOpen, text, handler, noBtnText, yesBtnText } = dialog;
  const btnRef = useRef(null);

  const resetDialog = useCallback(() =&amp;gt; {
    setDialog({ isOpen: false, text: "", handler: null });
  }, [setDialog]);

  const handleYesClick = () =&amp;gt; {
    handler();
    resetDialog();
  };

  const handleNoClick = () =&amp;gt; {
    resetDialog();
  };

  useEffect(() =&amp;gt; {
    const { current } = btnRef;
    if (current) current.focus();
  }, [isOpen]);

  useEffect(() =&amp;gt; {
    const handleKeydown = (e) =&amp;gt; {
      if (e.key === "Escape") resetDialog();
    };
    window.addEventListener("keydown", handleKeydown);
    return ()=&amp;gt; window.removeEventListener("keydown", handleKeydown);
  }, [resetDialog]);

  if (!isOpen) return null;

  return ReactDOM.createPortal(
    &amp;lt;Container role="dialog" aria-describedby="dialog-desc" {...rest}&amp;gt;
      &amp;lt;Text id="dialog-desc"&amp;gt;{text}&amp;lt;/Text&amp;gt;
      &amp;lt;Box&amp;gt;
        {children}
        &amp;lt;Button ref={btnRef} onClick={handleNoClick} variant="red"&amp;gt;
          {noBtnText}
        &amp;lt;/Button&amp;gt;
        &amp;lt;Button onClick={handleYesClick}&amp;gt;{yesBtnText}&amp;lt;/Button&amp;gt;
      &amp;lt;/Box&amp;gt;
    &amp;lt;/Container&amp;gt;,
    document.getElementById("portal")
  );
}

export default Dialog;

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

&lt;/div&gt;



&lt;p&gt;We added, two &lt;code&gt;useEffect&lt;/code&gt; hooks, first one calls the callback function to focus on the &lt;code&gt;Dialog&lt;/code&gt; button after rendering the &lt;code&gt;Dialog&lt;/code&gt;. This is much more convenient to use the &lt;code&gt;Dialog&lt;/code&gt; buttons, especially for screenreader users. We achieved this using &lt;code&gt;useRef&lt;/code&gt; hook which is the proper way to manipulate and access the &lt;code&gt;DOM&lt;/code&gt; element in React.&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%2Fndjcmr5t54h9awjovyiq.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%2Fndjcmr5t54h9awjovyiq.png" alt="Dialog component and focused button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also added &lt;code&gt;role&lt;/code&gt; and &lt;code&gt;aria-describedby&lt;/code&gt; WAI-ARIA attributes to improve accessibility.&lt;/p&gt;

&lt;p&gt;The last &lt;code&gt;useEffect&lt;/code&gt; hook calls the callback function to add an event listener to the &lt;code&gt;window&lt;/code&gt; object after rendering the &lt;code&gt;Dialog&lt;/code&gt; which is triggered after &lt;code&gt;keydown&lt;/code&gt; event. If the pressed key is &lt;code&gt;Escape&lt;/code&gt;, &lt;code&gt;Dialog&lt;/code&gt; will be closed.&lt;/p&gt;




&lt;p&gt;Our &lt;code&gt;Dialog&lt;/code&gt; component is finished, now we can test it.&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, { useContext } from "react";
import DialogContext from "../context/dialog";

function Home() {
  const { setDialog } = useContext(DialogContext);
  const handleClick = () =&amp;gt; {
    setDialog({
      isOpen: true,
      text: 'Are you want to log "Hello World"?',
      handler: () =&amp;gt; console.log("Hello World"),
      noBtnText: "Don't log",
      yesBtnText: "Log it",
    });
  };
  return &amp;lt;button onClick={handleClick}&amp;gt;Activate The Dialog&amp;lt;/button&amp;gt;;
}

export default Home;

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

&lt;/div&gt;



&lt;p&gt;I created a button to activate the &lt;code&gt;Dialog&lt;/code&gt; and added a handler for the button. After clicking it, our &lt;code&gt;Dialog&lt;/code&gt; has shown.&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%2Fgm8b5t4xmn72qqrwqpks.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%2Fgm8b5t4xmn72qqrwqpks.png" alt="Dialog activation button and dialog component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dialog&lt;/code&gt; buttons are working correctly too.&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%2F6ppbrez39g2hoisipcob.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%2F6ppbrez39g2hoisipcob.png" alt="Chrome Dev Tools console, "&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  That's it!
&lt;/h2&gt;

&lt;p&gt;We created our reusable &lt;code&gt;Dialog&lt;/code&gt; component. We can use this &lt;code&gt;Dialog&lt;/code&gt; component for different actions with different texts. &lt;/p&gt;

&lt;p&gt;In order to prevent the performance issues because of rerendering, you should only wrap the components that use the &lt;code&gt;Dialog&lt;/code&gt; with the &lt;code&gt;DialogProvider&lt;/code&gt;, and if there is still performance issues, probably using &lt;code&gt;React.memo&lt;/code&gt; will be a good idea. However, for most applications, I think this won't be needed.&lt;/p&gt;

&lt;p&gt;Feel free to reach out to me &lt;a href="https://github.com/bilkn" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; || &lt;a href="https://www.linkedin.com/in/bilkankonus/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Any feedback would be greatly appreciated.&lt;/p&gt;

</description>
      <category>react</category>
      <category>styledcomponents</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
