- Blog ➔
- Programação ↴
Como acessar o state do Redux de um build de produção do React 18
Solução atualizada para acessar o state do Redux em um build de produção com o React 18
Escrito em 21 de agosto de 2022 - 🕒 3 min. de leituraHá alguns meses atrás, eu publiquei um post no meu blog sobre como acessar o state do Redux em um build de produção utilizando o console do navegador. No entanto, com o lançamento recente do React 18, essa técnica não funciona mais.
Neste blog post, vamos explorar o motivo pelo qual ela deixou de funcionar e como criar um script que ainda permita acessar o state do Redux em produção.
O que mudou?
No React 17, havia uma propriedade chamada _reactRootContainer
no container do React, mas essa propriedade não existe mais no React 18. Em vez disso, como podemos ver no código-fonte do React, o container do React agora possui uma propriedade prefixada com __reactContainer
e um número aleatório no final.
Para encontrar o container do React, podemos procurar por elementos DOM que possuem uma propriedade começando com __reactContainer
. Primeiro, precisamos encontrar todos os elementos DOM que podem ser potencialmente o container do React.
A maioria dos aplicativos React usa um id
HTML para definir o container e, em seguida, usa a função getElementById()
para recuperá-lo. Portanto, para obter todos os elementos com um “id” no documento, podemos usar document.querySelectorAll("*[id ]")
.
Para encontrar todos os containers do 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')).at(-1);
return el[key];
}).filter((key) => key);
Pronto! Agora tudo o que temos a fazer é encontrar o _internalRoot
e pronto, né? Né?!?!
Não
Na verdade, descobrir a primeira parte foi relativamente simples. Como não estou muito familiarizado com o código-fonte do React, tentei explorar todas as propriedades disponíveis do container, mas acabei optando pelo caminho mais fácil, ainda que preguiçoso.
Já que para obter o state do Redux usamos a função getState()
, tudo o que precisamos fazer é percorrer a árvore de variáveis do container do React em busca dela.
Felizmente, já existe um Gist do GitHub para isso, então basta adaptá-lo para o nosso caso, examinando 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')).at(-1);
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());
Conclusão
Para concluir, neste post, exploramos o motivo pelo qual o método anterior para acessar o state do Redux em um build de produção deixou de funcionar no React 18 e apresentamos uma solução atualizada que permite acessar o state do Redux em produção.
Apesar de ter sido um desafio descobrir o novo método, com a ajuda de um script já existente e um pouco de adaptação, conseguimos encontrar uma solução viável.
Espero que este post tenha sido útil e que você consiga utilizá-lo em seus futuros projetos.
Tags:
Posts relacionados
Publicar um comentário
Comentários
Nenhum comentário.