【问题标题】:ReactDOM.createPortal modal is mounted on DOM but nothing is displayed on the screenReactDOM.createPortal modal 挂载在 DOM 上,但屏幕上没有显示任何内容
【发布时间】:2021-05-01 00:07:24
【问题描述】:

这是一个 typescript-next.js 项目。我有这个模态组件:

interface ModalProps {
  onCancelModal: () => void;
  onAcceptModal: () => void;
  acceptEnabled: boolean;
  isLoading?: boolean;
  title: string;
}

const Modal: React.FC<ModalProps> = (props) => {
  let containerRef = useRef<HTMLDivElement | null>(null);
  console.log("container", containerRef);
  useEffect(() => {
    const rootContainer = document.createElement("div");
    const parentElem = document.querySelector("#__next");
    parentElem?.insertAdjacentElement("afterend", rootContainer);
    if (!containerRef.current) {
      containerRef.current = rootContainer;
    }
    return () => rootContainer.remove();
  }, []);
  return containerRef.current
    ? ReactDOM.createPortal(
        <div className="modal">
          <header className="modal__header">
            <h1>{props.title}</h1>
          </header>
          <div className="modal__content">{props.children}</div>
          <div className="modal__actions">
            <Button design="danger" mode="flat" onClick={props.onCancelModal}>
              Cancel
            </Button>
            <Button
              mode="raised"
              onClick={props.onAcceptModal}
              disabled={!props.acceptEnabled}
              loading={props.isLoading}
            >
              Accept
            </Button>
          </div>
        </div>,
        containerRef.current
      )
    : null;
};

export default Modal;

我将自定义错误传递给 ErrorHandler 组件:

const ErrorHandler: React.FC<ErrorHandlerProps> = (props) => (
  <Fragment>
    {props.error && <Backdrop onClick={props.onHandle} />}
    {props.error && (
      <Modal
        title="An Error Occurred"
        onCancelModal={props.onHandle}
        onAcceptModal={props.onHandle}
        acceptEnabled
      >
        <p>{props.error}</p>
      </Modal>
    )}
  </Fragment>
);

但是,Modal 组件已成功安装在 DOM 上,但屏幕上没有显示任何内容。

编辑 我有背景和模态组件。

// css for backdrop
.backdrop {
  width: 100%;
  height: 100vh;
  background: rgba(0, 0, 0, 0.75);
  z-index: 100;
  position: fixed;
  left: 0;
  top: 0;
  transition: opacity 0.3s ease-out;
  opacity: 1;
}

// css for Modal
.modal {
  position: fixed;
  width: 90%;
  left: 5%;
  top: 20vh;
  background: white;
  border-radius: 5px;
  z-index: 200;// I changed this to 999999 but didnot solve the issue
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
}

.modal__header {
  border-bottom: 2px solid #3b0062;
}

.modal__header h1 {
  font-size: 1.5rem;
  color: #3b0062;
  margin: 1rem;
}

.modal__content {
  padding: 1rem;
}

.modal__actions {
  padding: 1rem;
  text-align: right;
}

.modal__actions button {
  margin: 0 0.5rem;
}

@media (min-width: 768px) {
  .modal {
    width: 40rem;
    left: calc((100% - 40rem) / 2);
  }
}

【问题讨论】:

  • 看来 DOM 渲染正确。因此,问题可能是由 css 引起的。 Modal 中的 CSS 怎么样?
  • 您能否单击f12 devtool 中的div.modal DOMElement。它将在屏幕上显示模态可见范围。并获取快照,可以更清楚地检查模态是否正确呈现在屏幕中间。
  • @bcjohn 当我点击 div.modal 时它不会突出显示屏幕。但是,当我单击 div.backdrop 时,屏幕会突出显示。所以看起来像 div.modal 永远不会被激活
  • @bcjohn 我解决了这个问题。感谢您的宝贵时间!
  • 太棒了!很高兴您解决了问题。

标签: reactjs typescript modal-dialog next.js react-portal


【解决方案1】:

我在刷新记忆后找到了答案。我意识到元素样式选项卡上还有另一个.modal className。它指向/node_modules/bootstrap/scss/_modal.scss 文件,该文件也有modal 类名,它覆盖了我的自定义类名。

.modal {
  position: fixed;
  top: 0;
  left: 0;
  z-index: $zindex-modal;
  display: none;
  width: 100%;
  height: 100%;
  overflow: hidden;
  // Prevent Chrome on Windows from adding a focus outline. For details, see
  // https://github.com/twbs/bootstrap/pull/10951.
  outline: 0;
  // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
  // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
  // See also https://github.com/twbs/bootstrap/issues/17695
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多