React/Redux dispatch not triggering reducer

Viewed 12056

Struggling to dispatch an action from my React component. This is my first Redux app. Everything seems to be working fine, but if it was I would not be posting this question. I am using Redux devTool to debug my app. If I use the dispatcher from the devTools my reducer is triggered with no problem. However I am unable to dispatch the same action from my React components. I added a breakpoint in my action to see if it was being triggered. I definately is and it is also returning a valid action (type & payload). Here is my code:

store.js

import {createStore, applyMiddleware, compose} from 'redux'
import {createLogger} from 'redux-logger'
import thunk from 'redux-thunk'
import promise from 'redux-promise-middleware'
import reducers from './reducers/index'

const logger = createLogger()

const store = createStore(
    reducers,
    window.__REDUX_DEVTOOLS_EXTENSION__ && 
    window.__REDUX_DEVTOOLS_EXTENSION__(),
    compose(
      applyMiddleware(thunk, promise, logger)
    )
)

export default store

reducers (index.js)

import {combineReducers} from 'redux'
import userReducer from './userReducer'

const allReducers = combineReducers({
    user: userReducer
})

export default allReducers

client.js

import React from 'react'
import ReactDOM from 'react-dom'
import {Provider} from 'react-redux'
import store from './store'
import Router from './modules/router'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import CustomTheme from './modules/theme'
import injectTapEventPlugin from 'react-tap-event-plugin'
require('../scss/style.scss')

// Needed for onTouchTap
// http://stackoverflow.com/a/34015469/988941
injectTapEventPlugin();

ReactDOM.render(
  <Provider store={store}>
    <MuiThemeProvider muiTheme={CustomTheme}>
      <Router/>
    </MuiThemeProvider>
  </Provider>,
  document.getElementById('app')
);

userReducer.js

export default function (state = {loggedIn: false}, action) {
    console.log("THIS IS THE REDUCER: STATE: ", state, " - ACTION: ", action)
    switch (action.type) {
        case 'LOGIN':
            return {...state, loggedIn: action.payload}
    }
    return state;
}

userActions.js

export const login = () => {
  console.log("TEST")
    return {
        type: 'LOGIN',
        payload: true
    }
}

login.js

import React from 'react'
import ReactDOM from 'react-dom'
import LoginForm from '../containers/loginform'

class Login extends React.Component {
  render() {
    return (
      <LoginForm/>
    )
  }
}

export default Login

loginform.js

import React, {PropTypes} from 'react'
import ReactDOM from 'react-dom'
import {Redirect} from 'react-router-dom'
import {connect} from 'react-redux'
import {login} from '../actions/userActions'
import RaisedButton from 'material-ui/RaisedButton'
import TextField from 'material-ui/TextField'

class LoginForm extends React.Component {
  constructor(props) {
    super(props)
  }
  loginReq(e){
     e.preventDefault()
     this.props.login()
  }
  render() {
    return (
      <div>
        <form className='login-form-container' onSubmit=    {this.loginReq.bind(this)}>
          <div className='login-form-row'>
            <TextField
              ref='email'
              hintText='Email'
              floatingLabelText='Email'
              className='login-form-field'/>
          </div>
          <div className='login-form-row'>
            <TextField
              ref='password'
              hintText='Password'
              floatingLabelText='Password'
              type='password'
              className='login-form-field'/>
          </div>
          <div className='login-form-row'>
            <RaisedButton
              type= 'submit'
              label='Login'
              className='login-form-button'/>
          </div>
        </form>
      </div>
    )
  }
}

const mapStateToProps = (state) => {
    return {
        loggedIn: state.user.loggedIn
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
      login: () => dispatch(login())
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(LoginForm)

Please could you give me some guidance to how else i can debug to find out why this dispatch is not working. I have tried adding the action object straight into that dispatch function. still no luck. I get no errors in the console nothing. My console.logs are only printed when the view renders and when i click on the login submit button.

Console Screenshot

3 Answers
Related