10

Context

I'm trying to debug a React application but cannot modify the source code to log redux variables. In chrome I'm able to access the redux store via the associated extension but it seems no such equivalent exists for safari.

Question

How can I access the redux store in Safari? Can I do so using the console?

Patrick Connors
  • 5,677
  • 6
  • 27
  • 54
  • use a middleware that logs the redux state to console.debug() – Derek Jan 04 '20 at 00:03
  • Question specifics that the source code is not modified – Patrick Connors Jan 04 '20 at 00:05
  • 1
    check your localstorage. it's possible it uses something like `redux-persist` to persist state between refreshes. – Derek Jan 04 '20 at 00:07
  • Good call but no such luck in my case – Patrick Connors Jan 04 '20 at 00:12
  • I just wanted to point out on your [recently deleted question](https://stackoverflow.com/questions/60087583/can-i-limit-credentials-for-certain-origins-in-node-js-without-blocking-requests) that you can programmatically control CORS based on the specified origin and the specified route. See the `origin` function in `corsOptions` [here](https://www.npmjs.com/package/cors). Sorry for hijaacking this question, but you deleted the one I was in the middle of typing a comment on. Still thought I might be able to help and don't have any other way of communicating. – jfriend00 Feb 06 '20 at 04:57

6 Answers6

6

The simplest solution, unfortunately, is to modify the source code to set a global variable to the Redux store. (It may be worth preemptively modifying any applications you can control to do this, just to make Safari easier to debug.)

Without modifying the source code, it should be possible, although it's awkward. The following instructions work for React 16.12.0.

  1. In Safari's Web Inspector (dev tools), go to the Elements tab and find your React root element (the <div id="root"> or similar that you pass to ReactDOM.render).
  2. Click on it. Web Inspector should show a = $0 next to it, indicating that you can now reference that DOM node in the Web Inspector console as $0.
  3. In the Web Inspector's Console tab, type Object.keys($0) and press Enter to see the internal properties that React adds to the DOM node. For my app, I see ["__reactContainere$8yexuoe6iiv", "_reactRootContainer"].
  4. Dump the internal React object to the console by typing $0["__reactContainere$8yexuoe6iiv"] (substituting your internal property name) and pressing Enter.
  5. Inspect the object properties to find the Redux store: on my app, it's under child, under memoizedProps, under store, but this may depend on the specifics of your React component hierarchy and where and how you mount Redux's <Provider>.
  6. Use the store reference you just found to call Redux's getState. For my app, that means typing $0["__reactContainere$8yexuoe6iiv"].child.memoizedProps.store.getState() and pressing Enter.

A simpler one-line alternative to the above:

document.getElementById('root')['_reactRootContainer']._internalRoot.current.child.memoizedProps.store.getState()
Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
  • `document.getElementById('root')['_reactRootContainer']._internalRoot.current.child.memoizedProps.children.props.store.getState()` – 100grams Dec 15 '21 at 12:35
2

In case you are using Nextjs framework, you can achieve this by opening the console in safari. Type window in it. Expand it. Now just check in the window object property. You will find a key something like '__REDUX' or something like that. In my case it was __NEXT_REDUX_STORE__.

Now after you find it just enter the following in your console.:

__NEXT_REDUX_STORE__.getState();

you can now check your current redux state of your application.

Anurag
  • 643
  • 1
  • 11
  • 28
  • 1
    I believe that `__NEXT_REDUX_STORE__` is provided by Next.js. If you're using a more vanilla Redux application, you may be out of luck. – Josh Kelley Jun 14 '21 at 14:13
  • Yes, its for nextjs. But usually in SSR apps using redux, the server sends the store in the HTML tags and from there is creates a global variable to store it. – Anurag Jun 15 '21 at 16:01
0

I'm not aware of a safari extension for redux debugging (corrections welcome). This thread suggests that it's due to a lack of a dev-tools API: https://github.com/zalmoxisus/redux-devtools-extension/issues/435

Redux state isn't in the global scope, so you won't be able to access it through the console without modifying the source code.

Gerard
  • 768
  • 5
  • 20
0

You could just extract state using the connect function. Then just stringify it?

<pre>JSON.stringify({this.props.store, null, 2})</pre>

Then you could visually see it.

Neil
  • 971
  • 2
  • 12
  • 33
0

Adding to @josh-kelley's answer...

In 2021, tested with Safari Version 12.1 (14607.1.40.1.4), following line did the trick for me:

document.getElementById('root')['_reactRootContainer']
    ._internalRoot.current.child.memoizedProps
    .children.props.store.getState()

Notice the children.props difference from what @josh had mentioned.

Farzan
  • 745
  • 10
  • 25
0

According to its GitHub repository for other browsers use remote-redux-devtools.