'ReactDOM.render is not rendering element created through React.createElement

I created a modal component that utilizes React's context, and hooks for easy usage. But for some reason, the element that I want to render in the modal doesn't appear.

Here's my code for the ModalContainer which contains the provider and the modal

ModalContainer.tsx

export type ModalElement =
  | React.ComponentClass<any, any>
  | React.FC<any>
  | JSX.Element;

const ModalContainer: React.FC = ({ children }) => {
  const [visible, setVisible] = useState(false);

  const modal = useRef<HTMLDivElement>(null);

  const showModal = (element: ModalElement) => {
    if (element && modal.current) {
      if (React.isValidElement(element)) {
        ReactDOM.render(element, modal.current);
      } else {
        const el = React.createElement(
          element as React.ComponentClass<any, any> | React.FC<any>,
          {}
        );

        ReactDOM.render(el, modal.current);
      }
      setVisible(true);
    }
  };

  const dismissModal = () => {
    setVisible(false);
  };

  return (
    <ModalContext.Provider value={{ showModal, dismissModal }}>
      {children}
      <Modal visible={visible} onClose={dismissModal} ref={modal} />
    </ModalContext.Provider>
  );
};

export default ModalContainer;

useModal.ts

export const useModal = (element: ModalElement) => {
  const context = useContext(ModalContext);

  if (!context) {
    Error(`Can't get modal context`);
  }

  const show = useCallback(() => {
    context.showModal(element);
  }, [context, element]);

  const dismiss = useCallback(() => {
    context.dismissModal();
  }, [context]);

  return [show, dismiss];
};

In a way that you'll use it as such:

const DivModal: React.FC = () => {
  return <div>Test</div>
}

const Component: React.FC = () => {
  const [show, dismiss] = useModal(DivModal);
  
  const onClick = () => {
    show();
  }

  return <button onClick={onClick}/>
}

The problem seems to happen when I create an element using React.createElement in the ModalContainer.tsx found specifically in this line:

const el = React.createElement(
  element as React.ComponentClass<any, any> | React.FC<any>,
  {}
);

ReactDOM.render(el, modal.current);

The modal renders properly if I replace el in the render function with a test JSX such as <div>test</div>. Can't really figure out what's wrong so I'll post it here just in case anyone knows what the problem is. Thanks!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source