Home > Blockchain >  NextJS Typescript Modal
NextJS Typescript Modal

Time:03-29

I am trying to build a modal in my app using NextJS with Typescript, but I can't get rid of the warning on my modal selector. How to correctly type this?

const Modal = ({ children }: ModalProps) => {
  const [_document, setDocument] = useState<Document | null>(null);

  useEffect(() => {
    setDocument(document);
  }, []);

  if (_document) {
    return ReactDOM.createPortal(
      <div className={styles.wrapper}>{children}</div>,
      _document.querySelector(_document.body)
    );
  } else {
    return null;
  }
};

enter image description here

CodePudding user response:

getElementById returns a nullable value

getElementById(elementId: string): HTMLElement | null;

but ReactDOM.createPortal only receives non-nullable params

You can be confident about your logic but Typescript is not, so you need to convert those params to non-nullable types for its understanding

const Modal = ({ children }: ModalProps) => {
  const [_document, setDocument] = useState<Document | null>(null);

  useEffect(() => {
    setDocument(document);
  }, []);

  if (_document) {
    return ReactDOM.createPortal(
      <div className={styles.wrapper}>{children}</div>,
      _document.getElementById("modal") as HTMLElement
    );
  } else {
    return null;
  }
};

Or you can use non-null assertion operator

A new ! post-fix expression operator may be used to assert that its operand is non-null and non-undefined in contexts where the type checker is unable to conclude that fact.

The full change can be

const Modal = ({ children }: ModalProps) => {
  const [_document, setDocument] = useState<Document | null>(null);

  useEffect(() => {
    setDocument(document);
  }, []);

  if (_document) {
    return ReactDOM.createPortal(
      <div className={styles.wrapper}>{children}</div>,
      _document.getElementById("modal")! //notice `!` at the end of line
    );
  } else {
    return null;
  }
};

Just a side note that these changes can cause bugs/errors if your values go undefined/null in some parts of your logic

  • Related