原生JavaScript访问React Props及函数的内部属性遍历问题
问题背景
- 研究React运行机制过程中,正在开发Google Chrome扩展,无法直接获取React组件的访问权限,需要通过原生JavaScript访问props中封装的函数,实现测试场景下的点击自动化操作。已知安装React开发者工具扩展后可在Chrome开发者控制台查看相关内容,但该方案无法满足需求。
现象描述
- 在Chrome开发者控制台中可通过如下代码选中目标DOM元素:
var elem = document.querySelector('.wrap-XdW9S1Ib');
- 上述元素为目标操作对象,它的props中包含需要调用的onClick事件处理函数。在控制台交互界面手动输入如下代码:
elem.__reactProps$63clhtkk874
可以正常获取到包含onClick等React自动生成函数的props对象,可清晰看到React生成的onClick事件与其他函数。
- 将完全相同的逻辑写入普通JS文件执行时,尤其是运行如下遍历代码:
for(key in elem){console.log(key);}
遍历元素所有属性时,__reactFiber和__reactProps这类属性完全不会出现在遍历结果中,仅能获取到align、title、lang等DOM原生属性,无法看到React相关属性。
- 代码逻辑和控制台手动输入的逻辑完全一致,控制台打印功能运行正常,唯独无法获取到React挂载的事件相关属性。
核心疑问
为什么这类React内部属性在开发者控制台手动输入指令时可以正常访问,在普通JS文件(非控制台交互式输入环境)中运行相同代码时,无法通过遍历获取到这些属性?
原因说明
出现这个差异的核心原因有两个:
- React内部属性的不可枚举特性
React 16及之后版本,挂载到真实DOM节点上的__reactFiber$[随机后缀]、__reactProps$[随机后缀]这类内部属性,都是通过Object.defineProperty方法定义的,默认设置了enumerable: false,也就是不可枚举属性。
原生JS的for...in循环、Object.keys()方法,默认只会遍历对象自身及原型链上可枚举的属性,自然不会把这些不可枚举的React内部属性列出来。这不是属性不存在——只要你写对完整的属性名,哪怕是不可枚举属性,直接访问是可以正常拿到值的。 - Chrome控制台的执行环境特殊处理
Chrome开发者工具的交互式控制台不是纯原生JS执行环境,它做了一层额外封装:当你在控制台输入代码访问DOM元素、打印元素属性时,控制台会主动读取元素上所有不可枚举的内部属性、甚至浏览器层面的内部绑定属性做展示,相当于帮你绕过了原生JS的可枚举属性遍历限制,所以你手动输入属性名访问、甚至在控制台展开元素看属性的时候,能看到这些React内部字段。
普通JS脚本中获取React内部属性的实现方案
不要用for...in遍历,直接通过获取对象自身所有属性(包含不可枚举属性)的方式匹配键名即可,适配Chrome扩展content script、普通页面JS场景:
// 选中目标元素 const elem = document.querySelector('.wrap-XdW9S1Ib'); // 获取元素自身的所有属性名,包含不可枚举属性 const ownPropNames = Object.getOwnPropertyNames(elem); // 匹配React挂载的props、fiber对应的键名(同页面所有React元素的后缀一致) const reactPropsKey = ownPropNames.find(key => key.startsWith('__reactProps')); const reactFiberKey = ownPropNames.find(key => key.startsWith('__reactFiber')); // 直接访问对应值 const reactProps = elem[reactPropsKey]; const reactFiber = elem[reactFiberKey]; // 比如要调用onClick,直接取即可 const onClickHandler = reactProps.onClick; // 执行点击逻辑,注意要根据业务逻辑补全事件对象参数 onClickHandler?.();
注意:不要硬编码
__reactProps后面的随机后缀,这个后缀是React初始化时随机生成的,不同页面、不同React版本的后缀都不一样,必须运行时动态匹配。
内容的提问来源于stack exchange,提问作者Joseph Astrahan
相关产品推荐
相关产品推荐

