Alguns meses atrás, EU escrevi um post no blog sobre como obter o state do Redux em produção, mas com o recente lançamento do React 18, esse código não funciona mais.
Vamos mergulhar no motivo pelo qual ELE não funciona mais e descobrir como criar um script que funcione.
O que mudou?#
No React 17, o container do React continha uma propriedade chamada _reactRootContainer, e esse não é mais o caso do React 18, como podemos ver no código-fonte do React, que agora usa __reactContainer como um prefixo com uma chave aleatória no final.
Com isso em mente, podemos tentar encontrar o container React verificando se ele contém uma propriedade começando com __reactContainer, mas antes disso, precisamos encontrar todos os elementos DOM potenciais que poderiam ser o container React.
A maioria dos aplicativos React usa um id do HTML para definir o container e, em seguida, usa a função getElementById() para pega-lo, então para pegar todos os elementos com um id no documento, podemos usar document.querySelectorAll("*[id ]").
Para encontrar todos os containers React na página, podemos executar o seguinte script:
const internalRoots = Array.from(document.querySelectorAll("*[id]")).map((el) => {
const key = Object.keys(el).filter((keyName) => keyName.includes('__reactContainer')).pop();
return el[key];
}).filter((key) => key);Pronto! Agora tudo o que temos a fazer é encontrar o _internalRoot e pronto, né? Né?!?!
Não#
Para falar a verdade, essa primeira parte foi bem fácil de descobrir, e como não estou muito familiarizado com o código-fonte do React, após tentar mergulhar em todas as propriedades disponíveis do container, decidi ser preguiçoso e usar a solução mais fácil.

Ok, então sabemos que podemos obter o state do Redux através da função getState(), então tudo o que precisamos fazer é uma busca na árvore da variável do container do React. Fácil.
Felizmente, já existe um GitHub Gist para isso, então tudo o que precisamos fazer é adaptá-lo ao nosso caso, então analisamos uma variável específica em vez da window.
const stores = new Set();
// code from https://gist.github.com/mindplay-dk/1843c267fc633688059dfa5e3b07d0dd
internalRoots.forEach((root) => {
let seen = new Map();
function search(obj) {
if (seen.has(obj)) {
return;
}
seen.set(obj, true);
for (name in obj) {
if (name === 'getState') {
stores.add(obj);
}
if ((obj?.hasOwnProperty?.(name)) && (typeof obj[name] === "object") && (obj[name] != null)) {
search(obj[name]);
}
}
}
search(root);
});Pronto, e daí podemos acessar os states com [...stores].map((store) => store.getState()).

Você pode copiar e colar o script completo abaixo.
const internalRoots = Array.from(document.querySelectorAll("*[id]")).map((el) => {
const key = Object.keys(el).filter((keyName) => keyName.includes('__reactContainer')).pop();
return el[key];
}).filter((key) => key);
const stores = new Set();
// code from https://gist.github.com/mindplay-dk/1843c267fc633688059dfa5e3b07d0dd
internalRoots.forEach((root) => {
let seen = new Map();
function search(obj) {
if (seen.has(obj)) {
return;
}
seen.set(obj, true);
for (name in obj) {
if (name === 'getState') {
stores.add(obj);
}
if ((obj?.hasOwnProperty?.(name)) && (typeof obj[name] === "object") && (obj[name] != null)) {
search(obj[name]);
}
}
}
search(root);
});
[...stores].map((store) => store.getState());E é isso! Nos vemos na próxima!