React - 从子 DOM 元素获取 React 组件?

IT技术 javascript dom reactjs
2021-04-20 09:50:59

我希望能够弄清楚什么 React 组件与某个 DOM 元素相关联。

例如,假设我有一个 div,我正在使用 React 渲染我的整个应用程序。div 必须由 React 组件呈现 - 但哪一个?

我知道 React 提供了方法“ getDOMNode ”来获取与 React 组件关联的 DOM 节点,但我想做相反的事情。

这可能吗?

3个回答

不。

React 中的一个中心概念是您实际上并没有在 DOM 中进行控制。相反,您的控制权是工厂功能。DOM 中的内容是控件的当前呈现。

如果你真的需要这个,你可以保留一个对象作为全局变量,它的键是工厂函数名称的字符串表示,其值是工厂函数,然后在你的可渲染 div 上,保留一个包含名称的属性工厂功能。

但这很可能是 XY 问题的问题(需要 X,看到 Y 的方法,然后询问如何做 Y。)可能如果你要解释你的目标,那么有一种更好的方法更适合 React 自上而下的概念模型.

一般来说,要求从其渲染中访问控件就像要求从其缓存的 PNG 渲染中访问 SVG。这是可能的,但通常是一个危险信号,表明其他东西在概念上是错误的。

@Andy - 你说得对,总有例外。不过,在大多数情况下,使用 CSS 过渡会更轻松,我愿意花两美元
2021-06-02 09:50:59
好点子,但是像 React Native 这样的程序和像 React DevTools 这样的工具都创建了一种从 DOM/native 元素获取 React 组件的方法。
2021-06-06 09:50:59
不,这不是 XY 问题。我需要这个用于需要与 reactjs 网页交互的用户脚本。
2021-06-14 09:50:59
总是有例外,例如,我正在考虑实施老式自定义 DnD 而不是使用 HTML5 DnD,这样我就可以使用拖动反馈图像来制作很多时髦的动画和东西。
2021-06-19 09:50:59
@frontsidebus - 按照 iOS 的消息驱动 UI 系统的工作方式,React Native 需要这样做。DevTools 这样做是因为它是一个调试器。
2021-06-20 09:50:59

这是我在 React 15.3.0 中使用的:

window.FindReact = function(dom) {
    for (var key in dom) {
        if (key.startsWith("__reactInternalInstance$")) {
            var compInternals = dom[key]._currentElement;
            var compWrapper = compInternals._owner;
            var comp = compWrapper._instance;
            return comp;
        }
    }
    return null;
};

然后使用它:

var someElement = document.getElementById("someElement");
FindReact(someElement).setState({test1: test2});
这是一个黑客。即使对于黑客来说,它也是非常丑陋的。这当然不是您可以依赖的东西。
2021-06-05 09:50:59
由于某种原因,它不起作用(返回null)。尽管我将 React 15.3.0 与 react-rails 一起使用——也许这就是原因。
2021-06-06 09:50:59
@AluanHaddad 同意,尽管它可能对开发过程中的某些调试任务有所帮助。
2021-06-16 09:50:59
这里有一个也适用于 Fiber 的新版本:stackoverflow.com/a/39165137/2441655
2021-06-17 09:50:59
这将随着fiber. 将未记录的内部结构与像 React 一样频繁更改的库使用可能是不明智的
2021-06-18 09:50:59

如果您的情况需要从 DOM 节点获取react元素,这里是一种方法,“通过事件进行通信并回调”

您应该在 DOM 元素上触发一个自定义事件,并在 React 组件中为该自定义事件设置事件侦听器。这会将 DOM 元素映射回 React 组件。

很棒的建议,我有一个表单验证脚本,需要验证许多不同类型的 React 组件。结合 jQuery.trigger('custom_event', data)和监听componentDidMount那个 custom_event 真是太棒了。
2021-05-23 09:50:59
你能在你的帖子中添加一个例子来描述你如何做到这一点吗?
2021-06-08 09:50:59
非常非常聪明的可能解决方案,实施起来有点麻烦,但建议为 5*。
2021-06-16 09:50:59
这不会让您获得子元素;它为您提供了一个闭包,其中包含来自渲染的旧传递的虚拟 dom 节点的过时副本,数据集可能已过时,几乎可以保证会发生变化,并且上下文已损坏。这是非常不正确的。
2021-06-19 09:50:59