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 pInternals = dom[key]._currentElement;
var pWrapper = pInternals._owner;
var p = pWrapper._instance;
return p;
}
}
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
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 pInternals = dom[key]._currentElement;
var pWrapper = pInternals._owner;
var p = pWrapper._instance;
return p;
}
}
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
Share Improve this question edited Nov 7, 2018 at 18:24 KyleMit♦ 30.8k72 gold badges511 silver badges702 bronze badges asked Mar 5, 2018 at 15:33 cedric_gcedric_g 1094 bronze badges 2-
1
A
$
without ajQuery
is different in console (it returns an HTML element) and$
with a jQuery is different. You should make sure that if it is ajQuery
on then then you get the element first and then check for__reactInternalInstance$
. @mrmusicman – Tarun Lalwani Commented May 31, 2018 at 11:10 - Since React 16+ your code for findReact won't work because internal property names changed.You may try the function on my answer here: (updated to work for React <16 and 16+) – eQ19 Commented Nov 21, 2019 at 6:54
2 Answers
Reset to default 4As 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
ponents (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
and the output from React Devtools
NOTE: you have to install React Developer Tools to make this trick work
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