通过 Ref 创建 React Portal

2024-01-02

我想创建一个 Portal 组件,该组件应该附加到它的容器组件,但不是通过容器的 ID,而是通过它的引用。换句话说,我不想将 document.getElementById('CONTAINER_ID') 作为第二个参数传递给 ReactDOM.createPortal 函数,而是仅依赖于 React.forwardRef 传递的容器的 ref。 有没有一种简单的方法可以实现这一目标? 否则我可能需要先创建一个“附加”到 ref 的 dom 节点,然后将该节点传递给 createPortal 函数作为第二个参数?我想尽可能避免分配 id。这是示例代码(我在 TypeScript 中工作):

export default React.forwardRef<HTMLDivElement, Props>( (Props, ref) =>{

        const {state, options, dispatch} = Props                     
        if(!state.open) return null
    
        return  ReactDOM.createPortal(
            <div
            className={css`
              height: 140px;
              background: white;
              overflow-y: scroll;
              position: absolute;
              width:100%;
            `}
          >
            {options}
          </div>,
          ref.current // <-- THIS DOESN'T WORK
        )
        
    }    
)

forwardRef当父组件需要访问子元素时使用,而不是相反。要将元素传递给子元素,您可以通过 prop 来完成。此外,由于直到第一次渲染后才会填充引用,因此您可能需要渲染父组件两次,一次将容器放在页面上,然后再次将其传递给子组件,以便子组件可以创建门户。

const Parent = () => {
  const ref = useRef<HTMLDivElement>(null);
  const [element, setElement] = useState<HTMLDivElement | null>(null);
  useEffect(() => {
    // Force a rerender, so it can be passed to the child.
    // If this causes an unwanted flicker, use useLayoutEffect instead
    setElement(ref.current); 
  }, []);

  return (
    <div ref={ref}>
      {element && (
        <Child element={element} {/* insert other props here */} />
      )}
    </div>
  )
}

const Child = (props: Props) => {
  const { state, options, dispatch, element } = props;
  if (!state.open) {
    return null;
  }

  return ReactDOM.createPortal(
    <div
      className={css`
        height: 140px;
        background: white;
        overflow-y: scroll;
        position: absolute;
        width: 100%;
      `}
    >
      {options}
    </div>,
    element
  );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 Ref 创建 React Portal 的相关文章

  • React 应用程序中的 addEventListener 不起作用

    一些背景 我正在尝试消费自定义网络组件在 React 应用程序中并尝试监听来自 Web 组件的事件 我相信您不能只在自定义 Web 组件上以通常的反应方式处理事件 i e
  • ReactJS - Redux Form - 如何根据单选字段元素有条件地显示/隐藏元素?

    我对 Redux 比较陌生 我有一个表单 其中有一些无线电输入 是 或 否 基本上 我想根据该无线电输入选择有条件地显示包含另一个 redux 表单字段的另一个元素 有直接的方法可以做到这一点吗 我想检查一下formProps site v
  • 如何使用Create React App安装React

    嗨 我对反应真的很陌生 我不知道如何实际安装它 也不知道我需要做什么才能在其中编写代码 我下载了node js并且安装了v12 18 3以及NPM 6 14 6 但是每次我尝试在许多网站上提到的create react app安装方法中输入
  • p5 向量减法“sub”返回错误

    我一直在尝试将 p5 草图上传到 React 构建中 使用react p5 wrapper 我能够成功在屏幕上渲染画布 但是 某些矢量函数会导致错误 var distance this position dist ball position
  • 使用 React.forwardRef 与自定义 ref prop 的价值

    我看到React forwardRef从反应文档来看 似乎是将引用传递给子功能组件的认可方式 const FancyButton React forwardRef props ref gt
  • 如何使用draft.js更改光标位置?

    我想知道在键盘命令上完成文本插入后如何更改 Draft js 中的光标位置 因此我目前正在使用 handleKeyCommand cmd 每当用户按下特定按钮时插入自定义文本块 接下来我尝试了以下操作 currentState this s
  • Redux-saga 从操作中获取数据返回patternOrChannel 未定义

    我需要将动态数据从屏幕发送到操作 减速器 并使用该数据从 API 获取数据 但是当我在我的rootSaga我会收到这样的错误 在检查 take patternOrChannel 时未捕获 patternOrChannel 未定义未捕获在 r
  • 需要有关 React Js 的帮助

    我是 React Js 新手 我的代码无法正常工作 请看下面 这是我的脚本文件Main jsx 该文件由 React 编译 输出放置在 dist 文件夹下的 main js 文件中 var react require react react
  • 如何正确更新反应钩子状态内的数组

    我一直在尝试更新代表反应状态的数组内的对象 当输入的值更改时应该更新该对象 我可以自己找到一种方法来更新它 但我不太确定这是正确的方法 因为当我打开反应开发工具并转到组件选项卡并单击我正在处理的组件时 在输入输入时状态不会立即更新 并且为了
  • React - 检查元素在 DOM 中是否可见

    我正在构建一个表单 用户需要回答一系列问题 单选按钮 然后才能进入下一个屏幕 对于字段验证 我使用 yup npm 包 和 redux 作为状态管理 对于一种特定场景 组合 会显示一个新屏幕 div 要求用户进行确认 复选框 然后用户才能继
  • useLocation 挂钩 - 确定过去的位置

    根据 React Router 5 1文档 https v5 reactrouter com web api location应该可以看到 应用程序现在在哪里 你想让它去哪里 甚至它曾经在哪里 在我的应用程序中 我需要查看 它在哪里 我访问
  • React-redux useDispatch() 未捕获类型错误

    我正在尝试创建一个简单的组件来使用 React Redux 钩子分派操作useDispatch 我收到一个错误 我已将组件修剪到发生错误的位置 当调用 useDispatch 函数时会发生这种情况 import useDispatch fr
  • ant-d upload中如何为removeFile添加PopConfirm一个图片文件

    我正在使用 Ant d Upload 通过本地系统上传文件 然后单击文件预览图像上的删除图标 图像文件将被删除 我想添加一个弹出确认 所以我尝试在 onRemovefunction 中添加确认作为承诺但它不起作用 它在浏览器中显示警报 on
  • 将 Sweet Alert 弹出窗口添加到 React 组件中的按钮

    我为 Bootstrap 和 React 找到了这个完美的 Sweet Alert 模块 我在 Meteor 应用程序中使用它 http djorg83 github io react bootstrap sweetalert http d
  • 如何修复超出最大调用堆栈大小

    有一个 MERN Firebase 应用程序并收到此错误和一堆 atdeepExtend deepCopy ts 71 RangeError Maximum call stack size exceeded getApps as apps
  • Google 将自动完成功能放置在 React 组件中

    我正在尝试构建一个谷歌地图组件 谷歌地图 API v3 一切正常 但自动完成功能不行 这是我正在使用的代码 Google 地图组件 import React Component from react import ReactDOM from
  • 如何在 React js 上使用历史记录重定向到另一个页面?

    我在前端使用 Reactjs 并在后端使用 Laravel 开发了一个注册页面 我希望当我单击注册按钮时 它将被重定向到我的登录页面 我的注册组件是 handleSubmit event gt event preventDefault co
  • 为什么react中的组件需要大写? [复制]

    这个问题在这里已经有答案了 因此 当您声明一个组件以小写首字母进行反应时 它不会显示 也不会引发错误 当您将组件名称大写时 它确实有效 这样的实现是怎样的呢 为了避免与现有的 html 元素发生冲突 还是这是一个错误 var test Re
  • 带有 'as' 属性的通用 React TypeScript 组件(能够渲染任何有效的 dom 节点)

    我在下面的示例中按预期工作 我的问题是 无论如何我可以重写它 这样我就不必传递通用的T和as支柱 理想情况下我想通过asprop 并让组件的 prop 接口使用它 这在 TypeScript 中可能吗 export type Props l
  • React hooks 状态变量在重新渲染后未更新

    在下面的示例中 我有一个想要更新的元素 水果 数组 并使用更新后的数组执行其他操作 在本例中保存更新后的列表 我的理解是重新渲染状态将更新 但它不在这里 或者状态更新和我的操作之间存在延迟 In the addFruit功能我可以看到 Pe

随机推荐

  • 曲线透视:将 3D 转换为 2D

    我正在寻找转换 3D 坐标的数学表达式 x0 y0 z0 到 2D x1 y1 坐标在一个曲线透视 http en wikipedia org wiki Curvilinear perspective半径R其中 x1 和 y1 的值是原始点
  • 使用标准 .NET Framework 的 AOP 类属性的基本实现 [重复]

    这个问题在这里已经有答案了 可能的重复 C 通过属性包装方法 https stackoverflow com questions 2206554 c sharp wrap method via attributes 我想实现这样的功能 At
  • iPhone自定义相机覆盖(加上图像处理):操作方法[重复]

    这个问题在这里已经有答案了 可能的重复 如何创建自定义相机视图 而不是 UIImagePickerViewController https stackoverflow com questions 5156417 how do you cre
  • 如何在 MERN 中组织后端和前端的文件结构

    我有基于express mongoose 的后端 文件结构为 models item js node modules server js package lock json package json 以及常规的基于 create react
  • Pandas 创建空数据框时出错

    我尝试制作一个虚拟数据框 column names a b c df pd DataFrame columns column names 我收到以下错误 以前没有发生过这种情况 我是否遗漏了一些东西 这仅发生在创建空数据框时 这是最近引入的
  • ffmpeg 支持 KLV 元数据吗?

    是ffmpeg的元数据 也有描述 http wiki multimedia cx index php title FFmpeg Metadata http wiki multimedia cx index php title FFmpeg
  • UISearchbar 键盘搜索按钮操作

    我在用着UISearchBar当我输入文字时UISearchBar键盘显示 此时 键盘返回键是 搜索 我想在按下键盘搜索按钮时实现事件 我该如何实施该行动 在UITextField it has BOOL textFieldShouldRe
  • AxisFault:Server.userException 是什么意思?

    以下 AxisFault 是什么意思 这是否意味着 服务器发出和接收的请求以及服务器抛出 未捕获的 异常 因此该异常被返回给客户端 or 我的 Web 应用程序无法创建 SOAP 请求 因此该请求甚至不是从客户端应用程序发送的 注意 我是网
  • 为什么需要调用 close() 或 shutdown() 方法?

    我是 Java 新手 高中时有一些 C 背景 现在我正在尝试做一些事情 我选择了 Java 作为编程语言 我已经完成了我的作业并查看了很多关于 Java 的 析构函数 的内容 完成 方法 以及close or 关闭 方法 但我仍然认为我不知
  • Python 中哪个最好:urllib2、PycURL 还是 mechanize?

    好的 我需要使用 Python 下载一些网页 并对我的选项进行了快速调查 Python 中包含 urllib http docs python org library urllib html 在我看来我应该使用 urllib2 代替 url
  • Linux 相当于 DOS 暂停的是什么?

    我有一个 Bash shell 脚本 我想在其中暂停执行 直到用户按下某个键 在 DOS 中 这可以通过以下命令轻松完成pause命令 我可以在脚本中使用 Linux 等效项吗 read做这个 user host read n1 r p P
  • 最小、独立、可分发、跨平台 Web 服务器

    我最近一直在编写相当多的小型 wsgi 应用程序 并且正在寻找一个可以分布式 预先配置为运行特定应用程序的 Web 服务器 我知道像twisted和cherrypy这样的东西可以为wsgi应用程序提供服务 但它们似乎缺少我的一个关键功能 即
  • 最佳 2D 调色板排列算法

    给定一组256我想创建一个颜色16 x 16 调色板从这些颜色中 颜色之间所有 4 个相关差异的总和最小 当然有256个 不同的安排 因此不考虑暴力 我尝试使用贪婪算法 从最接近黑色的颜色开始 然后以之字形对角线方式穿过 16x16 网格
  • 从 BeautifulSoup 中的 JSON 对象中解析出特定值

    import urllib from urllib import request from bs4 import BeautifulSoup url http mygene info v3 query q symbol CDK2 speci
  • 如何使用 Marmalade 编译 Cocos2d-X?

    有谁知道教程 或者三个简单的步骤来编译我用 Cocos2d x 和 Marmalade 编写的代码 我想将我已经在 Cocos2d X 中编译和使用的代码插入到 marmalade 项目中 然后进行编译 很多地方都写得很简单 但我却很难做到
  • 如何在生成的 html 代码中插入换行符

    我正在使用 codeigniter 生成一个 html 表以插入到模板视图中 不幸的是 这在一行中以非常长的字符串形式出现 例如 table class table table bordered table striped tbody tr
  • Typescript 2.1.5 不支持函数调用

    我有以下 ngrx 减速器功能 export const raceReducer ActionReducer
  • Playground 执行失败:错误:无法查找符号 - 使用 swift 在 xcode 中的 Playground

    我刚刚开始使用游乐场并尝试运行一些基本代码 例如 import UIKit var str Hello playground 我想它应该实时运行 但在我的情况下需要永远运行 一段时间后 我收到以下错误 Playground executio
  • ElasticSearch 文档值有哪些缺点

    该文档声称 10 25 slower than in memory fielddata and It is possible that doc values will become the default format in the nea
  • 通过 Ref 创建 React Portal

    我想创建一个 Portal 组件 该组件应该附加到它的容器组件 但不是通过容器的 ID 而是通过它的引用 换句话说 我不想将 document getElementById CONTAINER ID 作为第二个参数传递给 ReactDOM