Cleanup, Linting, and Login Form Styling


In this video we need to do three things:

  1. Cleanup of the Boilerplate leftovers
  2. Fixing all the linting errors
  3. Styling the Login screen with Bootstrap / Reactstrap

The first step is not interesting, but it is essential. There's a lot of left over stuff when using a Boilerplate that becomes less and less useful to you as your experience improves, and your knowledge grows.

You can see all the deleted files in this diff.

Likewise, you can check out git tag vid-12-post-cleanup if you'd like to continue on with this project from this particular point.

Linting

And also, the second step - "Fixing all the linting errors" - isn't really fun either.

Linting is the process of statically analysing your code to spot potential problems, and more prominently in my experience, enforcing a specific set of code style guidelines across the codebase. You know when you're working on a project with strict linting rules, trust me :)

Anyway, in our case we are using ESLint by the incredible Nicholas C. Zakas, author of the best JavaScript book I've ever read.

You can see the Linting settings in use here. I've highlighted the one change I have made to every React project I've worked on. You may disagree, but for me this works better than the alternative.

More infrequently you may find Linting picks up issues that may not arise in dev, but that can cause the build to fail when wanting to deploy to prod.

An example of this was in getting caught by no-class-assign.

In my case I had reassigned my class by wrapping it in a higher order component:


/**
 * WRONG
 *
 * LoginPage = withRouter(LoginPage);
 *
 * export default connect(
 *   mapStateToProps
 * )(LoginPage);
 */

// correct, but harder to read, imho
export default connect(
  mapStateToProps
)(
  withRouter(LoginPage)
);

Anyway, very useful all the same.

Styling

And that leaves us with the more interesting problem of making our Log In page look more like the Bootstrap 4 Example.

Fixing this is easy enough. We're going to be doing a little copy / pasting, but also incorporating the Reactstrap Button component, and re-covering CSS className inside React:

// /src/components/LoginForm.js

import React from 'react';
import {Field, reduxForm} from 'redux-form';
import {Button} from 'reactstrap';
import '../styles/login-form.scss'

const LoginForm = (props) => {

  return (
    <form onSubmit={props.handleSubmit} className="form-signin">

      <Field component="input"
             name="username"
             id="username"
             type="text"
             placeholder="Username or email address"
             required="required"
             className="form-control"
      />

      <Field component="input"
             name="password"
             id="password"
             type="password"
             placeholder="Password"
             required="required"
             className="form-control"
      />

      <Button type="submit"
              size="lg"
              block
              color="success"
      >
        Login
      </Button>
    </form>
  );

};

LoginForm.propTypes = {
  handleSubmit: React.PropTypes.func.isRequired,
  onSubmit: React.PropTypes.func.isRequired
};

export default reduxForm({
  form: 'login'
})(LoginForm);

We've added the className elements to the form and the two Field components.

These will be taken directly from the Bootstrap Example's CSS:

/* /src/styles/login-form.scss */

.form-signin {
  max-width: 330px;
  padding: 15px;
  margin: 0 auto;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
  margin-bottom: 10px;
}
.form-signin .checkbox {
  font-weight: normal;
}
.form-signin .form-control {
  position: relative;
  height: auto;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  padding: 10px;
  font-size: 16px;
}
.form-signin .form-control:focus {
  z-index: 2;
}
.form-signin input[type="email"] {
  margin-bottom: -1px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
  margin-bottom: 10px;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

It's debatable whether to add the CSS styles to the component, or to the component that uses the form. In my case I've chosen to add the style import on the LoginPage, as to begin with I had imported a style that affected the body element. A definite refactoring to make more sense here would be to move the CSS to the LoginForm component now, to pay off some technical debt.

For the purposes of this video write up, I have enacted my suggested refactoring. Note this does not match directly to the code on GitHub, or in the video.

Anyway, with these changes in place, we now have a nicely Bootstrap-styled Login Page.

Code For This Course

Get the code for this course.

Episodes