【问题标题】:Access third party React app state from outside React从 React 外部访问第三方 React 应用程序状态
【发布时间】:2020-02-16 20:18:21
【问题描述】:

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

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

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

另外,我无法修改 React 应用程序以通过 ref 或 export 使状态可用。我只能在app外写JS。

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

【问题讨论】:

  • 谁说一个页面上只能运行一个 React 应用程序?我已经为更大的非 React 管理界面的各个部分编写了大量使用 10 个或更多 React“应用程序”的页面。
  • 这是很好的反馈,迈克!您对我如何访问特定应用程序有什么建议(例如,当我知道根 DOM 节点时)?

标签: javascript reactjs


【解决方案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

【讨论】:

    猜你喜欢
    • 2014-11-21
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 2017-12-26
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多