React

The 2017 React Development Starter Guide


DemoCode

React is one of the top JavaScript front-end frameworks in 2017 and is likely to gain more traction in the future. If you would like to start out and make your first steps with React you’ll quickly realize that React is easy to learn (especially if you’re already familiar with other component-oriented front-end frameworks like Angular or Vue.js). However one of the biggest obstacles you’ll be confronted with as a React beginner is the tooling and ecosystem.

Choosing from the various tooling options and packages is an overwhelming task if you’re a React beginner. In fact, trying to set up the right starter boilerplate app for React can hinder you to get going with this framework fast.

However, you can avoid this pain by choosing a premade boilerplate for your first React app. In the following tutorial we’ll use create-react-app to bootstrap our application. It’s an opinionated zero-configuration starter kit for React introduced by Facebook in 2016.

Install The Yarn Package Manager

Before we’re starting out with React, let’s first install the Yarn package manager. The Yarn packages manager is build by the community to deliver an improved package management in comparison to NPM.

The download and installation instructions are available on the project’s website: https://yarnpkg.com/en/docs/install.

Install create-react-app

Now we’re ready to install create-react-app which will be used to bootstrap our React application by using Yarn:

$ yarn global add create-react-app

This command downloads the latest version of create-react-app and installs it globally on your system. Having completed the installation successfully we’re able to use create-react-app to initiate a new React project:

$ create-react-app react-todo

This creates a new initial React project in the folder react-todo. Dependencies are installed automatically.

Next, change into the newly created folder and execute the following command to start up the development web server and open the default application in the browser:

$ yarn start

The application is hosted on http://localhost:3000:

The URL is opened in the browser automatically and you’ll see the following output:

Exploring The Project Structure

Next, let’s take a look at the project structure. If you take a look into folder react-todo you’ll find the following content:


You’ll find a clean project setup inside that folder, no additional configuration files for Webpack, Babel, web server or the build process are needed.

  • node_modules: The node_modules folder contains all dependencies which are needed by the project. These packages have been downloaded automatically.
  • public: The public folder is containing the static assets of your project. By default you’ll find the index.html file and the favicon of your project.
  • src: The src folder is the place where the React application lives. The file index.js is the starting point of the React application. If you take a look into that file, you’ll find the code which is needed to insert the output of the React application into the DOM.

What We’re Going To Build

To get started with a new framework, it’s always good to implement something and learn the basics along the way. So here you can see what we’re going to build in this tutorial:

It’s a simple React todo manager application. It consists of one application screen which is split up into two areas:

  • A form to add new todos (by providing values for the todo title, responsible, description and priority.
  • A list of all todos. For every list item a Delete button is available, so that the user can use this button to delete todo items.

Let’s see which steps are needed to implement this application.

Defining The Data Model And Using Local

Let’s start by adding the data model to our application. Add the following code to file App.js right after the import statements:

var todos = [
  {
    todoTitle: 'My first todo',
    todoResponsible: 'Sebastian',
    todoDescription: 'Todo description',
    todoPriority: 'low'
  },
  {
    todoTitle: 'My second todo',
    todoResponsible: 'Sebastian',
    todoDescription: 'Todo description',
    todoPriority: 'medium'
  },
  {
    todoTitle: 'My third todo',
    todoResponsible: 'Sebastian',
    todoDescription: 'Todo description',
    todoPriority: 'high'
  }
]

The todos array consists of three todo objects, each consisting of the properties todoTitle, todoResponsible, todoDescription and todoPriority.

Next, we’re adding the todos array to the state of app component. This is done by introducing a class constructor where we can set the initial component state like you can see in the following:

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      todos
    };

  }
 [...]
 }

In React every component has an internal state. The state contains the data which is used by the component so the state contains the properties of a component. However the state is private and is fully controlled by the component.

Using JSX

Now that we’ve initially set the internal state of App component we’re removing the default JSX code from the return statement of the render method and insert our own JSX code to render out the list view of todos:

  render() {
    return (
      <div className="container">
        <h4>
          Todo Count: <span className="badge">{this.state.todos.length}</span>
        </h4>
        <ul className="list-group">
          { this.state.todos.map((todo, index) =>
              <li className="list-group-item" key={index}>
                <h4 className="list-group-item-heading">{todo.todoTitle} <small><span className="label label-info">{todo.todoPriority}</span></small></h4>
                <p><span className="glyphicon glyphicon-user" aria-hidden="true"></span> {todo.todoResponsible}</p>
                <p>{todo.todoDescription}</p>
                <button className="btn btn-danger btn-sm" onClick={this.handleRemoveTodo.bind(this, index)}><span className="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete</button>
              </li>
          )}
        </ul>
      </div>
    );
  }

As you can see JSX is a direct syntax extension to JavaScript. By using JSX you can use HTML elements in your JavaScript code directly without the need of embedding your template code in a string. Furthermore you can embed JavaScript expressions in JSX by wrapping it in curly braces, e.g. {this.state.todos.length}. When rendering the output this expression is replaced with the value of the length property from the todos array in the internal component state.

The list of todos is generated by using an unordered list element (<ul></ul>). For each element a <li></li> element is generated. To iterate over the elements the map method is used. The array function which is passed into the map method call returns the JSX code which is needed to generate the HTML output for a todo item element.

Event Handling

Next, let’s focus on event handling. The JSX code from the listing above contains the following code:

onClick={this.handleRemoveTodo.bind(this, index)}

Here we’re attaching the handleRemoveTodo component method as an event handler to the click event of the Delete button. In addition we’re binding the event handler method to this and index. Now we’re able to access the internal component state (this.state) and the array index of the current todo array item in the handler method:

handleRemoveTodo(index) {
    this.setState({
      todos: this.state.todos.filter(function (e, i) {
        return i !== index;
      })
    });
}

To delete the current todo element from this.state.todos we’re using the this.setState method here. In React the setState method is used to modify the internal component state. State properties can not be modified.

Implementing TodoInput Component

Next, let’s add another component to our application in file App.js. The TodoInput component should encapsulate the todo input form. Let’s start by implementing the component class, add the constructor and set the initial component state:

class TodoInput extends Component {
  constructor(props) {
    super(props);

    this.state = {
      todoTitle: '',
      todoResponsible: '',
      todoDescription: '',
      todoPriority: 'Lowest'
    }
  }
}

The initial state of the component consists of four properties: todoTitle, todoResponsible, todoDescription and todoPriority. We’ll use the TodoInput component later in App component.

Adding JSX Code

Let’s add the JSX code to TodoInput component which is needed to render the HTML form. Again, we need to add a render method to the component class and embed the corresponding JSX code in the return statement:

render() {
    return (
      <div>
        <h4>Add New Todo</h4>
          <form className="form-horizontal" onSubmit={this.handleSubmit}>
            <div className="form-group">
              <label htmlFor="inputTodoTitle" className="col-sm-2 control-label">Todo</label>
              <div className="col-sm-10">
                <input  name="todoTitle"
                        type="text"
                        className="form-control"
                        id="inputTodoTitle"
                        value={this.state.todoTitle}
                        onChange={this.handleInputChange}
                        placeholder="Title"></input>
              </div>
            </div>
            <div className="form-group">
              <label htmlFor="inputTodoResponsible" className="col-sm-2 control-label">Responsible</label>
              <div className="col-sm-10">
                <input  name="todoResponsible"
                        type="text"
                        className="form-control"
                        id="inputTodoResponsible"
                        value={this.state.todoResponsible}
                        onChange={this.handleInputChange}
                        placeholder="Responsible"></input>
              </div>
            </div>
            <div className="form-group">
              <label htmlFor="inputTodoDesc" className="col-sm-2 control-label">Description</label>
              <div className="col-sm-10">
                <textarea   name="todoDescription"
                            className="form-control"
                            rows="3"
                            id="inputTodoDesc"
                            value={this.state.todoDescription}
                            onChange={this.handleInputChange}></textarea>
              </div>
            </div>
            <div className="form-group">
              <label htmlFor="inputTodoPriority" className="col-sm-2 control-label">Priority</label>
              <div className="col-sm-10">
                <select   name="todoPriority"
                          className="form-control"
                          id="inputTodoPriority"
                          value={this.state.todoPriority}
                          onChange={this.handleInputChange}>
                  <option>Lowest</option>
                  <option>Low</option>
                  <option>Medium</option>
                  <option>High</option>
                  <option>Highest</option>
                </select>
              </div>
            </div>
            <div className="form-group">
              <div className="col-sm-offset-2 col-sm-10">
                <button type="submit" className="btn btn-success">Add Todo</button>
              </div>
            </div>
          </form>
      </div>
    );
  }

As you can see the form consists of two text input elements, one textarea element and one select element. In HTML all input elements maintain their own state which is updated based on user input. To synchronize the values with properties from the internal component state we’re using the value attribute and assign the corresponding state property by using the expression syntax with curly braces, e.g.

value={this.state.todoPriority}

The value of the form input elements is therewith set to the value of the corresponding state properties. However this synchronization is only working in one direction. Changing the input value by the user is no longer possible.

To solve that problem and establish a two-way data binding we need to handle the change event of each input element.

Handling The OnChange Event To Update Component State

The event handler method handleInputChange is connected to the change event type of each form input element by adding the following attribute to the HTML element:

onChange={this.handleInputChange}

Next, we need to bind the method to this by adding the following line of code to the class constructor:

this.handleInputChange = this.handleInputChange.bind(this);

This is needed because we would like to call this.state inside of the method to set the new state based on the user input:

  handleInputChange(event) {
    const target = event.target;
    const value = target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }

The handleInputChange method is implemented in a generic way, so that this event handler can be used for all four form input elements in the same way.

Handling The Form Submit Event

The submit event type of the form is connected to the handleSubmit method:

onSubmit={this.handleSubmit}

Again we need to make the this context of the class accessible inside the handler method. Therefore add the following code to the constructor:

this.handleSubmit = this.handleSubmit.bind(this);

The implementation of the handleSubmit method is straight forward. First event.preventDefault() is called to prevent the default submit behavior of an HTML form:

  handleSubmit(event) {
    event.preventDefault();
    this.props.onAddTodo(this.state);
    this.setState({
      todoTitle: '',
      todoResponsible: '',
      todoDescription: '',
      todoPriority: 'Lowest'
    });
  }

Calling this.props.onAddTodo(this.state) emits the onAddTodo event, so that the parent component will be notified that a new todo item is available. In the next section we’ll make use of the onAddTodo event in App component and make sure that the new todo is added to the todos array.

Finally we make sure that the form values are set to the initial state by calling this.setState.

Including TodoInput Component in App Component

Include TodoInput Component in JSX Code of App Component

Having completed the implementation of TodoInput component, the last step is to include this component in App component.

To include TodoInput component add the following JSX code:

        <TodoInput
          onAddTodo={this.handleAddTodo}
          />
        <hr />

Next, bind the this context of the component class by adding

this.handleAddTodo = this.handleAddTodo.bind(this);

to the constructor. Finally implement handleAddTodo as you can see in the following:

handleAddTodo(todo) {
  this.setState({todos: [...this.state.todos, todo]});
}

The new todo item is passed into that method as a parameter. Then we’re calling this.setState to assign a new extended array to the todos state property.

Conclusion

Getting started with React development is not as hard as you might have thought, isn’t it? By using the right tools (e.g. create-react-app) you can set up your first React project including the dev environment quickly. You do not need to spend up hours of configuration, instead you can start developing your first React application right away.

I hope that this tutorial helps you to kickstart your next front-end development project with React quickly and easily.

ONLINE COURSE: The Complete React Web App Developer Course

Check out the great Complete React Web App Developer Course by Andrew Mead with thousands of students already enrolled:

The Complete React Web App Developer Course

  • You’ll learn how to develop, test, and deploy React web applications
  • Learn how to setup and automate testing using Karma and Mocha
  • Understand the rich ecosystem of 3rd-party libraries like Redux and Webpack
  • Learn to style applications using the Foundation framework

Go To Course


Using and writing about best practices and latest technologies in web design & development is my passion.

    View Comments

    *