2

I'm studying how react currently works and am a bit confused how to access the functions that are hidden in the props with native javascript. I'm aware if I download the react extension I can view them in the google developer console but this is not what I need. I don't have access to the react components directly because I'm making a Google chrome extension.

For example in the Chrome Developer Console, I can type the following:

var elem = document.querySelector('.wrap-XdW9S1Ib');

Lets just say that this element is my element of interest and it has an onClick event within it's props that I would like to access to automate clicks for testing purposes.

Attached is a picture of the progress so far:

enter image description here

I can then type something like...

elem.__reactProps$63clhtkk874

Which shows the below:

enter image description here

Note you can see the onClick event and other functions that react creates.

Now... if you try to do this same thing via code. In particular the for(key in elem){console.log(key);} for some reason __reactFiber and __reactProps do not appear!

enter image description here

Note: Notice that align,title,lang etc... all show up but the __reactProps are not there now.

Note#2: My code is identical to what you see above in the pictures and works just fine printing out to console (as you can also see in the screenshot), except..., I just don't see the react events.

Why do these show up in the developer console and NOT in the same console via my code I write. In otherwords, when I type in the console prompt it not via non prompt (I.E, just regular .js file)

Joseph Astrahan
  • 8,659
  • 12
  • 83
  • 154
  • This was closed without any explanation and the link reason makes no sense. I feel this is a valid question and not a duplicate. – Joseph Astrahan Jun 23 '22 at 17:40

2 Answers2

3

I found the solution to this question, it is indeed because the chrome extension is in isolated memory space compared to the DOM. To get access to that variable I first have to inject my script into the regular DOM and then use chrome messaging api to send a message to my injected script to THEN get the variables I'm looking for. Hopefully this helps someone else out. I can see why my question was initially closed now as a duplicate, but none the less I think this may help some people that get confused by this particular issue when it comes to react.

Joseph Astrahan
  • 8,659
  • 12
  • 83
  • 154
  • can you please explain more about how did you inject your script inside the dom – Nachat Ayoub Mar 17 '23 at 20:01
  • You have to do something like this: var s = document.createElement('script'); s.src = chrome.runtime.getURL('./js/page-script.js'); s.onload = function() { this.remove(); }; (document.head || document.documentElement).appendChild(s); – Joseph Astrahan Mar 27 '23 at 23:14
  • The code you run @NachatAyoub has to be in a content script file, so run this code from your contentscript.js or equivalent. This essentially loads it outside of the chrome DOM space and in the ACTUAL space that react exists in. – Joseph Astrahan Mar 27 '23 at 23:15
0

I'm just guessing over here. But judging from the underscores you are probably accessing elements from React's internal virtual DOM. Which may or may not be the same as the DOM. I've read that React was built for the purpose of abstracting away the imperative DOM manipulation that vanilla javascript uses.

Though sometimes interacting with the DOM cannot be avoided, so whenever I see DOM manipulation in React, I think of the useRef hook. By setting the useRef hook to a variable and linking it to a DOM element, you can console.log variable.current, and see the real DOM element and work with it in a useEffect hook for example. Hope this was at least a little helpful! All the best in your learning endeavors!

Reuben B
  • 184
  • 1
  • 6
  • How do I do that with vanilla JS though? – Joseph Astrahan Jun 23 '22 at 17:39
  • The best answer I could come up with is: useEffect(() => { let ele=document.querySelector(".App"); console.log(ele); }, []); This prints two properties that you are looking for. I don't know how to do it through pure javascript though if it is even possible. Sorry I misunderstood your question. – Reuben B Jun 23 '22 at 18:35
  • I found a native js way of doing it! setTimeout(() => { const app = document.querySelector(".App"); console.dir(app); }, 0); Hope this helps! :) – Reuben B Jun 24 '22 at 02:34