0

I am trying to create a Modal on React and am using TypeScript. I got an error of a 'parameter of type Node' and couldn't figure out what this is (nor subsequently fix my problem).

const Modal = ({ children }: { children: any }) => {
  const elRef = useRef<HTMLDivElement | null>(null); //tried adding'| Node'
  if (!elRef.current) {
    const div = document.createElement("div");
    div.className = "modalDiv";
    elRef.current = div;
  }

  useEffect(() => {
    const modalRoot = document.getElementById("modal");
//Argument of type 'HTMLDivElement | null' is not assignable to parameter of type 'Node'.
//Type 'null' is not assignable to type 'Node'.ts(2345)
    modalRoot!.appendChild(elRef.current);

    return () => modalRoot!.removeChild(elRef.current);
  }, []);

  return createPortal(<div>{children}</div>, elRef.current);
};
uber
  • 4,163
  • 5
  • 26
  • 55
  • 1
    There is `ReactNode` https://stackoverflow.com/questions/58123398/when-to-use-jsx-element-vs-reactnode-vs-reactelement – keikai Apr 25 '20 at 08:26
  • I tried adding ReactNode but that doesn't solve my problem – uber Apr 25 '20 at 08:34
  • 1
    To answer the question in the title (which doesn't seem the same as the question in the body), [Node](https://developer.mozilla.org/en-US/docs/Web/API/Node) is one of the most basic concepts in HTML manipulation. – Álvaro González Apr 25 '20 at 08:36
  • All you're doing doesn't look idiomatic for React. Anyway type error happen because `elRef.current` defined as nullable. You can go with `modalRoot!.appendChild(elRef.current!);` because you're sure it is initialized – Aleksey L. Apr 25 '20 at 08:36
  • 1
    `ReactNode` is not relevant here – Aleksey L. Apr 25 '20 at 08:38
  • How would I go about solving this? this fix by @AlekseyL. kind of pushes the problem to the useEffect now, stating that ```Argument of type '() => () => HTMLDivElement' is not assignable to parameter of type 'EffectCallback'. ``` – uber Apr 25 '20 at 08:48
  • 1
    Please change question title, this is misleading, try to use the TS error and the context. – leonardfactory Apr 25 '20 at 12:21

1 Answers1

3

The problem typescript is signaling here is not about the Node. Node is a generic DOM element, and HTMLDivElement matches correctly. The problem is the null value it may assume, and a null is obviously not a Node, so you cannot use null in appendChild.

You should add a check like if (elRef.current != null) { ... } in order to ensure the HTMLDivElement has been correctly created.

useEffect(() => {
    const modalRoot = document.getElementById("modal");
    if (elRef.current) modalRoot!.appendChild(elRef.current);

    return () => {
      if (elRef.current) modalRoot!.removeChild(elRef.current);
    }
  }, []);

An easier way (and in this case, a more logical one) would be just to use elRef.current! to tell TS you are sure that the element is present, and this is clear given your previous code.

leonardfactory
  • 3,353
  • 1
  • 18
  • 25