React中createPortal 的详细用法

createPortal 是 React 提供的一个实用工具,用于将 React 子元素渲染到 DOM 中的某个位置,而该位置与父组件不在同一个 DOM 层次结构中。这在某些特殊场景下非常有用,比如实现模态框、弹出菜单、固定定位元素等功能。

基本语法

JavaScript

复制

复制代码
const portal = createPortal(child, container);
  • child 是要渲染的 React 子元素。

  • container 是 DOM 元素,子元素将被渲染到这个元素中。

使用场景

  1. 模态框:将模态框的内容渲染到 body 的顶层,以确保模态框不会被其他元素遮挡。

  2. 弹出菜单:将弹出菜单渲染到 body 的顶层,以确保菜单不会被其他元素遮挡。

  3. 固定定位元素:将固定定位的元素渲染到 body 的顶层,以确保元素的定位不会受到父元素的影响。

示例

下面是一个使用 createPortal 实现模态框的示例:

复制代码
import React, { useState, useEffect } from 'react';
import { createPortal } from 'react-dom';

function Modal() {
  const [showModal, setShowModal] = useState(false);

  // 创建一个 DOM 元素作为模态框的容器
  const modalRef = React.useRef(document.createElement('div'));

  useEffect(() => {
    // 将模态框容器添加到 body 中
    document.body.appendChild(modalRef.current);
    return () => {
      // 组件卸载时移除模态框容器
      document.body.removeChild(modalRef.current);
    };
  }, []);

  return (
    <>
      <button onClick={() => setShowModal(true)}>Open Modal</button>

      {showModal && (
        createPortal(
          <div className='modal-overlay'>
            <div className='modal'>
              <h2>Modal Title</h2>
              <p>This is a modal content</p>
              <button onClick={() => setShowModal(false)}>Close Modal</button>
            </div>
          </div>,
          modalRef.current
        )
      )}
    </>
  );
}

export default Modal;
CSS
复制代码
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}

.modal {
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  width: 300px;
}

优点

  • 灵活性:可以将子元素渲染到 DOM 中的任意位置。

  • 避免样式冲突:通过将元素渲染到不同的 DOM 层次结构中,可以避免样式冲突。

  • 优化性能:通过减少不必要的 DOM 操作,可以优化性能。

注意事项

  • 清理资源:在组件卸载时,确保移除创建的 DOM 元素,以避免内存泄漏。

  • 样式隔离:确保渲染到不同 DOM 层次结构中的元素不会受到其他样式的影响。

总结

createPortal 是 React 提供的一个强大工具,用于将子元素渲染到 DOM 中的任意位置。通过使用 createPortal,可以实现模态框、弹出菜单等功能,并确保这些元素的样式和行为不受父组件的影响。

以下是一个更完整的示例,展示如何使用 createPortal 实现一个模态框:

复制代码
import React, { useState } from 'react';
import { createPortal } from 'react-dom';

function Modal() {
  const [showModal, setShowModal] = useState(false);

  // 创建一个 DOM 元素作为模态框的容器
  const modalRef = React.useRef(document.createElement('div'));

  // 将模态框容器添加到 body 中
  useEffect(() => {
    document.body.appendChild(modalRef.current);
    return () => {
      document.body.removeChild(modalRef.current);
    };
  }, []);

  return (
    <>
      <button onClick={() => setShowModal(true)}>Open Modal</button>

      {showModal && (
        createPortal(
          <div className='modal-overlay'>
            <div className='modal'>
              <h2>Modal Title</h2>
              <p>This is a modal content</p>
              <button onClick={() => setShowModal(false)}>Close Modal</button>
            </div>
          </div>,
          modalRef.current
        )
      )}
    </>
  );
}

export default Modal;

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal {
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  width: 300px;
  max-height: 80vh;
  overflow-y: auto;
}

在这个示例中,模态框的内容被渲染到一个独立的 DOM 容器中,该容器被添加到 body 中。这确保了模态框不会被其他元素遮挡,并且可以独立于父组件进行样式控制。

相关推荐
2501_920931702 小时前
React Native鸿蒙跨平台采用ScrollView的horizontal属性实现横向滚动实现特色游戏轮播和分类导航
javascript·react native·react.js·游戏·ecmascript·harmonyos
0思必得03 小时前
[Web自动化] Selenium处理动态网页
前端·爬虫·python·selenium·自动化
摘星编程4 小时前
React Native鸿蒙版:Drawer抽屉导航实现
react native·react.js·harmonyos
东东5164 小时前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino4 小时前
图片、文件的预览
前端·javascript
2501_920931705 小时前
React Native鸿蒙跨平台实现推箱子游戏,完成玩家移动与箱子推动,当所有箱子都被推到目标位置时,玩家获胜
javascript·react native·react.js·游戏·ecmascript·harmonyos
layman05286 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔6 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李6 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN6 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化