Scotch is going to help you learn an awesome library in a really fun way. What could be more fun than making a music app?

Yeah I get it! You have been hearing React thrown around these days but you have had no reason to learn it yet or rather you have tried but it just didn't work. Together we will build a fairly complex but easy to understand music app with React, Soundcloud and Electron which is going to cover everything you need to know about React and its best practices.

It is difficult to convince people to learn a new library or framework and I understand that. I am coming from an Angular background and I consider myself a professional for that matter. For that reason I never considered learning React until I came across this video.

A quick gif:

The working CodePen

A basic knowledge of HTML and JavaScript (ES6) is enough for you to understand this tutorial. On the other hand the only fairly advanced topic you need is an understanding of the mystries of this keyword.

Browserify and Babel:

Browserify helps us use client JS libraries like React and jQuery with Node's require() and makes bundling easy:

Upgrade Your JS Go from vanilla JavaScript 👉 React

Watch for FREE

npm install -g browserify

If you want to learn more abou Browserify, check out Peleke's tutorial

Not all browsers have EcmaScript 2015 (ES6) support, therefore a transpile tool will be needed in such case. JavaScript transpilers are important. here is an article on when and why we use them.

To install Babel (which is the transformer) and its squad of tools called presets , we will include them in our package.json which we will address soon.

We also need to create ./.babelrc file to inform babal which presets we are using:

"presets" : [ "es2015" , "react" ]

Electron

Electron is a tool for building cross platform desktop apps with web technologies. This means that you do not have to learn an OS native language so as to build an app that runs natively on computers. The amazing aspect actually is that you write ones and build the same code for different platforms (OSX, Windows, Linux). We have written an article on Angular and Electron and can learn more from this Jasim's tutorial

Our app is expected to run as a standalone app and not in a browser. Electron is in my opinion the most popular tool for building desktop apps with web technologies (HTML, CSS, JS):

$ git clone https://github.com/electron/electron-quick-start scotch-player $ cd scotch-player

The starter has two important files: main.js and index.html . These files serve as entry to an Electron project.

To see the expected blank workspace, run:

npm start

Directory Structure

Below is the directory structure of what we are building and will serve as guide down the journey:

| ---app | ----components | ------details.component.js | ------footer.component.js | ------player.component.js | ------progress.component.js | ------search.component.js | ----containers | ------app.container.js | ----app.js | ---public | ----css | ------global.css | ----img | ------logo.png | ------soundcloud.png | ----js | ------bundle.js | ---index.html | ---main.js | ---package.json | ---.babelrc

Configure package.json

{ "name" : "scotch-player" , "productName" : "Scotch Player" , "version" : "1.0.0" , "description" : "Scotch Demo Player" , "main" : "main.js" , "scripts" : { "start" : "electron main.js" , "watch" : "watchify app/app.js -t babelify -o public/js/bundle.js --debug --verbose" } , "author" : "Scotch" , "license" : "MIT" , "dependencies" : { "axios" : "^0.9.1" , "babel-preset-es2015" : "^6.6.0" , "babel-preset-react" : "^6.5.0" , "babelify" : "^7.2.0" , "classnames" : "^2.2.3" , "electron-prebuilt" : "^0.36.0" , "electron-reload" : "^0.2.0" , "jquery" : "^2.2.3" , "react" : "^0.14.8" , "react-autocomplete" : "^1.0.0-rc2" , "react-dom" : "^0.14.7" , "react-sound" : "^0.4.0" , "soundmanager2" : "^2.97.20150601-a" } }

Our concerns are the scripts and dependencies section. The scripts has two commands, the firsts ( start ) starts the app and the second ( watch ) tells browserify to watch the app folder and bundle the JS content to public/js/bundle.js

Go ahead and install the dependencies:

npm install

React is really a simple and small library. It only echoes one word, Components . React is simply a UI library that helps web designers/developers build reusable UI components. Reusable from as small as a button to as complex as navigation menus. See Ken's article for more on getting started with React.

A simple component could be:

import React from 'react' ; class Search extends React . Component { render ( ) { return ( < form > < input type = "text" / > < input type = "submit" / > < / form > ) ; } } export default Search

We will see more of that while we build the app. The only weird thing here is the XML-like content in our JavaScript. It is called JSX and just a convenient way to write HTML in JavaScript. You have the option to go hardcore with document.createElement .

A little exception could be made though - components are not just for UIs, they can be used to manage state of UI component. Let's have a deeper look:

Presentation Components

This components are simple and very straightforward. They just present UI details and nothing much. It should never manage state but should only receive properties to be bound to its UI.

Events also are handled as callbacks via properties and not in components.

One more thing, for no reason should a presentation component be aware of how data sent to it came about. It should be possible to isolate it.

A simple example:

import React from 'react' ; class Search extends React . Component { constructor ( props ) { super ( props ) ; this . state = { value : '' } ; } handleSubmit ( ) { postRequest ( this . state . value ) ; } handleChange ( e ) { this . setState ( { value : e . target . value } ) ; } render ( ) { return ( < form onSubmit = { this . handleSubmit . bind ( this ) } > < input type = "text" value = { this . state . value } onChange = { this . handleChange . bind ( this ) } / > < input type = "submit" / > < / form > ) ; } } export default Search

The above example is doing exactly what we do not want a presentation component to do. It knows how values are manipulated and sent to the server. Let's refactor:

import React from 'react' ; class Search extends React . Component { render ( ) { return ( < form onSubmit = { this . props . handleSubmit } > { } < input type = "text" value = { this . props . searchValue } onChange = { this . props . handleChange } / > < input type = "submit" / > < / form > ) ; } }

Now the component is extra lean and is focused on presenting content depending on the values passed to it via this.props . It also handles events with functions passed to it via this.props too. So where do the states and those event handlers go to? They are moved to the container components.

Note on props and states Properties and states join forces to make React an amazing and awesome tool. Properties are just read only values passed from one component to another or a component to its UI elements. Props are accessed with just this.props because they are read only. States on the other hand are writable and that is the way we update our application data (state). States are accessible via this.state and because they are writable, can be updated with this.setState({value: 'value'}) .

Container Components

This works with the concept of service provider . They tend to expose APIs for the presentation components. This is where you can get your hands dirty and do the dirty jobs of updating states and defining application behaviors. This is the guy that takes care of all those jobs we asked presentation components to drop.

To better understand container components, let us have a look at one that compliments our above Search Component :

import React from 'react' ; import Search from './search' ; class AppContainer extends React . Component { constructor ( props ) { super ( props ) ; this . state = { value : '' } ; } handleSubmit ( ) { postRequest ( this . state . value ) ; } handleChange ( e ) { this . setState ( { value : e . target . value } ) ; } render ( ) { return ( < Search handleSubmit = { this . handleSubmit . bind ( this ) } handleChange = { this . handleChange . bind ( this ) } searchValue = { this . state . value } / > ) ; } } export default AppComponent

See how the above component abstracts the state update and event handling from the presentation component. Once an event is called on the presentation component, it asks its parent container component to handle the event and if any change in state, pass it back.

Do not panic, we learn better with examples and there are few examples in the demo we will talk about.

It is very simple to use React in an Electron project. You can bundle with Browserify or Webpack but in our case we will use browserify. The following checklist is good for setting React in any platform including Electron:

Install Browserify: [✔] Install Babel: [✔] Configure Babel presets using package.json or .babelrc : [✔] Add a watch script to package.json : [✔] Create a component and render it to the index.html Run start and watch scripts to start Electron and bundling respectively

As you can see, we have accomplished 1 to 4 and that is why they are checked. Let us have a look at 5 and 6.

Create app.js in the app folder as shown in the directory structure with the following:

import React from 'react' ; import ReactDOM from 'react-dom' ; class Search extends React . Component { render ( ) { return ( < form > < input type = "text" / > < input type = "submit" / > < / form > ) ; } } ReactDOM . render ( < Search / > , document . getElementById ( 'content' ) ) ;

Something new is ReactDOM which is used to render components to the DOM. The index.html in our case:

<!DOCTYPE html> < html > < head > < meta charset = " UTF-8 " > < title > Scotch Player </ title > </ head > < body > < div id = " content " > </ div > < script src = " public/js/bundle.js " > </ script > </ body > </ html >

We are pointing to a non existing file, bundle.js . It will contain our bundled app therefore create the file and leave it empty then run:

npm run watch

Browserify comes with two flavors: browserify and watchify . The difference is that watchify just waites for change and re-creates the bundle while browserify bundles only when you issue the command.

It is painful to continue running npm start for every change just to update Electron with the changes. We can automate it by adding the following in the main.js :

require ( 'electron-reload' ) ( __dirname ) ;

We already install the package using package.json .

Hopefully, you have a fair knowledge of React, how it is useful, and the two types components. If you need more on component types Dan's Medium post will help. In the next tutorial, we will design our presentation components. See you then...

Like this article? Follow @codebeast on Twitter