135

I have unit tests for my reducers. However, when I'm debugging in the browser, I want to check if my actions have been called correctly and whether the state has been modified accordingly.

I'm looking for something like:

window._redux.store

... in the browser so I can type that on the console and check how things are going.

How can I achieve that?

Andre Pena
  • 56,650
  • 48
  • 196
  • 243
  • 1
    As a side note, you might consider using the [Redux Devtools](https://github.com/gaearon/redux-devtools) along with [the `LogMonitor`](https://github.com/gaearon/redux-devtools-log-monitor) to visualize your actions and resulting states. – Michelle Tilley Dec 19 '15 at 18:07
  • 1
    Talking about security, in production build mode, is it possible read store from browser console? – JRichardsz Feb 08 '18 at 20:51
  • @JRichardsz https://stackoverflow.com/questions/43507052/redux-security-is-it-possible-to-access-store-data#comment74068933_43507052 – Daniel Oct 29 '18 at 19:22

11 Answers11

194

How to view redux store on any website, with no code changes

Update Nov 2019

The react devtools have changed since my original answer. The new components tab in chrome's devtools still has the data, but you may have to search a little bit more.

  1. open chrome devTools
  2. select react devtool's Components tab
  3. click on the top-most node and look in right-hand column for store to be shown
  4. repeat step 3 down the tree until you find the store (for me it was the 4th level)
  5. Now you can follow the steps below with $r.props.store.getState()

Example screenshot

Original Answer

If you have react developer tools running you can use $r.store.getState(); with no changes to your codebase.

Note: You have to open the react devtool in your developer tools window first to make this work, otherwise you will get a $r is not defined error

  1. open developer tools
  2. click the React tab
  3. ensure the provider node (or topmost node) is selected
  4. then type $r.store.getState(); or $r.store.dispatch({type:"MY_ACTION"}) into your console
S.Kiers
  • 4,086
  • 3
  • 32
  • 38
  • 2
    Note: for this to work, you need to store the `state` as a property on your root component. If you follow [the directions](https://redux.js.org/basics/usage-with-react#passing-the-store) and have the `` as the top-level component, this will work fine. Just got bit by moving it around! – Aidan Feldman Jul 16 '18 at 23:13
  • Hi @S.Kiers and thanks for this great tip. But since react developer tools also work on production websites, it looks like react developer tools isn't required to connect to the store. Would love it if someone had a nice js command to replace the need for react devtools (eg if wanting to show something on somebody else computer) Also, do you have any tips regarding production environments ? I can see that facebook's store isn't accessible from window.$r, and this sounds a bit more secure that way. Wondering if I shouldn't do the same thing with my product – Adrien Lemaire Aug 06 '18 at 09:46
  • 1
    @Fandekasp Facebook doesn't use redux. Your redux store will always be available to someone with enough will. :) – S.Kiers Aug 18 '18 at 02:57
  • 1
    Mine says `$r` doesn't exist. – CMCDragonkai Jun 25 '19 at 08:15
  • @CMCDragonkai did you read the full answer. There are things you need to do to make this work. Or perhaps the site doesn't use redux? – S.Kiers Jun 27 '19 at 21:47
  • 3
    Try `$r.state.store.getState()` – user1032752 Jul 05 '19 at 21:52
  • While running https://www.valentinog.com/blog/redux/ tutorial, I came upon this problem too. I did not find a way to do this in FireFox dev tools, I had to use Chrome. In Chrome, I clicked Components, then selected the Provider. In the pane below, I clicked console. Then, to get the state, I typed: $r.props.store.getState() – JEPrice Aug 30 '19 at 14:33
  • 4
    Looks like `$r` refers to currently selected component in the `Components` section of Dev Tools. I don't seem to be able to access the entire `store` through `$r`, maybe because I'm using hooks everywhere, but I get to see the part of the store that my component can see, which is almost as good, and sometimes more to the point! – Dima Tisnek Sep 25 '19 at 01:33
  • 2
    `$r.hooks[0].subHooks[0].subHooks[0].value.store.getState()` works for those components that `useSelector`... Ob., YMMV depending on hooks you use... – Dima Tisnek Sep 26 '19 at 04:42
  • 13
    I had to use `$r.props.store` – Kris Dover Jun 11 '20 at 05:41
  • I can't click to console without the Component being unselected. Any ideas? – SAM Jan 13 '21 at 10:34
  • once you pop open components $r will exist – nbpeth Feb 04 '21 at 16:31
  • is this also possible in production builds? – eamanola Aug 30 '21 at 10:22
  • @eamanola yes, it works on production build. Although, depending on the structure, you may have to tweak it a little – S.Kiers Sep 03 '21 at 17:40
  • If above doesn't work then try `$r.props.store.getState()`. Make sure the devtools is open as shown in the image. – Niraj Mar 23 '22 at 13:19
72

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

Now you can access the store from window.store in the console like this:

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

Adrian Silvescu
  • 785
  • 6
  • 10
26

The recommended solution doesn't work for me.

The correct command is:

$r.props.store.getState()
thodwris
  • 1,327
  • 1
  • 17
  • 27
15

You can use a logging middleware as described in the 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)

Alternatively, you could change the logging to just append to a global array (your window._redux) and you could look in the array when you needed information on a particular state.

Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
  • 1
    Or even better, use a library like [redux-logger](https://www.npmjs.com/package/redux-logger) – Anand Sainath Nov 21 '16 at 20:28
  • If you're importing the reducers like this: import reducers from './reducers/' then you can just use let store = createStoreWithMiddleware(reducers) as the './reducers/' file typically will have combineReducers in it. – Bruce Seymour Aug 19 '19 at 20:04
6

If you're using Next JS, you can access the store by: window.__NEXT_REDUX_STORE__.getState()

You can also dispatch actions, just look at the options you have in window.__NEXT_REDUX_STORE__

Satwik Gupta
  • 63
  • 2
  • 6
6

Another answer suggests adding the store to the window, but if you just want access to the store as an object, you can define a getter on the window.

This code needs to be added where you've configured your store - in my app, this is the same file as where <Provider store={store} /> is called.

Now you can type reduxStore in the console to get an object - and copy(reduxStore) to copy it to the clipboard.

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

You can wrap this in an if (process.env.NODE_ENV === 'development') to disable it in production.

James Wilson
  • 852
  • 13
  • 29
1

In case you would like to see store state for debugging you could do this:

#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)
igor
  • 5,351
  • 2
  • 26
  • 22
0

With react developer tools:

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

If you want to use the various methods of the redux state and view it as well, you can store it as a temp global variable and access it via the console. In my solution I used Firefox with React Dev Tools installed. enter image description here

  1. Open React dev tools, find the topmost component where the store is visible.
  2. Right click the store variable in the inspector window and click on Store as global variable. As soon as you do this, you should see some variable name output to the browser's console. Something like $reactTemp0.
  3. You can now use this variable to access the store and its methods. So if I wanted to execute a get method, I could say $reactTemp0.getState() and view the entire state. You can also use other methods, like dispatch, but there might be better ways of testing those behaviors.
Dwigt
  • 729
  • 6
  • 16
0

Another way I was able to access the redux store in my reducers when simply console.log()s were not working was as follows:

First import current like:

import { current } from '@reduxjs/toolkit'

then you can print the values like:

reducers: {
    addItem: (state, action) => {
      // some stuff
      console.log('==>state:');
      console.log(current(state));
    },

! WARNING! : Since the redux store is in a wrapper, simply console logging it would print: Proxy(Object)...

Awshaf Ishtiaque
  • 441
  • 5
  • 11
-3

First of all, you need to define the store in the window object (You can place it in you configureStore file):

window.store = store;

Then you only need to write in the console the following:

window.store.getState();

Hop this helps.

Alberto Perez
  • 2,561
  • 1
  • 14
  • 21