从 React 外部访问第三方 React 应用程序状态

IT技术 javascript reactjs
2021-05-22 09:23:17

网站使用 React 应用程序附带的第三方插件。

我需要一个 JS 函数来从 React 应用程序状态中读取一些值。但是,我在全局window范围内找不到 React 实例... React 在哪里存储应用程序实例?

我的尝试:当我在 Chrome 中安装浏览器扩展“ React Developer Tools ”时,有一个全局对象window.$r允许我访问 React 状态。我可以var title = window.$r.state.title
但是,该$r对象仅在安装了 React Developer Tools 时才存在。我需要编写一些适用于所有用户的 JS,即使他们没有那个浏览器扩展。

此外,我无法修改 React 应用程序以通过引用或导出使状态可用。我只能在应用程序之外编写JS。

我还尝试检查呈现主应用程序组件的根 DOM 节点,但我还没有找到一种方法来从中读取应用程序详细信息......

1个回答

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