zalmoxisus / redux-devtools-extension

Redux DevTools extension.
MIT License
13.5k stars 1.01k forks source link

When browser doesn't have the redux devtools extension the app throws an undefined error #320

Open Arrow7000 opened 7 years ago

Arrow7000 commented 7 years ago

My React/Redux app worked fine on my computer but when I sent it to someone else the app would fail to load altogether.

After some debugging it turns out that window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() was returning undefined, which meant that .apply() was being called on undefined, thereby causing the error.

I therefore propose to change this line in the documentation to:

window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f

This will make sure that if the redux extension is not present, the store enhancer added will at least be a function, as opposed to undefined.

I will submit a pull request immediately.

zalmoxisus commented 7 years ago

That's because you're including it inside the compose. In this case you should use window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose instead. See Advanced store setup.

Arrow7000 commented 7 years ago

Hm ok I see. Does the __REDUX_DEVTOOLS_EXTENSION_COMPOSE__ include additional functionality? Because if it doesn't it looks like my solution is a little bit cleaner. Would obviate the need for an additional global variable.

I haven't tested this on a basic store, but if it does work on a basic store then maybe it could be nicer to only have a single line of code that will add the functionality for both?

What do you think?

zalmoxisus commented 7 years ago

Yes, it does. Because the enhancer is last in the compose, it is not aware of other middlewares and enhancers, thus remotely dispatched actions wouldn't work as expected and lock button will not have any effect on the enhancers.

See the blog post for more details why we introduced this.

zalmoxisus commented 7 years ago

__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ can be used instead of __REDUX_DEVTOOLS_EXTENSION__ enhancer, but it's confusing and we might not support using it as enhancer in future. See https://github.com/zalmoxisus/redux-devtools-extension/issues/310.

zalmoxisus commented 7 years ago

To clarify, you should use one of them for the specific case, not both. __REDUX_DEVTOOLS_EXTENSION__ is used only when it's the only enhancer, not to be included in the compose.

Arrow7000 commented 7 years ago

Ok thank you. I got started with the basic store setup and didn't look at the advanced setup when I started including enhancers.

Thanks for explaining things so clearly!

zalmoxisus commented 7 years ago

You're welcome. We could add a note in the README for the basic store and information about that exception in troubleshooting. If you change your pr with that, it would be much appreciated.

Arrow7000 commented 7 years ago

Ok will do

epozsh commented 6 years ago

Hello i tried the advnaced store example, but still the same when i use icognito window without redux devtools extension available, i get the

error Cannot read property 'apply' of undefined in Google Chrome

this is my code

let enhancer;
if (__DEV__) {
  const composeEnhancers =
    typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
      ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__()
      : compose;

  enhancer = composeEnhancers(
    applyMiddleware(thunk),
    applyMiddleware(sessionTimerMiddleware)
  );
} else {
  enhancer = compose(
    applyMiddleware(thunk),
    applyMiddleware(sessionTimerMiddleware)
  );
}

const store = createStore(rootReducer, initialState, enhancer);
hackhat commented 6 years ago

I wonder why redux is not checking for undefined? Is assuming that all args are a function, but sometimes we want to pass undefined.

hugoh59 commented 6 years ago

I'm also getting the same issue. Can't find a fix.

danielecr commented 6 years ago

@Shadowman4205 that solution does not work for me too, instead I tryed with

enhancer = applyMiddleware(settingsMiddleware, epicMiddleware, router);

and this works, also applyMiddleware() accept an array as parameter, so I think that applyMiddleware(...middleware) is meant as:

enhancer = compose( applyMiddleware([settingsMiddleware, epicMiddleware, router]) )

but I am still confused

Note:

enhancer = applyMiddleware(settingsMiddleware, epicMiddleware, router);

works for me

AndrewCraswell commented 6 years ago

@Shadowman4205 I was having the same issue until I changed it slightly to match the Advanced Setup guide:

  const composeEnhancers =
    typeof window === 'object' &&
      (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
      (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;

Here I'm passing an empty {} object to the __REDUX_DEVTOOLS_EXTENSION_COMPOSE__(). Only then it works, otherwise throws the same error you're receiving. This feels counterintuitive to me.

sht5 commented 5 years ago

see solution through package here(worked for me): https://stackoverflow.com/questions/49190781/redux-app-not-working-if-redux-devtools-extension-is-not-installed

qodesmith commented 5 years ago

I needed to go from this:

const composeEnhancers = !__PROD__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose

To this:

const composeEnhancers = !__PROD__ ? (window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose) : compose
KrishieldKyle commented 5 years ago

i fixed mine, now my app can now run with or without reduxDevtool installed

i just changed

window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()

to

window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__() || compose

mmunier44 commented 5 years ago

Bottom one worked for me thanks so much

ghost commented 5 years ago

@KrishieldKyle: thx!

kekexunxun commented 5 years ago

@Arrow7000 thx