首页 > 解决方案 > 从 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 节点,但我还没有找到从中读取应用程序详细信息的方法......

标签: javascriptreactjs

解决方案


我通过搜索大量 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


推荐阅读