captbaritone / raven-for-redux

A Raven middleware for Redux
295 stars 25 forks source link

Using dispatch in componentWillMount #1

Closed MartinCerny-awin closed 7 years ago

MartinCerny-awin commented 7 years ago

In some components I am using dispatch function directly. If I do this in componentWillMount lifecycle methods I get uncaught error Cannot read property 'type' of undefined.

index.js:22 Uncaught TypeError: 
    at index.js:22
    at index.js:14
    at Object.dispatch (bindActionCreators.js:7)
    at CalendarView.componentWillMount (CalendarView.jsx:15)

My component using dispatch function:

componentWillMount() {
  this.props.dispatch({ type: 'start' });
}

const mapDispatchToProps = dispatch => bindActionCreators({
  dispatch,
}, dispatch);

I have changed dispatched action to action creator and it solved the problem, but I do not not understand why I can't use dispatch in componentWillMount() when using this library

captbaritone commented 7 years ago

Are you, perhaps, using any other middleware? If so, in which order are you applying them?

MartinCerny-awin commented 7 years ago

I am using reduxThunk and reduxPromise. I use these parameters to call createStore function:

export default (reduxState = undefined) => createStore(
  reducer,
  reduxState,
  compose(
    responsiveStoreEnhancer,
    applyMiddleware(
      reduxThunk,
      createRavenMiddleware(Raven),
      reduxPromise
    ),
    getDevTools()
  )
);
captbaritone commented 7 years ago

If you move Raven for Redux after reduxPromise, do you get the same error?

-- Jordan Eldredge (mobile)

On Feb 21, 2017, at 9:38 PM, Martin Cerny notifications@github.com wrote:

I am using reduxThunk and reduxPromise. I use these parameters to call createStoref function:

export default (reduxState = undefined) => createStore( reducer, reduxState, compose( responsiveStoreEnhancer, applyMiddleware( reduxThunk, createRavenMiddleware(Raven), reduxPromise ), getDevTools() ) );

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

MartinCerny-awin commented 7 years ago

Yes, I get the same error no matter where I move createRavenMiddleware() function. The error disappears only, when I remove middleware.

This is the most important part of my store builder.

Raven.config('https://a342c215de0d48e1a39ca013a744dd58@sentry.io/138953').install();
Raven.setTagsContext({
  environment: process.env.NODE_ENV
});

if (typeof window === 'object') {
  window.onunhandledrejection = (evt) => {
    Raven.captureException(evt, { level: 'warning' });
  };
}

export default (reduxState = undefined) => createStore(
  reducer,
  reduxState,
  compose(
    responsiveStoreEnhancer,
    applyMiddleware(
      createRavenMiddleware(Raven),
      reduxThunk,
      reduxPromise,
    ),
    getDevTools()
  )
);

The error is actually throw even after moving it to action creator, but at least the component is rendered and can be normally used.

captbaritone commented 7 years ago

Its possible that the code you supplied has been simplified for the sake of this report, but if your mapStateToProps is actually as you've specified, I think it might be causing your problems.

This example:

const mapDispatchToProps = dispatch => bindActionCreators({
  dispatch,
}, dispatch);

Is equivalent to:

const outerDispatch = dispatch;

const mapDispatchToProps = dispatch => ({
    dispatch: (..args) => dispatch(outerDispatch(..args))
});

Which means the actual dispatch function is being executed with the return of your outer dispatch function. I'm guessing this is undefined, but your example does not make it clear where that outer function comes from.

When raven-for-redux tries to access .type on what it thinks is an action, (but is actually undefined) it crashes.

captbaritone commented 7 years ago

I'm going to close this issue on the assumption that the problem is with your mapStaeToprops. If that ends up not being the problem let me know and we can reopen the issue.

MartinCerny-awin commented 7 years ago

@captbaritone You were right, I helped me to fix the issue. I have changed my mapDispatchToProps function to

const mapDispatchToProps = dispatch => ({
  ...bindActionCreators({ fetchUser }, dispatch),
  dispatch
});
captbaritone commented 7 years ago

@MartinCerny-awin Great! In fact, you could even use the object shorthand for mapDispatchToProps:

const mapDispatchToProps = { fetchUser };

You can read more here: https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options