javascript - 从 React 外部访问第三方 React 应用程序状态
问题描述
网站使用 React 应用程序附带的第三方插件。
我需要一个 JS 函数,它从那个 React 应用程序状态中读取一些值。但是,我在全局范围内找不到 React 实例window
...... React 将应用程序实例存储在哪里?
我的尝试:当我在 Chrome 中安装浏览器扩展“ React Developer Tools ”时,会有一个全局对象window.$r
允许我访问 React 状态。我能做到var title = window.$r.state.title
。
但是,该$r
对象仅在安装了 React Developer Tools 时才存在。我需要编写一些适用于所有用户的 JS,即使他们没有该浏览器扩展。
此外,我无法修改 React 应用程序以通过引用或导出使状态可用。我只能在应用程序之外编写 JS。
我还尝试检查呈现主应用程序组件的根 DOM 节点,但我还没有找到从中读取应用程序详细信息的方法......
解决方案
我通过搜索大量 JS 数据找到了解决方案,但我可以提取一个返回 React 应用程序状态对象的函数。
我注意到状态嵌套在实际的 React 根 DOM 节点下方 6 到 10 层,因此我编写了一个函数,循环通过 React 应用程序并通过属性名称标识状态。
此代码使用 React 16.7 测试
function getAppState(rootNode, globalAttributeName) {
var $root = jQuery(rootNode);
var reactState = false;
var searchStack = [];
var searched = [];
// Fetch the "__reactInternalInstance$..." attribute from the DOM node.
for ( const key in $root[0] ) {
// The full name changes on every page load, e.g. "__reactInternalInstance$ek3wnas4g6"
if (0 === key.indexOf('__reactInternalInstance$') ) {
searchStack.push($root[0][key]);
break;
}
}
// Find the state by examining the object structure.
while (stack.length) {
var obj = stack.pop();
if (obj && typeof obj == 'object' && -1 === searched.indexOf(obj)) {
if ( undefined !== obj[ globalAttributeName ] ) {
reactState = obj;
break;
}
for (i in obj) {
stack.push(obj[i]);
}
searched.push(obj);
}
}
return reactState;
}
// In my example, I know that the app uses "state.activeModule",
// so I search for the key "activeModule" to identify the state:
getAppState('#root-id', 'activeModule');
// Here is the full path to the state, in my example:
// __reactInternalInstance$ek3wnas4g6g.alternate.return.alternate.return.alternate.memoizedProps._owner.alternate.memoizedState
这个答案确实极大地帮助我找到了这个解决方案:https ://stackoverflow.com/a/12103127/313501
推荐阅读
- ios - 当 AdMob 中的 GADRewardBasedVideoAd 关闭时,标签控制器也会关闭
- apache-spark - Spark编写Parquet数组
加载到 BigQuery 时转换为不同的数据类型 - python - Python - 检查字符串是否在数组的所有元素中
- node.js - 使用 express 框架在 pipeDrive 回调中进行 OAuth 授权
- sql - SQL Server 中的 SQL 查询和执行计划
- node.js - 使用带有异步函数和 setTimeout 的 while 循环。节点
- php - 移动框架时的数据库迁移
- javascript - 返回实例化类 + babel JS
- python - Python 3.6 中没有名为“Matplotlib”的模块错误
- css - 最大宽度媒体查询是否意味着“最多并包括”?