React – 9bit Studios https://9bitstudios.com Web Design, Themes, & Applications Tue, 04 Jul 2017 13:09:04 +0000 en-US hourly 1 https://wordpress.org/?v=4.8 To Do: Create Your First React Application – Part II https://9bitstudios.com/2016/11/to-do-create-your-first-react-application-part-ii/ https://9bitstudios.com/2016/11/to-do-create-your-first-react-application-part-ii/#respond Tue, 15 Nov 2016 01:07:17 +0000 https://9bitstudios.com/?p=1178 Previously, we looked at getting set up creating a React “to do” application by installing our Node.js driven build tools and laying out some introductory components of code. In what follows we will continue on where we left off.

Adding “To Do” Items & Handling User Input

So far we have just looked how to display our components. Rendering data out to our page is all well and good, but to make our application truly dynamic we are going to need to implement a way to add and remove items to and from our list as well as edit them should we need to make any changes to any of the properties. So let’s update the code in TodoList.js to the following…

import {react} from 'react';
import {Todo} from './Todo';

export class TodoList extends React.Component {
    
    constructor(){
        super(...arguments);
        this.state = {
            todos: this.props.data,
            addTodoTitle: '',
            addTodoSummary: ''
        }
    }
    
    addTodoTitleChange(e){
        this.setState({
            addTodoTitle: e.target.value
        });        
    }
    
    addTodoSummaryChange(e){
        this.setState({
            addTodoSummary: e.target.value
        });           
    }    
        
    addTodo(){
        this.state.todos.push({
            id: this.state.todos[this.state.todos.length - 1].id + 1,
            title: this.state.addTodoTitle,
            summary: this.state.addTodoSummary,
            done: false
        });

        this.setState({
            todos: this.state.todos,
            addTodoTitle: '',
            addTodoSummary: ''
        });        
    }
    
    render() {
        
        var items = this.props.data.map((item, index) => {
            return (
                <Todo key={item.id} title={item.title} summary={item.summary} completed={item.done} />
            );        
        });
        
        return(
            <div>
                <ul>{items}</ul>
                
                <h3>Add New Item:</h3>
                <label>Title</label> <input type="text" value={this.state.addTodoTitle} onChange={() => this.addTodoTitleChange()} />
                <label>Description</label> <textarea value={this.state.addTodoSummary} onChange={() => this.addTodoSummaryChange()}></textarea>
                <button onClick={() => this.addTodo()}>Add New Item</button>
            </div>
        )
    }
};

So let’s discuss what is going on here. We have added 2 new values to our initial state object and we have created a form that will allow us to add a new “to do” item to our list. When we enter text into these fields the functions to update the state will run and we will update these values with setState by getting the current value of the form element we are editing off of the event that is passed into the function (e.target.value). Once we have filled out the form with the title and summary of the new item that we want, we can click the “Add New Item” button which, as we can see from our “onClick” handler, will run the “addTodo” function. If we look at this function we can see the code that we will need to add a new item to our list. Recall that we have to give each individual item an id and no two items can have the same id. So to generate a new id we will look at what the id value of the last item in our array is and just add 1 to that. That is an easy way to ensure that the new items that we add are always unique. We get the title and the summary from this.state which we have been setting in our text input handler functions. Lastly, we just set the initial value of the “done” flag to false since adding a new to do to the list is presumably not done yet. All of this data is passed into the common JavaScript Array object’s “push” method. We then update the state of our “todos” and then clear out the input text box and textarea in our form to get them ready to receive another value.

So build your code with $ webpack (or whatever task runner you are using) and try it out. You can see how we can now add new items to our list! Pretty slick!

Improving Our Code

Our example above works but you may have noticed something problematic with our implementation. We have individual handler functions for the two text elements in our “Add New Item” form. We also have separate properties that we use for setState. This is fine for this simple example, but what if we had a component with many different properties and values with many different fields that needed to be filled out? If we were to take the same approach as our example above, we would have to create an individual function for each and every property. Not too efficient!

So what can we do to mitigate this potential scenario of our React application scaling to incorporate more complex objects? We should abstract this functionality into one handler function and also pass in the property that we need to update depending on the form element we are currently changing. So let’s change the code in our TodoList.js file to the following…

import {react} from 'react';
import {Todo} from './Todo';

export class TodoList extends React.Component {
    
    constructor(){
        super(...arguments);
        this.state = {
            todos: this.props.data,
            newItem: {
                title: '',
                summary: ''
            }
        }
    }
    
    handleChange(key, event){
        var change = {
            title: this.state.newItem.title,
            summary: this.state.newItem.summary
        };
        change[key] = event.target.value;
        
        this.setState({           
            newItem: change        
        });               
    }
    
    addTodo(){
        this.state.todos.push({
            id: this.state.todos[this.state.todos.length - 1].id + 1,
            title: this.state.newItem.title,
            summary: this.state.newItem.summary,
            done: false
        });

        this.setState({
            todos: this.state.todos,
            newItem: {
                title: '',
                summary: ''
            }
        });        
    }
    
    render() {
        
        var items = this.props.data.map((item, index) => {
            return (
                <Todo 
                    key={item.id} 
                    title={item.title} 
                    summary={item.summary} 
                    completed={item.done} />);        
        });
        
        return(
            <div>
                <ul>{items}</ul>
                
                <h3>Add New Item:</h3>
                <label>Title</label> <input type="text" value={this.state.newItem.title} onChange={(e) => this.handleChange('title', e)} />
                <label>Description</label> <textarea value={this.state.newItem.summary} onChange={(e) => this.handleChange('summary', e)}></textarea>
                <button onClick={() => this.addTodo()}>Add New Item</button>
            </div>
        )
    }
};

So what have we done here? For starters, instead of creating individual properties for each value our component will hold we will hold we put these into one object called “newItem.” That way if our component were ever to change we could just add to this single object rather than creating separate properties directly on the state object. Note too that we have also created a single handler function called “handleChange” to handle the change to any of our form elements. We have updated the format of our “onChange” events. Now we are passing a second parameter in to the handler function. This serves to tell React which field is currently being updated. In the handler function, we then construct the object to get the current state of all the values in our component and then we use the key that we passed in to change the relevant property.

Now if we build and run again, we can see that we have the same functionality, but we have refactored our code in such a way that we can scale our components to add new properties in the future. This is much better for us in the long run.

Validation

Validation of data is an important aspect of any application. In React we are mostly dealing with client-side validation. It is common knowledge within software development that you can never trust client-side validation alone because anyone on the client side can use developer tools and change the code that runs on the client to circumvent any validation that happens on the client. So any data that we send up to a server from a React application should also always always always be validated on the server as well. But chances are most of the users of your app will not be malicious individuals cracking open their developer tools and trying to hack their way into your system, so we will want to make sure that the good/normal users of your application have a good user experience. Part of this involves making sure that any input(s) that the users of your app make is checked and validated on the client side so that the app does not have to wait to make an entire round trip up to the server before informing the user that they have done something they were not supposed to… forgot to fill out a required form field, entered incorrect data in a form field such as an improperly formatted e-mail address or phone number, or any number of other common errors that can happen when handling user input. Again, this does not substitute for always validating your data on the server side as well, but it is a useful first line of defense and an important element to an enjoyable experience for your users. It also can reduce the traffic load on your server(s). If you can prevent sending a request until all the data that you’re getting from the client is good and valid, you should only need to make the particular request that you need to make to the server one time!

So all that being said, client-side validation definitely has its uses and it is worth making the effort to put it in for the aforementioned reasons. Fortunately, React has built in structure to validate props that we pass into our components and make sure that required data is present and that the data is of the correct type. We can do a quick test to demonstrate that validation aspects of React are present.

To start out, in our Todo.js file place the following at the bottom of the file (outside of the class declaration)…

...
} // end of Todo class

Todo.propTypes = {
    title: React.PropTypes.string.isRequired
}

What we have declared here is that the title property is required and must be present on the component. To test out that this is working, edit the “Todolist.js” file by removing the “title” property in the render method…

...
    render() {
        
        var items = this.props.data.map((item, index) => {
            return (
                <Todo 
                    key={item.id} 
                    summary={item.summary} 
                    completed={item.done} 
                    remove={() => this.removeTodo(index)} />);        
        });
        
        return(
            <div> 
...

If we build and run our application we see the following warning message logged to our developers…

Warning: Failed propType: Required prop `title` was not specified in `Todo`. Check the render method of `TodoList`.

Because we have specified that we are expecting this property called “title” React issues this warning ahead of time. Now that we know that React is picking up on validation, we can go ahead and put the “title” property that we just deleted back in again. Now if we build and run the file again we see that the warning message goes away!

Let’s build upon this and explore some additional aspects of component validation. In addition to specifying which properties are required, we can also specify which data types we are expecting as well. We know that in rendering our list of “to do” components we are expecting an array of objects with different properties that we use to render out in the list. In our “TodoList.js” file, let’s add the following at the bottom (again, after the closing “}” for the class definition).

...
}
TodoList.propTypes = {
    data: React.PropTypes.arrayOf(React.PropTypes.object)
}

Here we have specified that the property that we pass into data in our “App.js” file needs to be an array of objects. Then in the Todo.js file we can build on what we did earlier with the “title” prop and add a few more rules around the expected values.

Todo.propTypes = {
    title: React.PropTypes.string,
    summary: React.PropTypes.string,
    completed: React.PropTypes.bool
}

There are many other aspects of validation that you can incorporate into your application and how you incorporate things really depends on how your application is structured. We will not cover every single validation case in detail here, but the preceding sections should give you a good place to start when you want to implement validation into your components. For more detail on this you can consult the React documentation.

Removing “To Do” Items & Passing Click Events From Child Component to a Parent Component

So now that we have the ability to add “to do” items, let’s take a look at how we can implement the functionality to remove items. Change the code in TodoList.js to the following…

import {react} from 'react';
import {Todo} from './Todo';

export class TodoList extends React.Component {
    
    constructor(){
        super(...arguments);
        this.state = {
            todos: this.props.data,
            newItem: {
                title: '',
                summary: ''
            }
        }
    }
    
    handleChange(key, event){
        var change = {
            title: this.state.newItem.title,
            summary: this.state.newItem.summary
        };
        change[key] = event.target.value;
        
        this.setState({           
            newItem: change        
        });               
    }
    
    addTodo(){
        this.state.todos.push({
            id: this.state.todos[this.state.todos.length - 1].id + 1,
            title: this.state.newItem.title,
            summary: this.state.newItem.summary,
            done: false
        });

        this.setState({
            todos: this.state.todos,
            newItem: {
                title: '',
                summary: ''
            }
        });        
    }
    
    removeTodo(index) {
        this.state.todos.splice(index, 1);

        this.setState({
            todos: this.state.todos
        });  
    }
    
    render() {
        
        var items = this.props.data.map((item, index) => {
            return (
                <Todo 
                    key={item.id} 
                    title={item.title} 
                    summary={item.summary} 
                    completed={item.done} 
                    remove={() => this.removeTodo(index)} />);        
        });
        
        return(
            <div>
                <ul>{items}</ul>
                
                <h3>Add New Item:</h3>
                <label>Title</label> <input type="text" value={this.state.newItem.title} onChange={(e) => this.handleChange('title', e)} />
                <label>Description</label> <textarea value={this.state.newItem.summary} onChange={(e) => this.handleChange('summary', e)}></textarea>
                <button onClick={() => this.addTodo()}>Add New Item</button>
            </div>
        )
    }
};

As we can see we have added a “removeTodo” method that will remove the item in our “todos” array at a certain index. But there is an additional layer to this functionality that we need to explore. Each individual “to do” item needs to have its own remove button. Otherwise, how will the user know which item he/she is removing? So we are actually going to have to update Todo.js as well (where the definitions of individual “to do” components are located). Before we do that make special note of the “remove” property for the Todo component in the render method above. We are essentially passing our “removeTodo” method down into each component. This is how we get cross-component communication and it will become increasingly more important later on.

On that note, change the code in Todo.js to the following…

import {react} from 'react';

export class Todo extends React.Component {
    
    constructor(){
        super(...arguments);
        this.state = {
            completed: this.props.completed,
        }
    } 
    toggleCompleted(){
        this.setState({completed: !this.state.completed})
    }
    render() {
        
        return(
            <li>
                <h2>{this.state.title}</h2><p>{this.state.summary}</p> <input type="checkbox" checked={this.state.completed} onChange={() => this.toggleCompleted()} />
                <button onClick={this.props.remove}>Remove</button>
            </li>
        )  
    }
};

As we can see here we have added a “Remove” button and wired the “onClick” event to this.props.remove. Recall from above that the “remove” property was a function on the “TodoList” component. So when we are clicking that button we are essentially calling up into that function. This code works and our click event travels up into the parent component and runs the “removeTodo” function there and it knows which item the event came from and its index in the list. Pretty neat, eh? This is a basic example of how we can pass events from child components to parent components.

As we have seen that using props, state, and event handlers properly is an essential part of developing React applications. There are many different places we can put our props and our event handlers and how you go about structuring things is entirely up to you. It can seem a bit complicated or overwhelming at first but after working with React for awhile you will begin to see some of the wisdom behind it. If you ever find yourself in a place where you are not sure what to do, you should always keep in mind this simple ancient React proverb…

Pass properties down, pass events up.

We saw this with our functionality to remove items from our list. We passed our function that we wanted to run down as a property into the Todo component, and linked the two when we passed the button click for the “Remove” button up to this function on the parent component. That is the general pattern to follow when working with React and communication between components. If you heed this wisdom, you will be very wise and build React applications that will be maintainable enough to endure for all eternity, young grasshopper.

Editing “To Do” Items

There is one final piece of functionality that we need to implement to have a useful React application and that is the ability to edit items in place. As it turns out all of the pieces that we need to implement this can be done in the Todo component. We do not need to keep track of anything at the TodoList level because all of the data we want to change resides within each item. So change the code of Todo.js to the following…

import {react} from 'react';

export class Todo extends React.Component {
    
    constructor(){
        super(...arguments);
        this.state = {
            title: this.props.title,
            summary: this.props.summary,
            completed: this.props.completed,
        }
    } 
    toggleCompleted(){
        this.setState({completed: !this.state.completed})
    }
    editTodo(key, event) {
        
        var change = {
            title: this.state.title,
            summary: this.state.summary
        };
        change[key] = event.target.value;
        this.setState(change);       
    }       
    render() {
        
        return(
            <li>
                <h2>{this.state.title}</h2>
                <p>{this.state.summary}</p> 
                <input type="checkbox" checked={this.state.completed} onChange={() => this.toggleCompleted()} />
                
                <input type="text" value={this.state.title} onChange={(e) => this.editTodo('title', e)} /> <textarea value={this.state.summary} onChange={(e) => this.editTodo('summary', e)}></textarea>                 
                
                <button onClick={this.props.remove}>Remove</button>
            </li>
        )  
    }
};

As we can see we have added a textbox and a textarea where we can edit the title and the summary. Similar to what we did earlier with our code to add an item, we create a common handler function (editTodo) for all of the fields that are editable and pass in a string with the name of the property we want to update. Notice that when we edit each individual item, the display text of each individual title and summary also change because they are data bound to this value.

Conditionally Displaying Elements Within Components

This editing functionality works fine from a functional standpoint, but as far as UX (user experience) goes it is not very good. It is ugly having a big form in the middle of each item as part of the display and one can only imagine how big and bloated things would get if we have more properties and or more items. We need to have a way to only show these when that particular item is being edited. For this we can again turn back to state and see if we can add an “edit mode” flag to our component so that we will only display the editing form elements when this “edit mode” flag is set to true. So let’s update the code in our Todo.js file to the following…

import {react} from 'react';

export class Todo extends React.Component {
    
    constructor(){
        super(...arguments);
        this.state = {
            title: this.props.title,
            summary: this.props.summary,
            completed: this.props.completed,
            inEditMode: false
        }
    } 
    toggleCompleted(){
        this.setState({completed: !this.state.completed})
    }
    toggleEditMode(){
        this.setState({ inEditMode: !this.state.inEditMode });
    }
    editTodo(key, event) {
        
        var change = {
            title: this.state.title,
            summary: this.state.summary
        };
        change[key] = event.target.value;
        this.setState(change);       
    }       
    render() {
        
        return(
            <li>
                {this.state.inEditMode ? <div><input type="text" value={this.state.title} onChange={(e) => this.editTodo('title', e)} /> <textarea value={this.state.summary} onChange={(e) => this.editTodo('summary', e)}></textarea></div> : <div><h2>{this.state.title}</h2><p>{this.state.summary}</p> <input type="checkbox" checked={this.state.completed} onChange={() => this.toggleCompleted()} /></div>}
                <button onClick={() => this.toggleEditMode()}>{this.state.inEditMode ? 'Stop Editing' : 'Edit'}</button>
                <button onClick={this.props.remove}>Remove</button>
            </li>
        )  
    }
};

As we can see we have added the flag “inEditMode” to our state that we toggle when we click our newly added “Edit” button which runs the “toggleEditMode” function. What does this do? In our component display we are using a ternary operator to display the form elements if the item is in “edit mode.” If the particular item is not in “edit mode” we just display the title and summary as we had been doing before. This implementation is one of the ways that is suggested to conditionally display parts of a React component in the React documentation. As this piece grows with more complex templates doing things this way could get a little bit bloated. So an alternative to this, as is suggested in the React documentation, is to do the conditional check for “inEditMode” just outside of the render function’s return method like so…

import {react} from 'react';

export class Todo extends React.Component {
    
    constructor(){
        super(...arguments);
        this.state = {
            title: this.props.title,
            summary: this.props.summary,
            completed: this.props.completed,
            inEditMode: false
        }
    } 
    toggleCompleted(){
        this.setState({completed: !this.state.completed})
    }
    toggleEditMode(){
        this.setState({ inEditMode: !this.state.inEditMode });
    }
    editTodo(key, event) {
        
        var change = {
            title: this.state.title,
            summary: this.state.summary
        };
        change[key] = event.target.value;
        this.setState(change);       
    }       
    render() {
        var display;
        if(this.state.inEditMode) {
            display = <div><input type="text" value={this.state.title} onChange={(e) => this.editTodo('title', e)} /> <textarea value={this.state.summary} onChange={(e) => this.editTodo('summary', e)}></textarea></div>;
        } else {
            display = <div><h2>{this.state.title}</h2><p>{this.state.summary}</p> <input type="checkbox" checked={this.state.completed} onChange={() => this.toggleCompleted()} /></div>
        }
        
        return(
            <li>
                {display}
                <button onClick={() => this.toggleEditMode()}>{this.state.inEditMode ? 'Stop Editing' : 'Edit'}</button>
                <button onClick={this.props.remove}>Remove</button>
            </li>
        )  
    }
};

This approach is a bit cleaner for more complex displays with more data values to keep track of.

Updating the Parent Component after State Changes on the Child

As we have seen the state in our individual to do items (title, summary, etc.) is stored on each individual “to do” item and the list of them is stored on the parent “TodoList” component. However, let’s take a brief look at something involved with this interaction that will be very important to remember when developing React applications. It is something that might seem a little unexpected at first but not all state changes in a child necessarily trigger state changes in the parent. This is especially noticeable when storing lists of child components in a property on the state object that is an array. In our case, our “TodoList” component has the “todos” property that stores the array of “Todo” components.

As it turns out we will actually have to specifically declare what we want to do on the parent when the child updates because there are certain instances when the parent state array is not aware of what has changed on the child component. Let’s take a look at when and why this might occur and what we can do about it.

In our “addTodo” method of our “TodoList” component, add the following at the bottom of this method such that our method looks like the following…

addTodo(){
    this.state.todos.push({
        id: this.state.todos[this.state.todos.length - 1].id + 1,
        title: this.state.newItem.title,
        summary: this.state.newItem.summary,
        done: false
    });

    this.setState({
        todos: this.state.todos,
        newItem: {
            title: '',
            summary: ''
        }
    });

    console.log(this.state.todos)        
}

Here we are logging just the current array of “to do” items whenever we add a new item. Now, after webpack recompiles this code let’s refresh our browser. As expected, we will see our original list of “to do” items. Edit the first existing item in our list by changing the title from “Eat Breakfast” to “Eat Brunch” or something like that. You can change the summary as well if you like, but any change will suffice here for purposes of demonstration. When you are done click the “Stop Editing” button.

As we can see the array of objects is logged to the console and there will be 4 items as we would expect [Object, Object, Object, Object]. However, look and see what happens if we expand and examine the first object (the one we originally edited). Surprisingly, the title still says “Eat Breakfast,” even though in the UI it says “Eat Brunch” because we changed it earlier. What is going on there?

This is one of those cases where parent component does not pick up changes in the child. As far as the parent component sees, there is still an object at index 0 of the “todos” property on the state object. Even though we changed the properties of that object, there was no change in the array from the parent’s point of view. When a new object to the array, that change *is* actually picked up because the array is now 1 item longer so the new item appears in the array. Long story short, there are steps we need to take to make sure that the parent state that stores the list of child components gets updated when we edit individual items. If we were to go to save our list to a database or something like that, we would want to be sure that we have all the up to date information of all the items in our list.

The way that we will handle the updating of items is to create a method on the parent. We will then pass that method down into the child component via props and then call that method inside of the method that handles child updates. Let’s take a look at what this looks like when implemented…

Add the following method to the “TodoList” component…

updateTodo(obj, index){
    this.state.todos[index] = {
        id: this.state.todos[index].id,
        title: obj.title,
        summary: obj.summary
    };
}

Then in the render() method, when we are looping through each “to do” item via the Array.map method, attach an update prop to each “Todo” component.

render() {
    
    var items = this.props.data.map((item, index) => {
        return (
            <Todo 
                key={item.id} 
                title={item.title} 
                summary={item.summary} 
                completed={item.done}
                update={(obj) => this.updateTodo(obj, index)}
                remove={() => this.removeTodo(index)} />);        
});
...

There is nothing special about the name “update.” We could name this prop whatever we want. Notice that this prop points to the method we had just created earlier. It will receive 2 parameters. The first will be passed up from the child “Todo” component, and the second is the index so we have a way of knowing which item in the array to update. All we end up doing is replacing the old object at this spot with the new object with updated data. We keep the id key exactly the same.

Finally, in the “Todo” component, in the place where we update individual state for the item (out editing function), we can call the update method via this.props. So add the call to our update method on the parent to youe “Todo” component…

editTodo(key, event) {
    
    var change = {
        title: this.state.title,
        summary: this.state.summary
    };
    change[key] = event.target.value;
    this.setState(change);    
    this.props.update(change);   
}

Notice our call to the “update” method which comes in as a prop. Basically all we are doing here is passing the data object that we have just changed up into our update property. This data comes in and gets passed to the parent method along with the index location where this data lives in the array.

Now if we rebuild and rerun our code we can see that when we update our individual items and then add a new item (assuming we still have the console.log in our code) we can see that whenever we edit “Todo” items, they are getting updated in the array and our data is consistent between parent and child. If we were to go save this data, we could be confident knowing it is up to date and consistent with what the user is seeing in the UI.

So that is something to be cognizant of when working with React. It is always a good thing to confirm that your state of anything on parent components match the individual child state properties.

CSS Styling & Polish in React

We will cover how to handle the visual styling (CSS) in React more in depth in future discussions, but for now it is worth doing a little bit of styling to add a bit of polish to our application here just to get our feet wet. Let’s add a stylesheet reference to our index.html file…

<!DOCTYPE html>
<html>
<head>
    <title>React</title>
    <meta charset=&quot;UTF-8&quot;>
    <meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;>
    <link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/style.css&quot;>    
</head>
<body>
    <div id=&quot;content&quot;></div>
    
    <script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/react/15.3.0/react.js&quot;></script>
    <script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/react/15.3.0/react-dom.js&quot;></script>
    <script type=&quot;text/javascript&quot; src=&quot;dist/App.js&quot;></script>      
    
</body>
</html>

And then we can add a few additional items to each of our list items that make up each individual “to do” component. Update the code in Todo.js to the following…

import {react} from 'react';

export class Todo extends React.Component {
    
    constructor(){
        super(...arguments);
        this.state = {
            title: this.props.title,
            summary: this.props.summary,
            completed: this.props.completed,
            inEditMode: false
        }
    } 
    toggleCompleted(){
        this.setState({completed: !this.state.completed})
    }
    toggleEditMode(){
        this.setState({ inEditMode: !this.state.inEditMode });
    }
    editTodo(key, event) {
        
        var change = {
            title: this.state.title,
            summary: this.state.summary
        };
        change[key] = event.target.value;
        this.setState(change);       
    }       
    render() {
        var isComplete = this.state.completed ? 'complete' : '';
        var display;
        
        if(this.state.inEditMode) {
            display = <div><input type="text" value={this.state.title} onChange={(e) => this.editTodo('title', e)} /> <textarea value={this.state.summary} onChange={(e) => this.editTodo('summary', e)}></textarea></div>;
        } else {
            display = <div className={isComplete}><h2>{this.state.title}</h2><p>{this.state.summary}</p> <input type="checkbox" checked={this.state.completed} onChange={() => this.toggleCompleted()} /></div>
        }
        
        return(
            <li>
                {display}
                <button onClick={() => this.toggleEditMode()}>{this.state.inEditMode ? 'Stop Editing' : 'Edit'}</button>
                <button onClick={this.props.remove}>Remove</button>
            </li>
        )  
    }
};

All of the changes that we have made are in the “render” function. We are using the React “className” hook to add a class to the item if the state of the current item is “completed.” If it is not in a “completed” state, this class is not added. Note that we are only doing this for the elements in “display mode.” We do not need to show this distinction when we are in “edit mode”

And then of course let’s create a “style.css” file in a “css” directory and then add some CSS to a style.css file in a “css” directory…

.complete {
    text-decoration: line-through;
}

When our “completed” class is added to the item, the “to do” item will have a “crossed-out” look to it signaling that we are done with the task. Now if we build and run this code we can see that clicking on the text box will toggle the state of whether a “to do” is completed. When a “to do” is marked as complete, the item gets crossed out by using the line-through text decoration.

We can expand on this and add a bit more CSS to enhance the display of our application. Place the following styling in the style.css file…

.complete {
    text-decoration: line-through;
}

#content label {
    display: block;
    margin-bottom: 10px;
}

#content input[type="text"] {
    margin-bottom: 10px;
    display: block;
}

#content textarea {
    margin-bottom: 10px;
    display: block;
}

#content ul {
    list-style-type: none;
    padding-left: 0;
            
}

#content li {
    margin: 5px 0;
    background: #fcfcfc;
    border: 1px solid #eee;
    padding: 10px;
}

#content li input[type="text"] {
    display: block;
    width: 100%;
    margin-bottom: 10px;
}

#content li textarea {
    display: block;
    width: 100%;
    margin-bottom: 10px;
}

#content li h2 {
    margin-top: 0;
}

Nothing too fancy, but it cleans things up a little bit.

Summary

Whew! We have come a long way and made great progress in writing our “To Do” application but we have covered a lot of the basic components of application functionality: displaying, adding, editing, and removing items. In the preceding sections we took a look at how we could do some more complex implementations in our React applications. We looked at how we could nest components within one another and we also looked at how we could handle user input — including text input and clicks — and how to send it to the UI and let React handle our UI updates. By now we are seeing how React handles a lot of this stuff for us and how its simple understandable syntax makes writing a client-side UI in JavaScript a lot cleaner with a lot less code. These will provide some valuable aspects as our applications grow and get more complex.

]]>
https://9bitstudios.com/2016/11/to-do-create-your-first-react-application-part-ii/feed/ 0
To Do: Create Your First React Application – Part I https://9bitstudios.com/2016/10/to-do-create-your-first-react-application-part-i/ https://9bitstudios.com/2016/10/to-do-create-your-first-react-application-part-i/#respond Thu, 06 Oct 2016 20:09:02 +0000 https://9bitstudios.com/?p=1176 React is a JavaScript library that is primarily responsible for handling the “view” component of a JavaScript single-page application. As it describes itself of the React homepage…

Lots of people use React as the V in MVC. Since React makes no assumptions about the rest of your technology stack, it’s easy to try it out on a small feature in an existing project.

React’s focus, first and foremost, has to do with rendering dynamic UIs in a manner that is visually appealing to the user. It is flexible enough that it can be used in a diversity of capacities and contexts. We have looked at React in previous entries. In what follows we will look at creating an introductory application using React and React related tools and libraries. One of the more ubiquitous tutorial applications that developers build when learning a new language or framework is the TO DO (To do) app. In terms of prevalence, it is probably second only to the “Hello, World” app which has been around since the dawn of programming. But the “To Do” application is popular because it covers a lot of the basics of how a language or framework handles a number of things. There must be a way to add a new “to do” so handling user input is involved. The same is true for displaying data, editing and saving data, and changing display state when data updates. All of these things are going to be important implementations in any application.

In what follows we will create the iconic “To Do” application in React and discuss some of the inner workings as we go along. We will take a deeper look into React components and how we can add some dynamic interactivity to our React applications in response to user actions — things like clicks and entering text in a text box — and updating our views accordingly.

JSX Compilation with Babel & Browserify

As we will see, React has its own programming language called JSX. It has been described as sort of like a mixture of JavaScript and XML and it is React’s own special easy-to-read abstracted syntax. JSX is not required to create React applications and you can write your React components in native JavaScript if you prefer. Because browsers do not natively understand JSX in order for your react application to run JSX needs get converted to native JavaScript.

The React website suggests that you utilize tools like Babel and/or Browserify (both of which run on Node.js). Babel is what is known as a transpiler. It mostly functions as a tool that takes code written in ECMAScript 6 (ES6) and converts it to ES5. As of 2015 this is still necessary because support for ES6 across all browsers is not widespread yet. Until support for ES6 is implemented across all browsers, tools like Babel will still be needed. Although many people think of Babel primarily as an ES6 to ES5 transpiler, Babel also comes with JSX support as well. You can merely run the Babel transpiler on your JSX files and they will be converted to native JavaScript that will be recognized by any browser circa 2015.

Browserify allows for Node.js style module loading in your client-side JavaScript. Like with Node, it allows you to import code in certain JavaScript files into other JavaScript files for better organization of your code.

Task Runners / Module Bundlers

For our sample code, we will be using task runners to handle our JSX conversion to native JavaScript. You may have heard of task runners like Grunt or Gulp, or module bundlers like webpack. We will be using webpack because it has, at least for the time being, become the utility of choice among the React community. If you are not entirely familiar with JavaScript task runners it would definitely be worthwhile to read the webpack documentation (or watch a few videos) on what it is and why you would want to use it. The more recent versions of React essentially require you to set up your tools before you work with JSX in React. In previous versions of React there was an easy extra <script> tag that you could add in your HTML to make it easy to implement JSX. However this has since been deprecated. If this seems daunting and you are already feeling overwhelmed, not to worry! We will walk through how to set everything up before we dive into React coding.

Setting Up

To start we need to set up our package.json and webpack.config.js files so that we can set up our tools to do JSXcompilation to native JavaScript. Create a new directory and then create a package.json file and add the following…

{
    "name": "React",
    "version": "0.0.1",
    "description": "A React application...",
    "license": "MIT",
    "repository": {
        "type": "",
        "url": ""
    },
    "homepage": "https://9bitstudios.com",
    "scripts": {
        "start": "webpack-dev-server --progress"
    },    
    "dependencies": {
        "react": "15.3.0"
    },
    "devDependencies": {
        "webpack": "1.13.1",
        "webpack-dev-server": "1.14.1",
        "babel-core": "6.13.0",
        "babel-loader": "6.2.4",
        "babel-preset-es2015": "6.13.0",
        "babel-preset-react": "6.11.1"
    }
}

Next, in this same directory, create a webpack.config.js file and add the following…

var webpack = require('webpack');

module.exports = {
    devtool: 'source-map',
    entry: __dirname + "/src/App.js",
    output: {
        path: __dirname + "/dist",
        filename: "App.js"
    },
    watch: true,
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loader: 'babel',
                query:{
                    presets: ['es2015', 'react']
                }
            }
        ]
    },
    devServer: {
        colors: true,
        inline: true
    },     
    plugins:[
        new webpack.optimize.UglifyJsPlugin(),
    ]
};

After this, let’s open a command prompt and run the following…

$ npm install

to install all of our modules that we will need for compiling ES6 and JSX. And that is all there is to it. Now that we have our tools installed and configured, we can dive into writing our application.

Writing a “To Do” Application

So let’s get started creating our “To Do” app. We will start out by creating our index.html file…

<!DOCTYPE html>
<html>
<head>
    <title>React</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <div id="content"></div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.0/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.0/react-dom.js"></script>
    <script type="text/javascript" src="dist/App.js"></script>      
    
</body>
</html>

As we can see, we are going to include App.js, which will be a file that we generate in our task runner. Note too we are creating a

with the id of “content.”

Next, create a folder called “src” and create a file called App.js in this folder. For this tutorial we are going to be breaking our components up into different modules so in our App.js file all we need to add for now is the following.

import {react} from 'react';

In the same directory as your App.js file, next create a file called “Todo.js”. In this file, we are going to need to create a React component/class that will represent each individual “to do.” Add the following code to this file…

import {react} from 'react';

class Todo extends React.Component {
    
    render() {
        return(<div>I am a to do</div>)  
    }
};

Pretty straightforward. This should look familiar as it is similar to our other earlier examples.

Now what we’re going to do is import this module into our App.js file. How do we do this? In our App.js file we just need to add the following…

import {react} from 'react';
import {Todo} from './Todo';

This will tell our code to import the “Todo” module from the “Todo” file relative to where “App.js” is located. With module loading in ES6 you can omit the “.js” from the file when you are importing modules.

So we are definitely well on our way but if we were to run this code as it is right now we would get an error. Why is this? Well, because we are importing a module from our “Todo.js” file we need to specify what this file exports. To do this we need to add the “export” keyword in front of what we want to make available from the “Todo.js” file. Thus, we need to change our code in our “Todo.js” file to the following…

import {react} from 'react';

export class Todo extends React.Component {
    
    render() {
        return(<div>I am a to do</div>) 
    }
};

Notice how we have added the “export” keyword in front of our class. Now there is something that can be imported from the “Todo.js” file. We will get into more complex combinations of what various files can export and import later on, but for now this simple example shows the basic setup of how it is done.

Now in our App.js file add the “render” method so we can confirm that everything is working…

 import {react} from 'react';
import {Todo} from './Todo';

ReactDOM.render(<Todo />, document.getElementById('content'));

Let’s build our App.js file by running “webpack” by opening up a terminal window typing the following…

$ webpack

Doing the above will build the App.js file and place it in our “dist” folder. Now if we open up another terminal window and run our server with…

$ npm start

and we go to https://localhost:8080 in our browser, if all has gone well we should be able to see the text “I am a to do.”

Component Composition

For our application we will be rendering a list of “to do” items inside of our “to do” list. Thus, we will also need to create a component that represents our “to do” list. So create a “TodoList.js” file in the same directory as the others and add the following code…

import {react} from 'react';
import {Todo} from './Todo';

export class TodoList extends React.Component {
    
    render() {
        return(<div>To do list here...</div>)  
    }
};

“TodoList” is the component that will serve as our “root” container component for our React application. It is just returning some placeholder text for now, but we will be adding more complexity to it very soon. Because the “TodoList” top-level component for this particular application, it is this one that will be the one that we want to render in our App.js file (not the individual “Todo” components). So change the code in our App.js file to the following…

import {react} from 'react';
import {TodoList} from './TodoList';

ReactDOM.render(<TodoList />, document.getElementById('content'));

Notice now how we are now rendering the “TodoList” component now and not the “Todo” components.

Now let’s take a look at how we could add some “depth” to our components (i.e. nesting components within components). In this case we will be nesting individual “Todo” components inside of our “TodoList” component. So in our “TodoList.js” file we can update our code to the following…

import {react} from 'react';
import {Todo} from './Todo';

export class TodoList extends React.Component {
    
    render() {
        return (<Todo />);
    }
};

It is as simple as that! You can include other components in what you return in your render method. This can include multiple components if you so desire…

 import {react} from 'react';
import {Todo} from './Todo';

export class TodoList extends React.Component {
    
    render() {
        return (
            <div>
                <Todo />
                <Todo />
                <Todo />
            </div>
        );
    }
};

This example will render the text in our “Todo” component 3 times.

In a real-world application, what you render in any given React component will often include multiple components of many different types. This is what we refer to when we explain React components as being composable. They can be composed of multiple components of different types.

Our example is very plain right now. Let’s take a look and see if we can make things more dynamic by rendering out some variable data and adding some interactivity by wiring up some events (clicks, hovers, etc.)

Properties With this.props

We discussed the importance of this.props and this.state a bit earlier and we will expand upon this in the upcoming sections. To start let’s use some sample data. This data will again be an array of objects and will be somewhat similar to what we used earlier in our introduction to React. So update the App.js file to look like the following…

import {react} from 'react';
import {TodoList} from './TodoList';

let todos = [
    {
        id: 1,
        title: "Eat Breakfast",
        summary: "Toast and scrambled eggs would be nice.",
        done: true
    },
    {
         id: 2,
         title: "Walk Dog",
         summary: "Dress for wet weather.",
         done: false
    },
    {
         id: 3,
         title: "Learn React",
         summary: "I am making great progress!",
         done: false
         
     }
];

ReactDOM.render(<TodoList data={todos} />, document.getElementById('content'));

Here we have an array of objects that we are going to pass in to our “TodoList” component. Inside of our component the data will be accessible by using this.props.data. The name “data” is just the name that I picked. You can choose any name that you want for your property attributes.

Continuing on, update the code in our TodoList.js file to the following…

import {react} from 'react';
import {Todo} from './Todo';

export class TodoList extends React.Component {
    
    render() {
        
        let items = this.props.data.map(function(item){
            return (<Todo title={item.title} summary={item.summary} completed={item.done} />);        
        });
        
        return(<ul>{items}</ul>)
    }
};

As we can see, we are accessing the data that is passed into our component with this.props.data. We iterate through the array and for each item, we pass the data in the item one level deeper into a “Todo” component. We create a collection of these components and return each one.

And then finally, let’s update our Todo.js file to the following…

 import {react} from 'react';

export class Todo extends React.Component {
    
    render() {
        return(
            <li>
                <h2>{this.props.title}</h2>
                <p>{this.props.summary}</p>
                <input type="checkbox" checked={this.props.completed} />
            </li>
        )  
    }
};

So as we can see here, the title, the summary, and the flag on whether or not the item is marked as completed that we are passing into the component will be available with this.props.completed because we passed the done property in the object on each item into this slot.

Now if we build our files with $ webpack we can see the listing of our “to do” items. The ones that have the “done” property set to true have the checkbox checked.

Handling Events & State

One of the important parts that React applications handle for you is management of “state.” What is state? State is basically the current values that any given component holds that is often reflected in the way that the UI displays and represents its values. In our example above some of the items in our “to do” list hold a current state of being “completed” and some hold a current state of being “not completed.” State is the current collection of properties holding a set of values within a component. When the state updates, that is, when the value of one of these properties in a component changes, the component re-renders itself. We hinted at this piece of React briefly before and this one of React’s awesome features. Components re-render themselves when there is any change. We do not have to try to update things manually ourselves within the UI!

There are a number of different ways that a component’s state can change, but one of the more common ways is via events. Events are things such as mouse clicks and hovers that are usually instigated by a user but they can also be triggered in code as well. Wiring up events in React is similar to how it is done inline with JavaScript in HTML. You may have seen code like this before in vanilla JavaScript…

<script type="text/javascript">
function showMessage(){
   alert("Hello world!");
}
</script>
<input type="button" id="messageButton" value="Submit" onclick="showMessage()" />

In the “onclick” attribute, we run the showMessage() function which will alert a message “Hello world!”. React takes a similar approach to this when it comes to hooking up events. Let’s see what this looks like. Update the code in “Todo.js” to the following…

import {react} from 'react';

export class Todo extends React.Component {
    
    constructor(){
        super(...arguments);
        this.state = {
            completed: this.props.completed
        }
    }
    
    toggleCompleted(){
        this.setState({completed: !this.state.completed})
    }
    
    render() {
        return(
            <li>
                <h2>{this.props.title}</h2>
                <p>{this.props.summary}</p>
                <input type="checkbox" checked={this.state.completed} onChange={() => this.toggleCompleted()} />
            </li>
        )  
    }
};

You may have noticed the “…arguments” in the constructor. This is the spread operator that is a new feature in ES6 and in JSX. You also might notice our use of an arrow function that we discussed earlier in the “onChange” attribute. This is actually a necessity with regard to the scope of the component. If we did not use an arrow function here, the function in the attribute would create its own scope. Therefore we would have had to use “bind” and write something like onChange={this.toggleCompleted.bind(this)}. However, because arrow functions operate in the context of the parent scope, “bind” becomes unnecessary and the scope of the attribute operates under the scope of the component.

For the checkbox, we could attach and “onClick” event here if we wanted to and it would work fine, but instead of using the “onClick” event, we will use the “onChange” event because it is a bit more all-encompassing. In the future we will work with input textboxes, select boxes, and a number of other form elements. The “onChange” event will cover that a bit more comprehensively and we will be using it more regularly as we go along. There will be a time and a place for “onClick” specifically as well but in this case, onChange is a better fit.

If we build our code and ran this code as it is, we would get a warning message in the console saying…

Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `TodoList`. See https://fb.me/react-warning-keys for more information.

What is going on here? As we can see from the suggested page in the React docs there is a description of why this warning is appearing…

The situation gets more complicated when the children are shuffled around (as in search results) or if new components are added onto the front of the list (as in streams). In these cases where the identity and state of each child must be maintained across render passes, you can uniquely identify each child by assigning it a key… When React reconciles the keyed children, it will ensure that any child with key will be reordered (instead of clobbered) or destroyed (instead of reused).

So when dealing with events and state React requires a unique ID “key” to be attached for child components within a set. React uses this internally to allow for efficient reordering and identifying a specific item within the set. This is especially important when items are added to or removed from the set. So let’s update the code in our TodoList.js file…

import {react} from 'react';
import {Todo} from './Todo';

export class TodoList extends React.Component {
    
    render() {
        
        var items = this.props.data.map(function(item){
            return (<Todo key={item.id} title={item.title} summary={item.summary} completed={item.done} />);        
        });
        
        return(<ul>{items}</ul>)
    }
};

As we can see, we have passed in the item ID as the key property. That’s all we have to do! Once we do this and then rebuild our JavaScript this error message will go away. React is very helpful in giving us information with regard to how we need to change our code to set things up properly.

Now if we open our browser and go to our https://localhost:8080 site (run $npm start) we can see the items in our list rendered. The ones that have the “done” property set to true will have the checkbox checked. If we check/uncheck the checkboxes, the underlying data for the component underneath will be toggled as the “toggleCompleted” method will be running each time we do this. This brings us to the concept of state, something that is inexorably linked with events.

As we have mentioned earlier, state is the current collection of properties holding a set of values within a component. Collectively it is the status of the component at any given time and is subject to change at any time. This change will trigger React to do a “rerender” of the UI. In our example we are displaying the title and the summary with this.props.title and this.props.summary. In React, this.props is read-only and cannot be changed. Trying to set this.props.title = ‘Something Else’ will result in an error. Contrary to this.props, this.state is mutable. Because the “completed” property will change we will set an initial value for it in the constructor. Note that even though we cannot change anything on this.props we can still read the values in this.props to set an initial state. When certain events happen or certain functions execute, we can update the state of the component with this.setState and pass in an object containing all the properties we want to update. We will also do this for the title and summary properties later on when we get into writing our functions to edit our “to do” components. But for now we are just doing this with our “completed” flag.

That about does it for part 1. In part 2 we will work on filling out the application a bit more and adding in some validation. Until next time…

]]> https://9bitstudios.com/2016/10/to-do-create-your-first-react-application-part-i/feed/ 0 Develop Apache Cordova Applications with HTML5 & JavaScript https://9bitstudios.com/2015/12/develop-apache-cordova-applications-with-html5-javascript/ https://9bitstudios.com/2015/12/develop-apache-cordova-applications-with-html5-javascript/#respond Sat, 19 Dec 2015 22:59:14 +0000 https://9bitstudios.com/?p=1124 In a prior discussion we looked at how to set up a project so that we could develop an Apache Cordova application using HTML5 and JavaScript. In that section we mostly covered how to set up, build, and run the project — which consisted of the same application in the www folder that Apache Crodova bootstraps when you create a new project. In what follows we will look at the approach for actually writing own code for our app and will look at how an app in Apache Cordova gets initialized. We will also look at how we can extend the Apache Cordova platform by using plugins to give ourselves additional features and functionality that will make for an all around better user-experience (UX) for the users of our app.

Now that we have our project set up and all our platforms added all that we have left to do now is create our application by creating what basically amounts to a website that runs HTML and JavaScript in the “www” folder. How should one develop for Apache Cordova? Personally, I would delete all of the boilerplate files and folders and start from scratch. That is what we will do here. Just take a quick note of how things are referenced in the index.html file and do the same for your own files.

In doing this, I have modified the index.html file in the “www” folder to the following…

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <title>Cordova Application</title>
    </head>
    <body>
        
        <div id="main">Initializing...</div>
        
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
    </body>
</html>

Note: Do not worry about that “cordova.js” reference or the fact that this file is nowhere to be found in our “www” folder. Apache Cordova will utilize this in the proper context when the app runs (so leave it in there).

So as far as the index.html goes, there is nothing too fancy. I have a css file (index.css) and a js file (index.js). That is all you need to get started.

Next, let’s look at our JavaScript in the index.js file. There is really only one thing you need to make note of when you develop Apache Cordova applications in JavaScript. There is a special event that Apache Cordova uses to tell the platform that the everything is loaded and the device you are using is ready to start running JavaScript in your Cordova application. This is what is known as the “deviceready” event. It only fires when you are running an app within a Cordova context (i.e. on a device or an emulator of a device). In a lean version of JavaScript for a cordova application would look like the following (in index.js)…

var app = {
    init: function() {
        document.addEventListener('deviceready', this.main, false);
    },
    main: function() {
        document.getElementById('main').innerText = 'App is ready...'
    }
};

app.init();

Here we are calling the “init” function which will add a listener for the “deviceready” event. When this event fires the “main” function will run, which in this case just changes the inner text of a div element So if we run this using

$ cordova emulate android

or

$ cordova emulate ios

from the root of our project we will see our device boot up, our app launch, and if all goes well we will see the text “App is ready…” so we know that our event is firing.

But it gets kind of annoying to have to fire up the emulator every time we want to test something out or make small changes in doing development. So it would be easier to be able to open the index.html file in the browser. But the problem with this is that the browser does not natively support the “deviceready” event. If you try to open index.html in a browser you see that the text remains as “Initializing…” The “deviceready” event does not get fired by the browser. So to get around this we have to set a flag so that we conditionally check if we are trying to run our app in a browser. So update the code in index.js to the following…

var config = {
    DEV: true    
};

var app = {
    init: function() {
        if(config.DEV) {
            this.main();
        } else {
            document.addEventListener('deviceready', this.main, false);
        }
    },
    main: function() {
        document.getElementById('main').innerText = 'App is ready...'
    }
};

app.init();

Now that we have set a flag in config to check whether we are just intending to run in “dev mode” in the browser, we will just call the main function directly and that will be the place that we kick off our application. We essentially bypass the “deviceready” step.

Now if you run this in the browser, we see that the “App is ready…” text is rendered to the page. If we change the config.DEV flag to “false” and run

$ cordova emulate android

or

$ cordova emulate ios

we can see that our main function is still running to kick off our app.

Even though the “deviceready” event is kind of the official Apache Cordova way of making sure that everything is initialized, if you forget to change the “DEV” flag to “false” and directly call the “main” function while running on a device, things will probably still work.

Splash Screens, Icons, & Using Plugins

Apache Cordova gives you a great framework out of the box to create a mobile app that can run on different platforms (as we have seen). But as great as it is, often there are things that you run into that may not be as easy to implement as they would be if you were creating an app using the native tools and languages. Fortunately, if you run into something that is not natively supported in Apache Cordova, there is a vibrant plugin ecosystem (and community behind it) that has worked to extend the support and functionality of the framework. You may have noted that there was a “plugins” folder in our Apache Cordova project. This is where installed plugins go.

Let’s take a look at a plugin that allows us to display a “splash screen” while our app launches. This is a common feature that you may have seen in many apps. We will use the cordova-plugin-splashscreen plugin. This plugin will allow us to specify paths to images that we will use as our splash screens. Because there are so many different resolutions across iOS and Android phones and tablets, we are going to have to specify a number of different resolutions of images that we will use for our splash screens. It will also allow you to show the Rather than list out what each of these resolutions need to be I have included a sample Apache Cordova project here as a download with some blank images of the sizes that they need to be to support this feature on most (nearly all) modern devices (iPhones, iPads, Android phones, and Android tablets). You can find these in the “res” folder in the “www” directory.

This cordova-plugin-splashscreen plugin will also allow us to specify the images that will be used for the icon of our app that shows up on the user’s home screen when the app gets installed. Up until now, Apache Cordova has just been using its own default image (that little robot looking thingy). But with this plugin we can change the icon, to what we want it to be! Awesome!

To install our plugin we just need to run the following from the root of our Apache Cordova project…

$ cordova plugin add cordova-plugin-splashscreen

If for some reason that does not work for you, you can try running the following

$ cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git

Once the plugin is installed we can now specify the paths to our splash screens and icons. We will do this in the config.xml that resides in the root of our project. As mentioned prior I have posted a sample Apache Cordova project that is available for download. In that project we can see the config.xml file that looks like the following…

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.sample.sampleapp" version="0.0.1" xmlns="https://w3.org/ns/widgets" xmlns:cdv="https://cordova.apache.org/ns/1.0">
    <name>SampleApp</name>
    <description>
        A sample Apache Cordova application...
    </description>
    <author email="dev@cordova.apache.org" href="https://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <access origin="*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
        <!-- Android Icons -->
        <icon src="www/res/android/icons/ldpi.png" density="ldpi" />
        <icon src="www/res/android/icons/mdpi.png" density="mdpi" />
        <icon src="www/res/android/icons/hdpi.png" density="hdpi" />
        <icon src="www/res/android/icons/xhdpi.png" density="xhdpi" />
        
        <!-- Android Splash Screens -->
        <splash src="www/res/android/screen/splash-land-hdpi.png" density="land-hdpi"/>
        <splash src="www/res/android/screen/splash-land-ldpi.png" density="land-ldpi"/>
        <splash src="www/res/android/screen/splash-land-mdpi.png" density="land-mdpi"/>
        <splash src="www/res/android/screen/splash-land-xhdpi.png" density="land-xhdpi"/>
        <splash src="www/res/android/screen/splash-port-hdpi.png" density="port-hdpi"/>
        <splash src="www/res/android/screen/splash-port-ldpi.png" density="port-ldpi"/>
        <splash src="www/res/android/screen/splash-port-mdpi.png" density="port-mdpi"/>
        <splash src="www/res/android/screen/splash-port-xhdpi.png" density="port-xhdpi"/>   		
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <!-- iOS Icons -->
        <icon src="www/res/ios/icons/icon-60@3x.png" width="180" height="180" />
        <icon src="www/res/ios/icons/icon-57.png" width="57" height="57" />
        <icon src="www/res/ios/icons/icon-57@2x.png" width="114" height="114" />
        <icon src="www/res/ios/icons/icon-60.png" width="60" height="60" />
        <icon src="www/res/ios/icons/icon-60@2x.png" width="120" height="120" />
        <icon src="www/res/ios/icons/icon-76.png" width="76" height="76" />
        <icon src="www/res/ios/icons/icon-76@2x.png" width="152" height="152" />
        <icon src="www/res/ios/icons/icon-40.png" width="40" height="40" />
        <icon src="www/res/ios/icons/icon-40@2x.png" width="80" height="80" />
        <icon src="www/res/ios/icons/icon.png" width="57" height="57" />
        <icon src="www/res/ios/icons/icon@2x.png" width="114" height="114" />
        <icon src="www/res/ios/icons/icon-72.png" width="72" height="72" />
        <icon src="www/res/ios/icons/icon-72@2x.png" width="144" height="144" />
        <icon src="www/res/ios/icons/icon-small.png" width="29" height="29" />
        <icon src="www/res/ios/icons/icon-small@2x.png" width="58" height="58" />
        <icon src="www/res/ios/icons/icon-50.png" width="50" height="50" />
        <icon src="www/res/ios/icons/icon-50@2x.png" width="100" height="100" />
        
        <!-- iOS Splash Screens -->
        <splash src="www/res/ios/screen/Default~iphone.png" width="320" height="480"/>
        <splash src="www/res/ios/screen/Default@2x~iphone.png" width="640" height="960"/>
        <splash src="www/res/ios/screen/Default-Portrait~ipad.png" width="768" height="1024"/>
        <splash src="www/res/ios/screen/Default-Portrait@2x~ipad.png" width="1536" height="2048"/>
        <splash src="www/res/ios/screen/Default-Landscape~ipad.png" width="1024" height="768"/>
        <splash src="www/res/ios/screen/Default-Landscape@2x~ipad.png" width="2048" height="1536"/>
        <splash src="www/res/ios/screen/Default-568h@2x~iphone.png" width="640" height="1136"/>
        <splash src="www/res/ios/screen/Default-667h.png" width="750" height="1334"/>
        <splash src="www/res/ios/screen/Default-736h.png" width="1242" height="2208"/>
        <splash src="www/res/ios/screen/Default-Landscape-736h.png" width="2208" height="1242"/>  		
		
    </platform>
    <preference name="SplashScreen" value="screen" />
    <preference name="SplashScreenDelay" value="4000" />
</widget>

As we can see, we have specified paths to a number of different images of different resolutions. with these settings the cordova-plugin-splashscreen Apache Cordova plugin will automatically figure out which is the best resolution to use depending on the

We can also see that in the <preference> elements down at the bottom we have specified “SplashScreenDelay” preference down at the bottom of the config.xml file. This specifies to show the splash screen for 4 seconds (4000 milliseconds). You can change this value to the one that you prefer.

Now if you run your application with

$ cordova emulate android

or

$ cordova emulate ios

You will see a splash screen displayed before the app launches. It’s blank for now until you bust out your graphic designer skills and create a nice looking one. If you click on the “home” button on the emulator device you can see on the home screen that the icon we have in our project is now used as the app icon. Like with the splash screen, obviously for a production app we would want to make nice looking icons consistent with the theme of our app. But the functionality is there and all you have to do is replace the icons and splash screens in the sample project with your own app branding.

So sample project and try it out. Note: After downloading the project you will need to 1) add the platform(s) that you want to work with with $ cordova platform add and 2) install the splash screen plugin with $ cordova plugin add cordova-plugin-splashscreen.

Summary

Now that we have walked through how to set up some app initialization code from here, everything that you want to do is entirely up to you. There are really no limitations on what you can do here. Apart from the unique “deviceready” event there is nothing special that you need to do to code for Apache Cordova (and even hooking into the “deviceready” event probably isn’t even absolutely essential). You can just create things in the same way that you would if you were going to put this web application on the web and have users run it in their browsers. There is no special magic needed. You can add more CSS files, images, other JavaScript files, or whatever else you want to and start building. You can use popular front-end frameworks like Bootstrap or Foundation. Or, if you prefer, you can import a framework specifically designed for mobile such as jQuery Mobile. You can use popular JavaScript development frameworks like Backbone.js, Ember.js, AngularJS, or React. Ultimately the choice is entirely up to you. I cannot choose for you.

From there, the sky’s the limit. You can do whatever you like to create whatever kind of app you want. But since there are so many different types of applications for so many different purposes, it is ultimately up to you to decide on what technologies you want to use and what is the best way to implement your app. So get out there and develop it up. Until next time, cheers and happy developing!

]]>
https://9bitstudios.com/2015/12/develop-apache-cordova-applications-with-html5-javascript/feed/ 0
Create Mobile Applications for iOS and Android with HTML5, JavaScript, and Apache Cordova https://9bitstudios.com/2015/12/create-mobile-applications-for-ios-and-android-with-html5-javascript-and-apache-cordova/ https://9bitstudios.com/2015/12/create-mobile-applications-for-ios-and-android-with-html5-javascript-and-apache-cordova/#respond Sat, 12 Dec 2015 22:49:53 +0000 https://9bitstudios.com/?p=1101 Obviously at the time of this writing in the 2nd decade of the 21st century, you are no doubt well acquainted with the immense proliferation and impact that mobile apps have had in and on our world. It was not long ago that we were all sitting at our computers at our desks for the large majority of the time we spent in our various avenues of technological communications over the Internet — complete with our with our giant monitors, whirring computer fans, buzzing drives, and the garbled noise of dial-up modems. Now, mobile phones and tablets probably make up as much, if not more, of our time spent working, playing, and communicating online. Everyone has a ~$100 to $600 smartphone (i.e. computer) in their pocket. And with this rise of mobile, apps found on the popular stores — like Apple’s iOS App Store, Google Play (Android), Amazon and a host of others — have completely transformed the way that we do anything and everything because well, there is an app for anything and everything. Every single facet of life probably has an app to manage some aspect of it. Need to remember to breathe? There is an app for that! Yeah, that is a joke (probably)… but there are plenty of “real” apps out there (e.g. iBeer) that are just as pointless. Fun and goofy, yes, but pointless. And they all post their pointlessness to Facebook and/or Twitter.

Whether you want to develop an app to manage some minute aspect of life or just create a fun game, or whatever else, you can download the SDK for the platform(s) that you want to release your app on, do some tutorials, and start building. That’s all well and good, but if you want to port your application to another platform (e.g. release an iOS app also for Android), you will essentially have to try rebuild the same app using the languages in tools of a different platform. For example, iOS apps for iPhone and iPad have traditionally been developed on a Mac in the Xcode IDE using the Objective-C programming language (though Apple has recently released a new language called Swift that can also be used to build iOS apps). Android apps, by contrast are built using Java and Eclipse or the more recently released Android Studio. Native Windows Phone apps are built using C# and XAML in Visual Studio. Other platforms have their own setups. If you want to take this approach you definitely can, but it should be fairly apparent that developing and maintaining a number of different codebases for multiple platforms quickly adds up to a lot of time, effort, and often money as the sizes and complexity of your apps increase.

At the same time as the rise of mobile in the past decade, something else has occurred: the rise of HTML5 and JavaScript web applications. Beginning at around 2009 – 2010 one of the more noticeable developments was the rise of websites and web applications making use of more open technologies such as HTML5 and JavaScript to bring interactivity and 2-way communication between clients (usually browsers) and servers. With Flash on the way out due its proprietary nature, resource hogging, security issues, poor SEO — along with its being snubbed by Apple for support on iPhones and iPads for basically all these reasons — meant that something had to fill the void. HTML5 and JavaScript moved into this space and developers started turning to it for creating interactive “app-like” experiences.

Wouldn’t it be awesome if there were a way to write a single application in HTML and JavaScript with a single codebase and have a way to port this application to all of the different mobile platforms? I am so glad you asked.

Apache Cordova — also commonly known as “PhoneGap” (the only difference between the two is propriety) — allows us combine combine these open technologies together with the SDKs of the various mobile application platforms to make native mobile applications using technologies such as HTML and JavaScript. You can basically create a small static HTML and JavaScript website or web application and this code will be imported into native iOS, Android, Windows Phone projects and configured specifically for the respective platforms. Thus, you *do* still have to have the SDK of the platform installed to build, run, and release the apps. So to create an iOS app you will still need a Mac and Xcode. To create Android apps you will need to install the Android SDK (which comes with the Android Studio IDE). But the important aspect of using Cordova is that the HTML and JavaScript that each project will pull in and build will be the same across all platforms. Want to release an update with some slick new features or fix some bugs that have been reported by your users? You need only change your code in your HTML and JavaScript. You don’t have to try and rewrite the same code and/or functionality in a different language on each platform. From there all you need to do is run a few simple commands from the command lines and your HTML and JavaScript will get built and converted into an application that can run on the platform(s) you are targeting.

In what follows we will explore what it looks like to use Cordova to create a mobile application in HTML and JavaScript that can run on a number of different platform. For our examples, we will build our app for iOS and Android, but the process is essentially the same for building for other platforms (e.g. Microsoft Windows Phone, Amazon Kindle Fire). You would just need to download the SDKs for those platforms if you wanted to run your app on those types of devices as well.

So let’s get to it…

Installing Node.js

The first thing that we will need to do before we do anything else is install Node.js. Apache Cordova runs on Node.js so it is a prerequisite. If you’re not entirely familiar with Node.js there is a primer on Node.js here. It has become a huge part of JavaScript development in the last half-decade and is only becoming more and more prominent.

To install Node.js all you have to do is head on over to their website and follow the directions for your operating system (Windows, Mac, or Linux).

Installing Apache Cordova

Once we have Node.js installed, next we will need to install Apache Cordova. We just do this over npm. npm comes with the Node.js installation, so you already have it on your machine from installing Node.

To install Cordova open up a command window or terminal and run the following…

$ npm install -g cordova

In case you are not familiar with it, the “-g” flag means “global.” You will want to do this so that you can run Cordova commands from any directory on your system.

Creating an Apache Cordova Project

Now you can go to a directory where you want to create your Cordova project and open a command window/terminal. We will be initializing a new Cordova application here with the Cordova “create” command. For more information on the configuration options you can choose when installing and setting up your project, please see the Apache Cordova documentation here. Run the following command from your command line…

$ cordova create ninebit com.ninebitstudios.ninebitapp NinebitApp

The command above will create a vanilla Cordova project called “NinebitApp” and ocnfiguring it with a unique ID that uses reverse domain name notation in a directory named “ninebit.” What you will want to do is change these values to what you want for your own application.

$ cordova create   

For example…

$ cordova create yourdirectory com.yourdomain.yourapp YourAppName

but just plug your own values that you want in there.

You should see the directory with the name you specified created with with a number of files and directories in there like “platforms,” “plugins,” “www”, and a “config.xml” file. The config.xml file will have some of the values that you specified in your mobile. The actual location where you will write your HTML and JavaScript is in the “www” directory. If you explore that directory and open the index.html file you will see a boilerplate web application which basically just displays an image on the page. Even though it does not do much, this is an app that can run on any of the platforms we want to specify. We will add these platforms next.

Adding Support for Android Devices to the Project

Now that we have our project created we need to “add” the platforms that we want to release on to our project. Open a command window in the root directory of the project (the one with the config.xml file).

To add Android to our project run the following…

$ cordova platform add android

You should see a directory called “android” in the platforms folder. This folder contains a native Android project that is preconfigured to take the HTML and JavaScript in the “www” folder and run it in an Android device. If you opened Android Studio and clicked on “Create New Android Project” you would see almost the same files and folders in the project that gets created when creating a native Android application. There will be few extra files and folders in the Cordova Android project specific to Apache Cordova.

Because we now have a native Android project, we can run it on the Android emulator. In the root directory we can now run following…

$ cordova emulate android

This should launch the Android emulator and automatically run your application after it boots up. Note that you might need to set up a device for Android project to use before you try to run the command above. To do this, you will need to launch the Android Virtual Device Manager (AVD Manager.exe). This application resides in the root folder of where you installed your Android Studio SDK. You can also launch AVD Manager in Android Studio under the “Tools” menu under “Android.” However you open this application, once you are in there just click “Create New” and pick whatever device you want. Once you get the device set up you can try to run the command above again.

Adding Support for iOS Devices to the Project

Similarly, if you want to add support for iOS

$ cordova platform add ios

As was the case with Android above, you should see an “ios” directory. This folder contains a native Xcode project that is preconfigured to take the HTML and JavaScript in the “www” folder and run it in an iOS device.

Remember that you *must* have the SDK of the platform you are trying to add installed on your system. If you do not the Cordova console should inform you of this error.

For iOS you will want to make sure that you have the proper folder permissions in all of the directories and folders you will be working in. I had some issues trying to emulate when running all the cordova commands with sudo. So make sure on your Cordova project directory you do something like the following…

$ sudo chmod -R 777 foldername

so that you can run all the commands without using sudo

The first thing that you’ll want to do is add the iOS platform to your project.

$ cordova platform add ios

You can then build for iOS by running the following command. If you are able to do so without errors, you’ll know that everything is all good.

$ cordova build ios

Note in /platforms/ios/cordova/lib there is a list-emulator-images tool that you can run to list out all of the emulator images that you have installed. These are the different devices that you can emulate your apps…

$ ./platforms/ios/cordova/lib/list-emulator-images 

You will see a list like the following…

  • iPhone-4s
  • iPhone-5
  • iPhone-5s
  • iPhone-6-Plus
  • iPhone-6
  • iPad-2
  • iPad-Retina
  • iPad-Air
  • Resizable-iPhone
  • Resizable-iPad

If you want to specify a target, you can run the simulator on a specific device by targeting a specific device. For example…

cordova emulate ios --target="iPhone-4s"
cordova emulate ios --target="iPad-Air"
cordova emulate ios --target="iPhone-6"
cordova emulate ios --target="iPhone-6-Plus"

Otherwise, the iOS development tools will just use what is set as the default device (usually the latest version of the iPhone that is currently in production).

And of course, if you want to emulate on an iOS device in Xcode you can run the following command in your project root…

$ cordova emulate iOS

This should launch the iOS simulator and run your application.

Summary

In the above discussion we looked at all of the steps, tools, and environments necessary to create an Apache Cordova project and get things set up such that you can begin developing cross-platform mobile applications. In a future discussions we will take a deeper look at how write the code for out apps as well as how to package everything in your application up once you are finished developing and submit it to the respective stores for iOS (App Store) and Android (Google Play). But those are other discussions for some other days. So until next time, happy mobile developing!

]]>
https://9bitstudios.com/2015/12/create-mobile-applications-for-ios-and-android-with-html5-javascript-and-apache-cordova/feed/ 0
Introduction to React https://9bitstudios.com/2015/09/introduction-to-react/ https://9bitstudios.com/2015/09/introduction-to-react/#respond Sat, 19 Sep 2015 03:13:54 +0000 https://9bitstudios.com/?p=1072 React is a JavaScript library that is primarily responsible for handling the “view” component of a JavaScript single-page application. As it describes itself of the React homepage…

Lots of people use React as the V in MVC. Since React makes no assumptions about the rest of your technology stack, it’s easy to try it out on a small feature in an existing project.

React’s focus, first and foremost, has to do with rendering dynamic UIs in a manner that is visually appealing to the user. It is flexible enough that it can be used in a diversity of capacities and contexts. We mentioned earlier that there are a number of different MVW/MV* JavaScript frameworks and all of them have different implementations in how they handle the various aspects of a JavaScript application. Naturally they all have different ways that they handle rendering visual representations of the data that the application is handling. Backbone.js natively uses Underscore.js templates, Ember users Handlebars.js, and Knockout.js and Angular have their own syntax. With a little bit of work you can swap view engines within these frameworks if you so choose. And it would be here where we could incorporate React to handle the view rendering portion of an application. But, as mentioned above, React is not dependent on any JavaScript framework being in place. It can be used as a standalone aspect of an application almost entirely independent from any other library or environment.

So why go to the trouble to incorporate React? Why not just use a framework’s native rendering engine (if you are using a framework). If you are not using a framework, why not just use something like jQuery to handle your view layer? Again, looking at the React homepage, the following description is provided…

React abstracts away the DOM from you, giving a simpler programming model and better performance. React can also render on the server using Node, and it can power native apps using React Native.

As it turns out there are a number of different positive aspects in terms of performance, scalability, and simplicity that React can provide to application development as it progresses along in both size and complexity. We will explore these in detail as we go forward. As many have noticed, React is a little bit unorthodox from “traditional” JavaScript application development (if there were such a thing) and it can take a little bit of working with it and a little bit of trial and error before many of the benefits of it are fully realized. Indeed, many developers admit that they did not quite “get it” at first and some have even described a substantial initial aversion to some of its implementations. So if you experience this on any level, you are definitely not alone and I would merely invite you to “stick with it” through some of the initial tutorials before you run for the hills screaming in terror. Who knows? You just might be surprised at the end of the day.

Note: For the following discussions want to run our various projects inside of a localhost HTTP web server. If you have a local Apache or IIS setup you may wish to use this by putting the files that you create in the upcoming tutorials in a directory created inside the www folder. Another quick easy implementation is to just pull down the Node.js http-server module by running the following from your command line…

$ npm install -g http-server

From there you can create a directory anywhere you like and run the following…

$ http-server

This will run an HTTP server at localhost:8080. If you got to https://localhost:8080 you should see something there that tells you a server is running.

React is a view rendering JavaScript library that is created and maintained by a team of engineers at Facebook. It is responsible for dynamically handling the visual display of various components within a web site or web application in a flexible, efficient, and interactive manner. What this often means is that React handles the displaying of the data that underlies an application and will dynamically update everything that it needs to in a performance conscious manner when that data changes. We will look at all of React’s various components that come together to make this happen in greater detail as we go along in the upcoming tutorials.

Perhaps the best thing to do is to jump right in and get our first look at React. To start out we will need an index.html file. So create a new file in a directory where you want to run things from and create a file called index.html. In this file place the following code…

<!DOCTYPE html>
<html>
<head>
    <title>React</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>        
    <script src="https://fb.me/react-0.12.2.js"></script>
    <script src="https://fb.me/JSXTransformer-0.12.2.js"></script>

</body>
</html>

So we are first loading up the React library over CDN and we are also loading up something called the “JSXTransformer.” React has its own programming language called JSX. It is React’s own special easy-to-read abstracted syntax that in the end gets converted to native JavaScript. It is important to note that using JSX is optional. It is not required to create React applications and you can write your React components in native JavaScript if you so choose. For a lot of the upcoming examples provided in what is to follow, we will look at the same code written in both JSX and native JavaScript and you can decide which is more appealing to you. We will discuss the pros and cons of leveraging JSX bit later on as well.

Hello World in React

So now that we have React loaded up, let’s write our first React component. We will do the obligatory “Hello World” example that has so ubiquitous throughout programming tutorials since the dawn of time. We are going to personalize this a bit more though and we are going to say “hello” to an individual rather than the entire world.

JSX

So let’s start by looking at the JSX syntax just to get a look at it. Create a folder called “js” and create a file called hello.jsx and include it after the scripts like so…

<!DOCTYPE html>
<html>
<head>
    <title>React</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>        
    <script src="https://fb.me/react-0.12.2.js"></script>
    <script src="https://fb.me/JSXTransformer-0.12.2.js"></script>
    <script type="text/jsx" src="js/hello.jsx"></script>
</body>
</html>

In this file add the following JSX code…

var HelloMessage = React.createClass({
    render: function() {
        return <div>Hello {this.props.name}</div>;
    }
});

React.render(<HelloMessage name="John" />, document.body);

Now let’s open this index.html in your favorite browser in your web server. You should see the message “Hello John” displayed. Congratulations, you have just written your first React component!

React components implement a render() method that takes input data and returns what to display. When we are calling React.render the first argument we are passing in specifies the name of the component to render and the properties that we want to pass in. The second parameter in React.render is a JavaScript object of the element that we want to append our element inside of. Indeed if we use our developer tools to inspect the source, we see our message inside a <div> inside the <body> (with some additional React wrapper elements).

You can play around with this a little bit. Try changing the <div> to a <p> or change the name from John to your own name to see the changes reflected in the code.

JavaScript

So now let’s take a look and see what it would look like to write a React component in native JavaScript. Change the HTML to point to a .js file instead of a .jsx file. We also do not need the JSX Transformer file any more since we are not working with JSX in this instance.

<!DOCTYPE html>
<html>
<head>
    <title>React</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>        
    <script src="https://fb.me/react-0.12.2.js"></script>
    <script type="text/javascript" src="js/hello.js"></script>
</body>
</html>

Create a file called “hello.js” in our “js” folder and in this file place the following code…

var HelloMessage = React.createClass({displayName: "HelloMessage",
    render: function() {
        return React.createElement("div", null, "Hello ", this.props.name);
    }
});

React.render(React.createElement(HelloMessage, {name: "John"}), document.body);

And again, open this index.html file in your favorite browser. We should see the same “Hello John”. So as we can see here, we are doing something similar in that we are still calling React.render, but we need to add some additional code in a couple of places in calling React.createElement. So things are a little bit more verbose in doing things the native JavaScript way, but ultimately this is the code that JSX gets converted to before it runs. So the choice regarding which of these you prefer is really up to you. The differences between the two approaches seem relatively minor, but as your applications grow in both size and complexity JSX can end up being a lot more succinct which can reduce the number of lines of code that you need to write and sort through.

Note too that there are tools that will do the JSX conversion to JavaScript for you. For example, if you copy and paste your components into this online JSX compiler it will be automatically converted to native JavaScript. So it really might be worth your while to take a look at JSX as a solution for developing your applications.

Displaying Data

Let’s try to create a React application that is a little bit more complex. In what follows we will pass a set of data into our React component and iterate through it. Create a new index.html file and add the following code

<!DOCTYPE html>
<html>
<head>
    <title>React</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
        
    <script src="https://fb.me/react-0.12.2.js"></script>
    <script src="https://fb.me/JSXTransformer-0.12.2.js"></script>
    <script type="text/jsx" src="jsx/notes.jsx"></script>  
    <script type="text/jsx" src="jsx/app.jsx"></script>  
	
</body>
</html>

In our “jsx” create a “notes.jsx” file and an “app.jsx” file. In our notes.jsx file add the following code…

var NotesList = React.createClass({
    render: function () {
        var notes = this.props.notepad.notes;
    
        return (
            <div className="note-list">
            {
                notes.map(function (note) {
                    var title = note.title || note.content;
                    var content = (!note.title) ? '' : note.content;
                    return (<div key={note.id} className="note-summary"><h2>{title}</h2><p>{content}</p></div>);
                })
            }
            </div>
        );
    }
});

So here we can see our “NotesList” component. The data that gets passed in to any React component is available on the “props” object. The format goes this.props.attribute where “attribute” is the name of the attribute. So in our example it is called “notepad”. So when we call our render function, it will look like the following…

React.render(<NotesList notepad={notepadObject}/>, document.body);

The value “notepadObject” can be any JavaScript type… a string, object literal, array, or whatever else. We access it inside our component with this.props. So when we say this.props.notepad.notes it means we are expecting notepadObject to have a “notes” property on it. In a production grade application it would probably be best practice to do some checking/error handling against this, but for this simple example we will omit it for now.

Because we are calling the map function on the notes property we are expecting this to be an array. We will iterate through this array and render out a title and some content. If there is no title, we will set the content to the title which is what the tertiary expression handles.

So we can implement this to see what this looks like in practice. So in our app.jsx file we can add the following code…

var notepadObject = {
    notes: [{
        id: 1,
        title: "Eat Breakfast",
        content: "Toast and scrambled eggs would be nice"
    },
    {
         id: 2,
         content: "Walk Dog"
    },
    {
         id: 3,
         title: "Learn React",
         content: "I am making great progress!"
     }]
};

React.render(<NotesList notepad={notepadObject}/>, document.body);

As we expected, our React component takes in a “notepadObject” object that has a “notes” property containing an array of objects. We iterate through the array and display the various values set in each object. For the second one, because there is no title, we just use that as the title. If we run this in our local web server, we can see the results.

Let’s take a quick look at how this would look in native JavaScript. Like with our earlier example, it will be slightly different but still recognizable as to what the code is doing. As before we will load JavaScript instead of JSX.

<!DOCTYPE html>
<html>
<head>
    <title>React</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
        
    <script src="https://fb.me/react-0.12.2.js"></script>
    <script type="text/javascript" src="js/notes.js"></script>  
    <script type="text/javascript" src="js/app.js"></script>  
	
</body>
</html>

Below is the code found in notes.js…

var NotesList = React.createClass({displayName: "NotesList",
    render: function () {
        var notes = this.props.notepad.notes;
    
        return (
            React.createElement("div", {className: "note-list"}, 
            
                notes.map(function (note) {
                    var title = note.title || note.content;
                    var content = (!note.title) ? '' : note.content;
                    return (React.createElement("div", {key: note.id, className: "note-summary"}, React.createElement("h2", null, title), React.createElement("p", null, content)));
                })
            
            )
        );
    }
});

And in app.js

var notepadObject = {
    notes: [
        {
            id: 1,
            title: "Eat Breakfast",
            content: "Toast and scrambled eggs would be nice"
        },
        {
            id: 2,
            content: "Walk Dog"
        },
        {
            id: 3,
            title: "Learn React",
            content: "I am making great progress!"
        },

    ]
};

React.render(React.createElement(NotesList, {notepad: notepadObject}), document.body);

So again here we have a similar but slightly more verbose set of code when we use the native JavaScript as opposed to JSX. If we run this example, the final result is the same.

Summary

So this concludes our very brief and succinct introduction to React. We have only just scratched the surface with some basic rendering of data coming from our React component. In upcoming discussions, we will explore the more complex and more dynamic features that React can give us and we will see where the value of this library really emerges. But our journey has started out with a few small steps that we can build upon from here.

]]>
https://9bitstudios.com/2015/09/introduction-to-react/feed/ 0