Uncaught Error: Target container is not a DOM element. at Object.createPortal$1 [as createPortal]

83 Views Asked by At

I have a react CheckProfileModal component that is supposed to render a modal to a portal div I created in the index.html. My Home.jsx handles the UseEffect hook that checks the firestore database and renders the modal if certain conditions are true. I get the uncaught error even though my portal div is present in my index.html.

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React</title>
    <script type="module" crossorigin src="/assets/index-5dfa2cb2.js"></script>
    <link rel="stylesheet" href="/assets/index-c1e7090c.css" />
  </head>
  <body>
    <div id="root"></div>
    <div id="portal"></div>
  </body>
</html>

These are the other components: CheckProfileModal .jsx

import React from "react";
import ReactDOM from "react-dom";
import { Backdrop, Box, Fade, Modal, Typography } from "@mui/material";

import styles from "../../src/assets/Styles/ModalStyles.module.css";

export const CheckProfileModal = () => {
  const [open, setOpen] = React.useState(false);
  const handleClose = () => setOpen(false);
  // handleopen to be triggered by useEffect

  return ReactDOM.createPortal(
    <>
      <Modal
        aria-labelledby="transition-modal-title"
        aria-describedby="transition-modal-description"
        open={open}
        onClose={handleClose}
        closeAfterTransition
        slots={{ backdrop: Backdrop }}
        slotProps={{
          backdrop: {
            timeout: 500,
          },
        }}
      >
        <Fade in={open}>
          <Box sx={styles}>
            <Typography id="transition-modal-title" variant="h6" component="h2">
              Text in a modal
            </Typography>
            <Typography id="transition-modal-description" sx={{ mt: 2 }}>
              Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
            </Typography>
          </Box>
        </Fade>
      </Modal>
    </>,
    document.querySelector("#portal")
  );
};

Home.jsx

import { IconButton, Typography } from "@mui/material";
import { getDoc, doc } from "firebase/firestore";
import React, { useEffect, useState } from "react";
import { db } from "../utils/firebaseConfig";
import "@fontsource/lexend";
import "@fontsource/lexend/500.css";
import "@fontsource/lexend/100.css";
import styles from ".././assets/Styles/AddictionsOptiosStyles.module.css";
import classNames from "classnames";
import Alcohol from ".././assets/images/addictions/alcohol.png";
import { nanoid } from "nanoid";
import { CheckProfileModal } from "../Modals/CheckProfileModal";

export const Home = () => {
  const userCredentials = JSON.parse(localStorage.getItem("userCredentials"));
  const [firstName, setfirstName] = useState("");
  const [modal, setModal] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const userSnap = await getDoc(doc(db, "users", userCredentials));
        if (
          !userSnap.data().firstName ||
          !userSnap.data().lastName ||
          !userSnap.data().mobile
        ) {
          setModal(true);
        } else if (
          userSnap.data().firstName ||
          userSnap.data().lastName ||
          userSnap.data().mobile
        ) {
          setfirstName(userSnap.data().firstName);
        }
      } catch (error) {
        console.log("Error fetching user data:", error);
      }
    };

    fetchData();
  }, [userCredentials]);

  return (
    <>
      <div className="pl-5">
        <div className={classNames("pt-10", styles.homeHeader)}>
          <div className={styles["headerName"]}>
            <Typography
              sx={{
                fontFamily: "Lexend",
                fontSize: "20px",
                fontWeight: 500,
                lineHeight: "22px",
                letterSpacing: "0.005em",
                textAlign: "left",
              }}
            >
              Hello, {firstName}
            </Typography>
            <Typography
              sx={{
                fontFamily: "Lexend",
                fontSize: "15px",
                fontWeight: 100,
                lineHeight: "22px",
                letterSpacing: "0.005em",
                textAlign: "left",
                paddingTop: "10px",
              }}
            >
              How are you doing today?
            </Typography>
          </div>
          <div key={nanoid()} className={styles["profile-image"]}>
            <IconButton>
              <div>
                <img src={Alcohol} />
              </div>
            </IconButton>
          </div>
        </div>
      </div>
      {modal && <CheckProfileModal />}
    </>
  );
};

0

There are 0 best solutions below