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

39

我希望能够找出与特定DOM元素相关联的React组件。

例如,假设我有一个div,在整个应用程序中使用React进行渲染。这个div必须由一个React组件进行渲染 - 但是它是哪一个呢?

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

这可能吗?

3个回答

17

在React中,一个核心概念是你实际上没有DOM中的控制权。相反,你的控制是工厂函数。DOM中的内容是控制的当前渲染。

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

但很可能这是XY问题(需要X,看到了Y的方法,然后问如何执行Y)。如果您解释清楚您的目标,可能有更好的方法更适合React的自上而下的概念模型。

一般来说,要求从渲染中访问控件就像要求从缓存的PNG渲染中访问SVG一样。这是可能的,但通常是其他概念性错误的红旗。


3
不错的观点,但是像React Native这样的程序和React DevTools这样的工具都可以从DOM / 原生元素中创建获取React组件的方式。 - frontsidebus
1
总会有例外,例如我正在研究实现老派的自定义 DnD,而不是使用 HTML5 DnD,这样我就可以在拖动反馈图像上做很多时髦的动画和其他事情。 - Andy
1
不,这不是XY问题。我需要它用于用户脚本,该脚本需要与ReactJS网页进行交互。 - Tomáš Zato
@frontsidebus - 顺便提一下,React Native是必需的,因为iOS的消息驱动UI系统需要它。DevTools之所以这样做是因为它是一个调试器。 - John Haugeland
尊敬的先生,我认为您误解了我的评论观点,请尽量减少个人攻击。祝您有一个愉快的一天。 - John Haugeland
显示剩余2条评论

11

以下是我在使用 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});

由于某些原因它不起作用(返回“null”)。虽然我正在使用React 15.3.0与react-rails - 也许这就是原因。 - EugZol
1
这是一个黑客行为。即使对于黑客来说,它也非常丑陋。它肯定不是你可以依赖的东西。 - Aluan Haddad
2
@AluanHaddad 同意,尽管在开发过程中进行某些调试任务时可能会有所帮助。 - Venryx
这将随着fiber的发布而破裂。在React这样频繁更改的库中使用未记录的内部可能是不明智的。 - John Haugeland
2
这里有一个新版本,可以与Fiber一起使用:https://dev59.com/j10b5IYBdhLWcg3wUP4X#39165137 - Venryx

7
如果您需要从DOM节点获取React元素,可以采用“通过事件和回调进行通信”的方法。您应该在DOM元素上触发自定义事件,并在React组件中为该自定义事件添加事件监听器。这将把DOM元素映射回React组件。

很棒的建议,我有一个表单验证脚本需要验证许多不同类型的React组件。这个建议与jQuery .trigger('custom_event', data)结合使用非常棒,并在componentDidMount中监听该自定义事件。 - Ross The Boss
1
非常聪明的可能解决方案,实现起来有点麻烦,但对于这个建议给予五星评价。 - Kayote
这不会给你子元素;它会给你一个闭包,其中包含来自旧的渲染过程的虚拟DOM节点的过时副本,数据集可能已经过期,几乎可以肯定会出现在Flux中,并具有损坏的上下文。 这是非常不正确的。 - John Haugeland
2
你能否在你的帖子中添加一个例子,描述一下你如何完成这个任务? - Kevin Ghadyani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接