Search code examples
javascriptreactjsgoogle-chrome-extensionwhatsapp

How to access a react component fiber in whatsapp web from chrome console?


I'm trying to develop a chrome extension that access the conversation of WhatsApp Web. I'm struggling to access the Conversation component state (component that I can see with the React developper tools)

When I try

document.querySelector("#main")['__reactFiber$lwbvlqgcvdi']

I get something like this

alternate: zu {tag: 5, key: null, elementType: 'div', type: 'div', stateNode: div#main._1fqrG, …}
child: zu {tag: 0, key: '[email protected]', stateNode: null, elementType: ƒ, type: ƒ, …}
childLanes: 1
dependencies: null
elementType: "div"
firstEffect: zu {tag: 5, key: null, elementType: 'div', type: 'div', stateNode: div._26lC3, …}
flags: 0
index: 0
key: null
lanes: 0
lastEffect: zu {tag: 1, key: null, stateNode: t, elementType: ƒ, type: ƒ, …}
memoizedProps: {id: 'main', className: '_1fqrG', style: {…}, children: {…}}
memoizedState: null
mode: 0
nextEffect: null
pendingProps: {id: 'main', className: '_1fqrG', style: {…}, children: {…}}
ref: e=> {…}
return: zu {tag: 10, key: null, elementType: {…}, type: {…}, stateNode: null, …}
sibling: zu {tag: 5, key: null, elementType: 'div', type: 'div', stateNode: div, …}
stateNode: div#main._1fqrG
tag: 5
type: "div"
updateQueue: null
[[Prototype]]: Object

instead of the following result I get when using the React developer tools $r variable

context: {}
props: {setInterval: ƒ, clearInterval: ƒ, setTimeout: ƒ, clearTimeout: ƒ, requestAnimationFrame: ƒ, …}
refs: {}
state: {chat: g, msgCollection: u, focusCtx: {…}, showConversationPreview: false, animate: false, …}
updater: {isMounted: ƒ, enqueueSetState: ƒ, enqueueReplaceState: ƒ, enqueueForceUpdate: ƒ}
_handleCloseChat: e=> {…}
_handleOpenChat: (e,t,a)=> {…}
_handleOpenChatId: 1
_msgCollectionChanged: (e,t,a,s)=> {…}
_newChatScrollInfo: (e,t)=> {…}
_openedChatInfo: {chat: g, renderedMsgsInfo: {…}, visibleMsgOrder: Array(11), clientHeight: 572}
_reactInternals: zu {tag: 1, key: null, stateNode: y, elementType: ƒ, type: ƒ, …}
_refContainer: {current: t.default}
_windowGainedFocus: ()=> {…}
_windowLostFocus: ()=> {…}
[[Prototype]]: m

document.querySelector("#main")['__reactFiber$lwbvlqgcvdi'].stateNodereturns the same element than document.querySelector("#main")['__reactFiber$lwbvlqgcvdi']

document.querySelector("#main")['__reactFiber$lwbvlqgcvdi'].return gives me the context provider wrapping the component

return.stateNode returns null

What do I miss?


Solution

  • I finally figured it out. It was the great great great great grandparent of the #main element. (Element react developer tools gives me as the matching DOM element for the Conversation component)

    Now I know that React developer tools can give the same matching DOM element for different components ^^'

    Update

    To access the state I was looking for I used the following code :

      document.querySelector("#main")['__reactFiber$lwbvlqgcvdi'].return.return.return.return.return.return.stateNode.state
    

    I really found this out of luck as I was crawling up the graph of object out of boredom / despaire / curiosity ^^'