从Chrome扩展程序中的Javascript获取reactInstance

时间:2018-03-05 15:33:36

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

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

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

当我使用Chrome检查器时,我发现我的div class="UserWallet">有一个属性__reactInternalInstance。我找到了一个用于获取React实例的函数findReact(element)。此功能用于名为 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

2 个答案:

答案 0 :(得分:3)

作为stated here

  

抬头说,在React 16中,这个黑客不会工作,因为内部属性名称发生了变化。

您尝试搜索的网站可能会使用React 16,以便您的方法无法正常工作。 有一种hacky方式我可以想到挂钩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)

这是控制台输出

Console output

和React Devtools的输出  output from React Devtools

注意:你必须安装React Developer Tools才能使这个技巧发挥作用

答案 1 :(得分:3)

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

也许您可以将嵌入数据放在这样的特定标签中:

<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')

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