Durante a depuração, posso ter acesso à loja Redux do console do navegador?


88

Eu tenho testes de unidade para o meu reducers. No entanto, quando estou depurando no navegador, quero verificar se minhas ações foram chamadas corretamente e se o estado foi modificado de acordo.

Estou procurando algo como:

window._redux.store

... no navegador para que eu possa digitar no console e verificar como as coisas estão indo.

Como posso conseguir isso?


1
Como uma observação lateral, você pode considerar o uso do Redux Devtools junto com oLogMonitor para visualizar suas ações e estados resultantes.
Michelle Tilley

1
Falando em segurança, no modo de construção de produção, é possível ler a loja no console do navegador?
JRichardsz de

Respostas:


151

Como visualizar a loja redux em qualquer site, sem alterações de código

Atualização de novembro de 2019

Os devtools de reação mudaram desde minha resposta original. A nova componentsguia nos devtools do Chrome ainda contém os dados, mas talvez você precise pesquisar um pouco mais.

  1. abrir cromo devTools
  2. selecione a Componentsaba do devtool de reação
  3. clique no nó superior e procure na coluna da direita storepara ser mostrado
  4. repita o passo 3 descendo a árvore até encontrar o store(para mim, era o 4º nível)
  5. Agora você pode seguir as etapas abaixo com $r.store.getState()

Captura de tela de exemplo

Resposta Original

Se você tiver ferramentas de desenvolvedor Rea em execução, poderá usá $r.store.getState();-lo sem alterações em sua base de código .

Nota: Você precisa abrir o react devtool na janela de ferramentas do desenvolvedor primeiro para fazer este trabalho, caso contrário, você receberá um $r is not definederro

  1. abrir ferramentas de desenvolvedor
  2. clique na guia React
  3. certifique-se de que o nó do provedor (ou nó superior) esteja selecionado
  4. em seguida, digite $r.store.getState();ou $r.store.dispatch({type:"MY_ACTION"})em seu console

2
Observação: para que isso funcione, você precisa armazenar o statecomo uma propriedade em seu componente raiz. Se você seguir as instruções e tiver o <Provider>como o componente de nível superior, isso funcionará bem. Só fui mordido movendo-o!
Aidan Feldman

3
Experimente$r.state.store.getState()
user1032752

4
Parece que $rse refere ao componente atualmente selecionado na Componentsseção de Ferramentas de Desenvolvimento. Parece que não consigo acessar todo o storecaminho $r, talvez porque estou usando ganchos em todos os lugares, mas consigo ver a parte da loja que meu componente pode ver, que é quase tão boa, e às vezes mais para o ponto!
Dima Tisnek

2
$r.hooks[0].subHooks[0].subHooks[0].value.store.getState()funciona para os componentes que useSelector... Ob., YMMV dependendo dos ganchos que você usa ...
Dima Tisnek

3
Eu tive que usar$r.props.store
Kris Dover

62

let store = createStore(yourApp); window.store = store;

Agora você pode acessar a loja em window.store no console desta forma:

window.store.dispatch({type:"MY_ACTION"})


6
e também pode acessar o estado:window.store.getState()
Liran Brimer

13

Você pode usar um middleware de registro conforme descrito no Redux Book :

/**
 * Logs all actions and states after they are dispatched.
 */
const logger = store => next => action => {
  console.group(action.type)
  console.info('dispatching', action)
  let result = next(action)
  console.log('next state', store.getState())
  console.groupEnd(action.type)
  return result
}

let createStoreWithMiddleware = applyMiddleware(logger)(createStore)

let yourApp = combineReducers(reducers)
let store = createStoreWithMiddleware(yourApp)

Como alternativa, você pode alterar o registro para apenas anexar a um array global (your window._redux) e pode olhar no array quando precisar de informações sobre um determinado estado.


1
Ou melhor ainda, use uma biblioteca como redux-logger
Anand Sainath

Se você estiver importando os redutores assim: import reducers from './reducers/', então você pode apenas usar let store = createStoreWithMiddleware (reducers), pois o arquivo './reducers/' normalmente terá combineReducers nele.
Bruce Seymour

7

A solução recomendada não funciona para mim.

O comando correto é:

$r.props.store.getState()

deve ser um comentário para essas respostas
gdbdable

6

Se estiver usando o Next JS , você pode acessar a loja: window.__NEXT_REDUX_STORE__.getState()

Você também pode despachar ações, basta olhar as opções que você tem emwindow.__NEXT_REDUX_STORE__


1

Caso queira ver o estado da loja para depuração, você pode fazer o seguinte:

#import global from 'window-or-global'
const store = createStore(reducer)
const onStateChange = (function (global) {
  global._state = this.getState()
}.bind(store, global))
store.subscribe(onStateChange)
onStateChange()
console.info('Application state is available via global _state object.', '_state=', global._state)

1

Outra resposta sugere adicionar a loja à janela, mas se você quiser apenas acessar a loja como um objeto, pode definir um getter na janela.

Este código precisa ser adicionado onde você configurou sua loja - em meu aplicativo, este é o mesmo arquivo de onde <Provider store={store} /> é chamado.

Agora você pode digitar reduxStoreno console para obter um objeto - e copy(reduxStore)copiá-lo para a área de transferência.

  Object.defineProperty(window, 'reduxStore', {
    get() {
      return store.getState();
    },
  });

Você pode embrulhar isso em um if (process.env.NODE_ENV === 'development')para desativá-lo na produção.


-1

Com as ferramentas de desenvolvedor react:

const store = [...__REACT_DEVTOOLS_GLOBAL_HOOK__.reactDevtoolsAgent.internalInstancesById.values()].find(e=>e.elementType.name==="Provider").pendingProps.store

1
Uncaught TypeError: Cannot read property 'values' of undefinederro
gdbdable

-2

Em primeiro lugar, você precisa definir o armazenamento no windowobjeto (você pode colocá-lo em seu configureStorearquivo):

window.store = store;

Então você só precisa escrever no console o seguinte:

window.store.getState();

Espero que isso ajude.


store é indefinido no console por padrão. Como isso chega lá?
Jen S.

Store precisaria ser definido primeiro no objeto window antes de poder ser usado.
Rafael Rozon

@RafaelRozon Sim, você está certo, eu editei minha resposta para mostrar isso.
Alberto Perez
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.