Zac Fukuda
009

React Tutorial for Beginners: Email Registration

This is a tutorial on React.js designed for beginners. You are going to make a simple email registration form with real-time validation function using React.js. For the sample codes, please check out: Github

Prerequisites

To run React.js, you must have npm installed on your computer. If you are not familiar with npm, first you need to install Node.js and then follow some other tutorials on Node.js and npm.

Overview

There are simply two ways to use React: one with npm, the other without npm. As for now, React official page recommends using React with a CommonJS such as browserify, so I chose using the former.

File Structure

Files are structured as follows:
/
    - index.html
    - css
        - style.css
    - js
        - app.js
        - bundle.js
        - bundle.min.js
    - node_modules
    - package.json

Note that bundle.js and bundle.min.js are generated by browserify based on app.js. I'll exlain this later.

React Structure

When we create React app, it it very important to structure DOM and its hierarchy carefully. In this registration app, the react components are structured like this:

- Registration Form
    - HTML Form
        - Name Input Field
        - Email Input Field
        - Submit Button
    - Feedback Box

Codes

Fitst, you need to create packages.json with a proper declaration. If you hace one packages uninstalled, the app won't work. Here it looks like:

packages.json

{
  "name": "whatever",
  "version": "1.0.0",
  "description": "",
  "main": "js/app.js",
  "dependencies": {
    "react": "^0.12.0"
  },
  "devDependencies": {
    "browserify": "^6.2.0",
    "envify": "^3.0.0",
    "jest-cli": "^0.4.3",
    "reactify": "^0.15.2",
    "uglify-js": "~2.4.15",
    "watchify": "^2.1.1"
  },
  "scripts": {
    "start": "watchify -o js/bundle.js -v -d js/app.js",
    "build": "browserify . -t [envify --NODE_ENV production] | uglifyjs -cm > js/bundle.min.js",
    "test": "jest"
  },
  "keywords": [
    "React.js"
  ],
  "author": "Your name",
  "browserify": {
    "transform": [
      "reactify",
      "envify"
    ]
  },
  "jest": {
    "rootDir": "./js"
  },
  "license": "ISC"
}

After creating packages.json, you need to install all packages that are necessary by running:

npm install

Next, let's create a index.html file, it looks like this:

<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>React Toturial for Beginners - Email Registration</title>
  <link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
  <div id="content">
    <p style="font-size:36px;color:#61dafb;margin:0;line-height:1.1em;">Email Registration using React.js</p>
    <p style="color:#ddd;">Please fill the form below.</p>
    <div id="register"></div>
  </div>
   <script src="js/bundle.js"></script>
   <!-- <script src="js/bundle.min.js"></script> -->
</body>
</html>

I don't provide css here, so please refer to my github repo.

The all codes I'll provide below go into js/app.js.
When you use React with CommonJS, first you need to require React module.

var React = require('react');

There is no simple and yet best regex for email validation, however, I use the regex below this time. So let's define it before we create react components—for the complete regex please check out Mail::RFC822::Address.

var emailRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$\/;

Now it's time to create React components that you're waiting for. The first class We make is NameInput.

var NameInput = React.createClass({
  getInitialState: function() {
    return ({className: '', value: ''});
  },
  onChange: function (e) {
    var value = e.target.value;
    var className = value ? 'ok' : 'err';

    this.setState({className: className, value: value});
  },
  render: function () {
    return (
      <input type="text" name="name" onChange={this.onChange}
        className={this.state.className} value={this.state.value}
        placeholder="Name" />
    );
  }
});

Next, create EmailInput. It looks pretty same as NameInput.

var EmailInput = React.createClass({
  getInitialState: function () {
    return ({className: '', value: ''});
  },
  onChange: function (e) {
    var email = e.target.value;
    var className = emailRegex.test(email) ? 'ok': 'err';

    this.setState({className: className, value: email});
  },
  render: function () {
    return (
      <input type="email" name="email" onChange={this.onChange}
        className={this.state.className} value={this.state.value}
        placeholder="Email Address" />
    );
  }
});

After creating the input fields, let's create a feedback box , named Feedback, which appears after submit providing the message whether your input values are correct.

var Feedback = React.createClass({
  render: function () {
    var className = 'feedback ' + this.props.status;
    return (
      <p className={className}>{this.props.feedback}</p>
    );
  }
});

We have already create react child elements, and what you have to do next is to create a form element which wraps all children. I name it simply RegistrationForm.

var RegistrationForm = React.createClass({
  getInitialState: function () {
    return ({
      status: '',
      feedback: ''
    });
  },
  onSubmit: function (e) {
    e.stopPropagation();
    e.preventDefault();

    var name = this.refs.name.state.className,
        email = this.refs.email.state.className;

    var feedback = [], status = '', ok = 'ok';

    if ( name !== ok || email !== ok) {
      feedback = 'ERROR: Please check the form.';
      status = 'err';
      this.setState({status: status, feedback: feedback})
      return 0
    }

    feedback = 'Your email has been registered.';
    this.refs.name.setState({className: '', value: ''});
    this.refs.email.setState({className: '', value: ''});
    this.setState({status: ok, feedback: feedback});
    
  },
  render: function () {
    var status = this.state.status,
        feedback = this.state.feedback;

    return (
      <div>
        <form onSubmit={this.onSubmit} noValidate>
          <NameInput ref="name" />
          <EmailInput ref="email" />
          <input type="submit" value="Submit" />
        </form>
        <Feedback status={status} feedback={feedback} />
      </div>
    );
  }
});

At last, it is time to render RegistrationForm. Add the code below at the end of app.js.

React.render(
  <RegistrationForm />,
  document.getElementById('register')
);

Running

After finishing app.js, we need to compile that file into bundle.js. To compile please run the command below from your root project directory. Note that the programs to be excuted are defined inside of packages.json.

npm start

This command keeps watching file changes, which means that everytime you make changes it will generate a bundle.js. To quit watching, press Ctrl+c. In order to generate a minified version of bundled file, bundle.min.js, just run:

npm run build

Now your React app is ready. To run the app, just open the index.html file in a browser.

Next Step

If you haven't done React.js official tutorial yet, I encourage you to do so at Tutorial | React. If you have, create something for your own.