React/Redux: how to hold login fail
<p>I'm very beginner in React/Redux and I was trying to do something in an already existing code, just to understand how it works. The part I want to edit is the connection part. As it's now, if the login and password are OK, you go to a new page, and if not, it does nothing.</p>

<p>The only simple thing I'm trying to do is to show the user their login informations are wrong, by adding a red border on the fields for example.</p>

<p>So here is the code I added, I'll try not to show you useless code and not to forget useful code, but let me know if you need more.</p>

<p>The first thing I did is adding a constant for the error in <strong>actionTypes.js</strong>:</p>

<pre><code>export const AUTH_REQUEST = 'AUTH_REQUEST';
export const AUTH_RECEIVE = 'AUTH_RECEIVE';
export const AUTH_ERROR = 'AUTH_ERROR';
</code></pre>

<p>Then in <strong>actions/auth.js</strong>, I added the <em>authError</em> function and called it after a fail response from the server:</p>

<pre><code>function authRequest() {
  return {
    type: actionTypes.AUTH_REQUEST
  };
}

function authReceive(authToken) {
  return {
    type: actionTypes.AUTH_RECEIVE,
    authToken
  };
}

function authError() {
  return {
    type: actionTypes.AUTH_ERROR
  };
}

export function fetchLogin(email, password) {
  return function (dispatch) {
    dispatch(authRequest());

    const urlApi = `//${AUTH_BACKEND_HOST}:${AUTH_BACKEND_PORT}/${AUTH_BACKEND_URL.login}`
    fetch(urlApi, {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'content-type': 'application/json'
      },
      body: JSON.stringify({
        email,
        password
      })
    })
    .then((response) =&gt; {
      if(response.ok) {
        // SUCCESS
        response.json().then(function(json) {
          dispatch(authReceive(json.key));
          dispatch(push('/'));
        });
      } else {
        // FAIL
        response.json().then(function(json) {
          dispatch(authError());
        });
      }
    })
    .catch(function(ex) {
      console.log(ex);
    });
  };
}
</code></pre>

<p>Now, in <strong>reducers/auth.js</strong>:</p>

<pre><code>const initialState = {
  authToken: '',
  isFetching: false,
  error: false,
  errorMessage: ''
}

export default function (state=initialState, action) {
  switch (action.type) {
    case actionType.AUTH_REQUEST:
      return {
        ...state,
        isFetching: true
      };
    case actionType.AUTH_RECEIVE:
      return authLogin(state, action);
    case actionType.AUTH_ERROR:
      return {
        ...state,
        error: true,
        errorMessage: 'Incorrect login or password!'
      };
  }
  return state;
}

function authLogin(state, action) {
  const { authToken } = action;
  return {
    ...state,
    isFetching: false,
    authToken
  };
}
</code></pre>

<p>Until now, it seems to work when I inspect it in Firefox. The state contains  the <em>error</em> and <em>errorMessage</em> values.</p>

<p>So here is my <strong>components/Login/presenter.jsx</strong> which I thought was going to display the right HTML depending on the state:</p>

<pre><code>import React from 'react';

const Login = React.createClass({

  handleSubmit(event) {
    event.preventDefault()

    const email = this.refs.email.value
    const password = this.refs.password.value

    this.props.onAuth(email, password);
  },

  render() {
    const { errorMessage } = this.props

      return (
        &lt;form onSubmit={this.handleSubmit}&gt;
          &lt;label&gt;Email &lt;input ref="email" placeholder="email" required /&gt;&lt;/label&gt;
          &lt;label&gt;Password &lt;input ref="password" placeholder="password" type="password" required /&gt;&lt;/label&gt;&lt;br /&gt;
          &lt;p&gt;{errorMessage}&lt;/p&gt;
          &lt;button type="submit"&gt;Login&lt;/button&gt;
        &lt;/form&gt;
      )    
  }    
});

export default Login;
</code></pre>

<p>And here is <strong>components/Login/index.js</strong> which I think imports the presenter and do... things...:</p>

<pre><code>import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import Login from './presenter';

function mapDispatchToProps(dispatch) {
  return {
    onAuth: bindActionCreators(actions.fetchLogin, dispatch)
  };
}

export default connect(null, mapDispatchToProps) (Login);
</code></pre>

<hr>

<p>Edit : it seems that one of the problems is that I'm not mapping the state to props. I tried Mael Razavet and azium's answers, adding mapStateToProps in Login/index.js:</p>

<pre><code>import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import Login from './presenter';

function mapDispatchToProps(dispatch) {
  return {
    onAuth: bindActionCreators(actions.fetchLogin, dispatch)
  };
}

function mapStateToProps (state) {
  return {
    errorMessage: state.errorMessage
  };
}

export default connect(mapStateToProps, mapDispatchToProps) (Login);
</code></pre>

<p>But it seems that errorMessage is still undefined.</p>

<p>Thank you.</p>