September 28, 2022

Robotic Notes

All technology News

All You Need to Know — Lyty.dev BlogLyty.dev Blog

4 min read


React Portal allows you to render child components into a DOM node that exists outside the DOM hierarchy of the parent component. It serves as a global transporter that helps to transport any children outside a parent component within your application. This article takes you through all you need to know about react portals with some details of React portal examples to learn it fast.

Syntax

ReactDOM.createPortal(child, container)

Portals in React take two arguments, the first argument accepts what you want to render which can be element, stringor fragment while the second argument is the DOM element you are targeting. The first argument will be injected into the targeted DOM element meanwhile React does not create any additional component or HTML element when performing the operation. Even though the React portal can be rendered anywhere in the DOM within the app, it also behaves like a normal React child which makes it possible to access and perform any operation a React child does such as accepting props, accessing the context API, etcetera, this is possible because the portal component exists in React tree hierarchy.

When To Use Portal

Normally, when you render a component in React, it will mount into the DOM as the child to the nearest dom elements eg

const Parent = () => {
  return (
    <div className="parent-node">
      <ChildComponent />
    </div>
  )
}
const ChildComponent = () => {
  return (
    <div>
      This is a child component
    </div>
  )
}

Whenever <ChildComponent /> render, it will mounts <div>This is a child component</div> which automatically makes it become the child to the nearest DOM elements. In our own case which is <div className="parent-node"> </div>
The final result will look like this:

const Parent = () => {
  return (
    <div className="parent-node">
      <div>
        This is a child component
      </div>
    </div>
  )
}

However, it makes more sense if you can inject the component wherever you want in the DOM node not only where the component is being rendered.

React Portal Examples, Use cases, And Solution

A typical use-case of the React portal is when building dialogues, hover cards, and tooltips which most time requires to break out within its parent node. Let’s assume we have a parent node that has a style of overflow:hidden and the width is just one-quarter of the viewport width, technically, if we render a component within this parent node, the component will automatically inherit its styles and may not break out within this parent. This is where the portal comes in, it helps to insert a node outside its initial parent. Below is a graphic illustration.

illustration

Let’s Build Something – A Dialogue

The first thing is to set up a React application, the easiest way to do this is to bootstrap or create your app with any of the commands below.

Npx
    npx create-react-app my-app
    cd my-app
    npm start

Yarn
    yarn create react-app my-app
    cd my-app
    yarn start

We are going to write most of our codes in the App.jsdelete all the codes inside the file then create a basic component and call it Portal, move on by pasting the following codes.

import { useRef, useEffect, useState } from "react";
import { createPortal } from "react-dom"; 
function Portal({ children, selector }) {
  const ref = useRef();
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    ref.current = document.querySelector(selector);
    setMounted(true);
  }, [selector]);

  return mounted ? createPortal(children, ref.current) : null;
}

We imported the createPortal from react-dom and pass the children (React child) as its first argument, ref. current as the second argument which is used to hold the node we are targeting, Meanwhile, we also import some useful hooks such as useEffect which runs after component render and useState which is used to keep the state. Click to learn more about React hook here. The next thing we are going to do is to create our modal component and do my pasting of the below code after the portal component.

function Modal({ children, showModal, toggleModalDisplay }) {


  const styles = {
    modalParent: {
      width: "100vw",
      height: "100vh",
      position: "fixed",
      background: "rgba(0,0,0,.5)",
      top: 0,
      justifyContent: "center",
      alignItems: "center",
      display: "flex"

    },
    modalContentContainer: {
      width: "40%",
      height: "auto",
      background: "#fff",
      padding: "25px"
    }
  }

  if (showModal) {
    return (
      <Portal selector="#modal-container">
        <div style={styles.modalParent}>
          <div style={styles.modalContentContainer}>
            {children}

            <button onClick={toggleModalDisplay}>
              Click to hide modal
            </button>
          </div>
        </div>
      </Portal>
    )
  }
  return null

}

The modal component takes received three props, the children , showModal and toggleModalDisplay, The first prop is a normal React child, the second represents a boolean which we used to determine whether to show the modal or hide it while the third one is a function to open the modal. Technically, whenever the modal component is being rendered, the Portal component will be called as it's a child to the modal component.

Note:

We passed a prop selector="#modal-container" to the Portal which serves as the ID of the node we are targeting. ie

<div id="modal-container"><div/>


So What Next?

'The last thing is to make use of the modal component.


export default function App() {
  const [showModal, setShowModal] = useState(false)

  const toggleModalDisplay = () => setShowModal(!showModal)

  return (
    <div id="modal-container">

      <div style={{ width: "33.33%", height: "33.33%", overflow: "hidden" }} class="parent">
        <Modal toggleModalDisplay={toggleModalDisplay} showModal={showModal}>
          This is a modal context
        </Modal>

        <button onClick={toggleModalDisplay}>
          Click me to open modal
        </button>
      </div>

    </div>
  )
}

showModal is a boolean which decides the visibility of the modal, while toggleModalDisplay is a function that is used to toggle the visibility of the modal. Even though the modal is rendered inside the <div class="parent">the modal component won't mount inside its parent node because the modal triggered the createPortal function which targets a node outside its parent node.

See Live Example

Developer Console Debug

illustration

Conclusion

The portal function has been a great function since it was introduced in React 16.0. As you can see it's very handy and serves its purpose. If you enjoyed this tutorial, don't hesitate to comment on what you have gained so far.



Source link