Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get reactInstance from Javascript in Chrome Extension

I'm currently facing a problem while developing a Chrome Extension. This extension is used on a ReactJS based website. I need to scrap some data from the page. He is an example of the page.

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

When I use the Chrome inspector, I can see that my div class="UserWallet"> has a property __reactInternalInstance. I found a function findReact(element) used to get the React Instance. This function is used in an other Chrome Extension called Steemit-More-Info. I have the exact same function and a use the same HTML element as parameter but my function is not working. When I do $(".UserWallet)", the result doesn't contains the property __reactInternalInstance. But in the other extension, it's working with the same JQuery code and the same findReact function.

Here is the code for 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;
};

Has anyone ever faced that problem? Is there a special library that I need to include in my extension to be able to scrap the reactInstance?

Thank you,

cedric_g

like image 375
cedric_g Avatar asked Mar 05 '18 15:03

cedric_g


2 Answers

As stated here:

Heads up that in React 16 this hack won't work because internal property names changed.

Your website you're trying to scrape might use React 16 so that your approach won't work. There is one hacky way I could think is to hook the react-devtools, and get the instance that the react-devtools already populate for you.

The following code is to get the MarkdownEditor components (the last one) from React homepage, run it in the console and you can get the result

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)

This is the console output

Console output

and the output from React Devtools output from React Devtools

NOTE: you have to install React Developer Tools to make this trick work

like image 174
An Nguyen Avatar answered Oct 08 '22 06:10

An Nguyen


A workaround idea when you can modify the webpage.

Maybe you can put the nedded data in a specific tag like this:

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

And then you can easily get this element by using

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

And so you can get the inner Text of this element

like image 21
chrisheyn Avatar answered Oct 08 '22 08:10

chrisheyn