【问题标题】:Get reactInstance from Javascript in Chrome Extension从 Chrome 扩展中的 Javascript 获取 reactInstance
【发布时间】:2018-03-05 15:33:36
【问题描述】:

我目前在开发 Chrome 扩展程序时遇到了问题。此扩展用于基于 ReactJS 的网站。我需要从页面中删除一些数据。他就是这个页面的一个例子。

<div class="UserWallet">
   <tbody>
      <tr class"Trans"><td>...</td></tr>
      ...
   <tbody>
</div>

当我使用 Chrome 检查器时,我可以看到我的 div class="UserWallet"&gt; 有一个属性 __reactInternalInstance。我找到了一个函数findReact(element) 用于获取 React Instance。此功能用于另一个名为 Steemit-More-Info 的 Chrome 扩展程序。我有完全相同的功能,并使用相同的 HTML 元素作为参数,但我的功能不起作用。当我执行$(".UserWallet)" 时,结果不包含__reactInternalInstance 属性。但在另一个扩展中,它使用相同的 JQuery 代码和相同的 findReact 函数。

这里是 findReact 的代码。

var findReact = function(dom) {
   for (var key in dom) {
      if (key.startsWith("__reactInternalInstance$")) {
        var compInternals = dom[key]._currentElement;
        var compWrapper = compInternals._owner;
        var comp = compWrapper._instance;
        return comp;
      }
    }
    return null;
};

有人遇到过这个问题吗?是否需要在我的扩展中包含一个特殊的库才能废弃 reactInstance?

谢谢,

cedric_g

【问题讨论】:

  • 没有jQuery$ 在控制台中是不同的(它返回一个HTML 元素)和带有jQuery 的$ 是不同的。您应该确保如果它是jQuery,那么您首先获取元素,然后检查__reactInternalInstance$。 @mrmusicman
  • 由于 React 16+ 您的 findReact 代码将无法工作,因为内部属性名称已更改。您可以在此处尝试我的回答中的功能:(updated to work for React <16 and 16+)

标签: javascript reactjs google-chrome-extension web-scraping


【解决方案1】:

作为stated here:

请注意,在 React 16 中,此 hack 将不起作用,因为内部属性名称已更改。

您尝试抓取的网站可能使用 React 16,因此您的方法将不起作用。 我能想到的一种怪方法是挂钩react-devtools,并获取react-devtools 已经为您填充的实例。

下面的代码是从React homepage获取MarkdownEditor组件(最后一个),在控制台运行就可以得到结果

var reactDevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__._fiberRoots;
var instArray = [...reactDevToolsHook[Object.keys(reactDevToolsHook)[0]]];
var mdInst = instArray[8];
console.log(mdInst.current.child.stateNode)

这是控制台输出

以及来自 React Devtools 的输出

注意:您必须安装 React Developer Tools 才能使这个技巧起作用

【讨论】:

    【解决方案2】:

    当您可以修改网页时的解决方法。

    也许您可以将 nedded 数据放在特定标签中,如下所示:

    <div class="UserWallet">
        <span
          style={{ display: 'none' }}
          id="my-user-wallet-data"
        >{ JSON.stringify(myData) }</span>
      ... 
    </div>
    

    然后你可以很容易地通过使用得到这个元素

    var wallet = document.getElementById('my-user-wallet-data')

    这样你就可以得到这个元素的内部文本

    【讨论】:

    • 好吧...这不是一个好的解决方案。当您可以修改网页时,您可以将数据存储在全局变量中:window.myData = myData
    猜你喜欢
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    相关资源
    最近更新 更多