React Error: Target container is not a DOM Element: got when loading a Modal Form

405 Views Asked by At

I'm working on a shopping cart application using ReactJS and Context-API, so far, I achieved this:

  1. load my products from Firebase
  2. Add product to the cart

The next step is to display the cart's content loading a modal form when the user clicks on the properly icon, but in this part I'm getting this error:

Target container is not a DOM Element

Target container is not a DOM Element

This is the code from FoodOrder, which is one of the most important:

import React, { useState } from "react";
import Header from "./Layout/Header";
import Meals from "./Meals/Meals";
import Cart from "./Cart/Cart";
import CartProvider from "./store/CartProvider";

const FoodOrder = () => {
  const [cartIsShown, setCartIsShown] = useState(false);

  const showCartHandler = () => {
    setCartIsShown(true);
  };

  const hideCartHandler = () => {
    setCartIsShown(false);
  };

  return (
    <CartProvider>
      {cartIsShown && <Cart onClose={hideCartHandler} />}
      <Header onShowCart={showCartHandler} />
      <main>
        <Meals />
      </main>
    </CartProvider>
  );
};

export default FoodOrder;

Header.js component is like a container which pass the props to HeaderCartButton, the bellow code is from Header.js:

import React, { Fragment } from "react";
import HeaderCartButton from "./HeaderCartButton";
import mealsImage from "../assets/banner.jpg";
import classes from "./Header.module.css";

const Header = (props) => {
  return (
    <Fragment>
      <header className={classes.header}>
          <h1>Let's order pupusas</h1>
          <HeaderCartButton onClick={props.onShowCart} />
          </header>
          <div className={classes['main-image']}>
              <img src={mealsImage} alt="all you can eat pupusas" />
              </div>
    </Fragment>
  );
};


export default Header;

And this is the code from HeaderCartButton.js:

import { useContext, useEffect, useState } from "react";
import CartIcon from "../Cart/CartIcon";
import CartContext from "../store/cart-context";
import classes from "./HeaderCartButton.module.css";

const HeaderCartButton = (props) => {
    const [btnIsHighlighted, setBtnIsHighlighted] = useState(false);
    const cartCtx = useContext(CartContext);

    const { items } = cartCtx;

    const numberOfCartItems = items.reduce((curNumber, item) => {
        return curNumber + item.amount;
    }, 0);

    const btnClasses = `${classes.button} ${
        btnIsHighlighted ? classes.bump : ""
    }`;

    useEffect(() => {
        if(items.length === 0){
            return;
        }
        setBtnIsHighlighted(true);
        const timer = setTimeout(() => {
            setBtnIsHighlighted(false);
        }, 300);
        return() => {
            clearTimeout(timer);
        }
    }, [items]);

    return(
        <button className={btnClasses} onClick={props.onClick}>
            <span className={classes.icon}>
                <CartIcon />
            </span>
            <span>Your Shopping</span>
            <span className={classes.badge}>{numberOfCartItems}</span>
        </button>
    );
}

export default HeaderCartButton;

Finally, this is the source code from the Modal.js component:

import React from "react";
import ReactDOM from "react-dom";
import classes from "./Modal.module.css";

const Backdrop = (props) => {
  return <div className={classes.Backdrop} onClick={props.onClose}></div>;
};

const ModalOverLay = (props) => {
  return (
    <div className={classes.modal}>
      <div className={classes.content}>{props.children}</div>
    </div>
  );
};

const portalElement = document.getElementById("overlays");

const Modal = (props) => {
  return (
    <React.Fragment>
      {ReactDOM.createPortal(
        <Backdrop onClose={props.onClose} />,
        portalElement
      )}
      {ReactDOM.createPortal(
        <ModalOverLay>{props.children}</ModalOverLay>,
        portalElement
      )}
    </React.Fragment>
  );
};

export default Modal;

As a final comment I'm not getting the error neither in the main web browser nor in my vscode console, I had to check the devtools to figure out what is going on.

So, any hints how to debug this error? what am I missing?

Thanks a lot

1

There are 1 best solutions below

1
On

I believe your problem is this part:

{cartIsShown && <Cart onClose={hideCartHandler} />}

By doing this you're essentially not rendering the Cart component at all if cartIsShow is false.

It would be better to implement it this way:

<Cart onClose={hideCartHandler} visible={cartIsShown} />

And then handle the rendering inside the Cart component using that value so that you can appropriately make use of the lifecycle functionality inside the Cart component (instead of avoid that all completely)