Redux Router - "Dispatch is not defined"
You need your action to return a function to utilize the thunk middleware, then redux will inject the dispatcher into it. You mixed your dispatcher invocation with the implementation detail. The following snippet fixes both defects.
guestLoginRequest: function(){
return function (dispatch) {
var ref = new Firebase("https://penguinradio.firebaseio.com");
ref.authAnonymously(function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
dispatch(actions.setLoginStatus(true, authData))
console.log("dispatched");
}
});
}
}
In addition, you need to dispatch your action correctly on the Login
class.
dispatch(this.props.actions.guestLoginRequest())
Your action invocation is always done by invoking dispatch
. The flow should be something like this:
React component --> dispatch ---> API call (thunk middleware) --> dispatch ---> reducer
Mike
Updated on July 09, 2022Comments
-
Mike almost 2 years
I've got a simple component that calls an action when a user loads a page, and inside that action, I'm trying to dispatch another action to set the
loggedIn
state of the store to true or false:import React, { Component } from 'react' import { Link, browserHistory } from 'react-router' import $ from 'jquery' class Login extends Component { constructor(props) { super(props) } componentDidMount() { this.props.actions.guestLoginRequest() } render() { return ( <div> <div classNameName="container"> <div className="row"> We are signing you in as a guest </div> </div> </div> ) } } export default Login
I can get the login information when the
guestLoginRequest
action is called, but when I try to dispatch another action inside of it, nothing happens:guestLoginRequest: function(){ var ref = new Firebase("https://penguinradio.firebaseio.com"); ref.authAnonymously(function(error, authData) { if (error) { console.log("Login Failed!", error); } else { console.log("Authenticated successfully with payload:", authData); return dispatch => { dispatch(actions.setLoginStatus(true, authData)) console.log("dispatched"); }; } }); }
I get an error of
Uncaught ReferenceError: dispatch is not defined
when I remove thereturn dispatch => { }
statement. In my store I am using redux-thunk, so I can dispatch inside of actions:// Store.js import { applyMiddleware, compose, createStore } from 'redux' import rootReducer from './reducers' import logger from 'redux-logger' import thunk from 'redux-thunk' let finalCreateStore = compose( applyMiddleware(thunk, logger()) )(createStore) export default function configureStore(initialState = { loggedIn: false }) { return finalCreateStore(rootReducer, initialState) }
I am mapping the dispatch to props in my app.js as well:
function mapStateToProps(state) { return state } function mapDispatchToProps(dispatch) { return { actions: bindActionCreators(actions, dispatch) } } export default connect(mapStateToProps, mapDispatchToProps)(App)
Just in case it could be helpful, here is my client.js and reducer files:
// client.js import React from 'react' import { render } from 'react-dom' import App from '../components/App' import configureStore from '../redux/store' import { Provider } from 'react-redux' let initialState = { loggedIn: false } let store = configureStore(initialState) render( <Provider store={store}> <App /> </Provider>, document.getElementById('app') ) // Reducer.js import { combineReducers } from 'redux' let LoginStatusReducer = function reducer(loggedIn = false, action) { switch (action.type) { case 'UPDATE_LOGIN_STATUS': return loggedIn = action.boolean default: return loggedIn } } export default LoginStatusReducer const rootReducer = combineReducers({ loggedIn: LoginStatusReducer }) export default rootReducer
Any ideas why my dispatch function isn't working? I'm confused since I did set up redux-thunk with my store, and I'm using code similar to the docs when I call
return dispatch => { }
. Is there something I'm missing? Thank you in advance for any advice! -
Mike about 8 yearsI've replaced my action with the one you posted above, and updated the dispatch call on Login.js, but I am getting a " dispatch is not defined" on the Login.js file. Do I have to pass in that function to the Login component? Also should I be calling return function (dispatch) instead of return function (dispatcher)?
-
Matt Lo about 8 yearsYou'll need to expose a wrapper around the store's
dispatch
(via mapDispatchToProps) or get the store's dispatcher directly (store.dispatch). Here's an implementation example: Component - github.com/mattlo/consultant-app/blob/master/src/client/… Store export - github.com/mattlo/consultant-app/blob/master/src/client/data/… -
Mike about 8 yearsI've updated my answer to include my
mapDispatchToProps
function, does it look right?