Intro to:

Presented by Vijay Menon

JavaScriptLA

Join Us On Slack!

http://javascriptla.herokuapp.com for an invite

Quick Note:

Please be sure to sign up for our raffle tonight via this link: http://vijayxtreme.com/randomdrawing

What is React?

  • All new JavaScript framework brought to you by Facebook
  • An architecture that allows you to build websites faster and cleaner, websites that scale
  • Something new and exciting to learn, especially if you want to master ES6 and beyond

Why React?

And why not just use JQuery?

  • Most sites still use "traditional" server-side code with a lot of JQuery on the front-end
    • However this leads to "code bloat" that is difficult to understand and potentially error ridden
    • Modern front-end development requires organization and structured thinking - which can be difficult as well
    • React solves both these problems and is FUN to use!

A Simple Intro

Code Exercise

Our first "Hello World" app

First, let's set up our project:

Here's what we need:

<!DOCTYPE html>
<html>
<head>
	<title>Simple Hello World Website</title>
	<script src="https://npmcdn.com/react@15.3.0/dist/react.min.js"></script>
	<script src="https://npmcdn.com/react-dom@15.3.0/dist/react-dom.min.js"></script>
	<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
</head>
<body>
	<div id="example"></div>


	<script type="text/babel">
		ReactDOM.render(
        	<h1>Hello, world!</h1>,
        	document.getElementById('example')
      	)
	</script>
</body>
</html>

Here's what your code should look like:

Important

And here's what you should see:

So what just happened?

And while you're at it, explain JSX

Here's the scoop:

  • Think of React as a layer between your code, and the actual HTML rendered by JavaScript (aka the DOM)
  • Work with React to create Components, aka "Smart HTML" that can manage itself and update the DOM -- organization & less human error as a result
  • JSX, or JavaScript eXtensive Markup Language is the language of writing components in React using JavaScript (though it feels like HTML ^_^).
  • React is ES6 Compatible!  That makes it more fun to play with, and a great way to up your programmer "value"
<!DOCTYPE html>
<html>
<head>
	<title>Simple Hello World Website</title>
	<script src="https://npmcdn.com/react@15.3.0/dist/react.min.js"></script>
	<script src="https://npmcdn.com/react-dom@15.3.0/dist/react-dom.min.js"></script>
	<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
</head>
<body>
	<div id="example"></div>


	<script type="text/javascript">
	'use strict';

	ReactDOM.render(React.createElement(
	        'h1',
	        null,
	        'Hello, world!'
	), document.getElementById('example'));	
</script>
</body>
</html>

Without JSX, we'd have to write code like this :/

JSX allows us to write neat components using "HTML" like syntax but has super powers and is reusable

Revisiting our code sample:

Let's Get Our Hands Dirty

Project for Tonight:

Building A Simple Movie Search App

So How Do We Get Started?

Any ideas?

Let's start off by using our default project structure (but slightly modify it):

Here's what we need:

  • Text Editor (of course)
  • Command Line
  • Files & folders created:
    • simple_movie_search_react/
      • sass
      • src/
      • src/js/
      • src/index.js
    • index.html 
  • And React!  Plus, we'll install some other cool stuff along the way via NPM & NodeJS

Next, let's install Webpack and some dev dependencies:

Here's what we need:

  • Babel-Core
  • Babel-Loader
  • Babel-Preset-ES2015
  • Babel-Preset-React, Babel-Preset-Stage-1
  • Webpack, Webpack-Dev-Server
  • & Maybe We'll Throw in Gulp, Gulp-SASS

Wait, what's all this random stuff?

Babel? Webpack? Gulp?

Here's the scoop:

You already saw Babel before:

  • ​Babel = JavaScript transformer: Allows you to write JSX & ES6 that gets transpiled down into ES5 aka regular JS
    • ​(The other babel files are definitions that help the translation process)
  • Webpack is a useful dev tool that can "watch" our folder's files and compile everything on the fly!  Plus it comes with a server that can refresh the browser when stuff finishes ("hot loading")
  • Gulp is a popular tool to compile our SASS files to regular CSS

Let's write some React!

import React from 'react'
import ReactDOM from 'react-dom'

ReactDOM.render(
	<h1>Hello World</h1>,
	document.querySelector('.container')
)

src/index.js

<!DOCTYPE html>
<html>
<head>
	<title>Simple Movie Search App</title>
</head>
<body>
	<div class="container"></div>
	<script type="text/javascript" src="bundle.js"></script>
</body>
</html>

index.html

We'll get this from webpack

Note: we're using ES6 this time :)

Ready to compile? Let's use Webpack!

Issues:

  • Just running "webpack" from command line won't do
  • We not only need to point webpack to our src folder and js files, we also need to link the ES6 definitions over to webpack -- so it can translate properly.
  • We'll also update our package.json so we can run webpack & dev-server simply via "npm start"

Here's our output via "npm start":

Notice the dev server =)

Onto the Build Phase

Now That Our Dev Environment is Set

Back to This:

How Do We Organize This Into Code?

Let's Break This Diagram Up

Into Components:

App

Search Form

MovieListing

MovieListings

Next:

Let's write these components in React

Here's what we need:

  • Need:
    • App.js
    • SearchForm.js
    • MovieListings.js
    • MovieListing.js
import React, { Component } from 'react'

import SearchForm from './searchform'
import MovieListings from './movielistings'

export default class App extends Component {
	render(){
		return (
			<div className="app">
                                <h1>Search for Movies</h1>
				<SearchForm />
				<MovieListings />
			</div>
		)
	}
}
import React, { Component } from 'react'

export default class SearchForm extends Component {
	render(){
		return (
			<div>I am the search form</div>
		)
	}
}

src/js/app.js

src/js/searchform.js

We need to wrap up our components or React will throw an error

import React, { Component } from 'react'

export default class MovieListings extends Component {
	render(){
		return (
			<div>I am the movie listings</div>
		)
	}
}
import React, { Component } from 'react'

export default class SearchForm extends Component {
	render(){
		return (
			<div>I am the search form</div>
		)
	}
}

src/js/movielistings.js

src/js/movielisting.js

Here's our output via "npm start":

Starting to see a pattern yet?

Build Each Component

Let's Start With the Search Form Component:

import React, { Component } from 'react'

export default class SearchForm extends Component {
	render(){
	    return (
		<div className="searchform">
		    <form>
			<input type="text" placeholder="Search Movies" />
			<input type="submit" value="Submit" />
		    </form>
		</div>
	    )
    }
}

src/js/searchform.js

Also, let's create a sass file & use gulp to create our default style.css which we'll link in index.html

 

Center the app with your stylesheet

Next, let's build the movielistings as a table

import React, { Component } from 'react'

import MovieListing from './movielisting'

export default class MovieListings extends Component {
	render(){
		return (
			<div className="movielistings">
				<table>
					<thead>
						<tr>
							<th>Poster</th>
							<th>Title</th>
							<th>Year</th>
						</tr>
					</thead>
					<tbody>
						<MovieListing />
					</tbody>
				</table>
			</div>
		)
	}
}

src/js/movielistings.js

Again, fix styles if needed and gulp

Now, let's build the movielisting as a table row

import React, { Component } from 'react'

export default class MovieListing extends Component {
	render(){
		return (
			<tr className="movielisting">
				<td>
					<p><img src="" />Poster</p>
				</td>
				<td>
					<p>Title</p>
				</td>
				<td>
					<p>Year</p>
				</td>
			</tr>
		)
	}
}

src/js/movielisting.js

Fix styles if needed and gulp

Wire up the components

Our components are looking good, but currently they don't do anything other than look pretty

Next we need to:

  • On submit, get some data -- from where?
  • Hook our results into our application's "state" 
  • Use application "state" to send information to our components:
    • whenever state changes, we re-render 
  • We'll discuss this.props while we are at it =)

Back to searchform.js

src/js/searchform.js

export default class SearchForm extends Component {
	constructor(props){
		super(props)
                this.state = {
                    term: ''
                }
		//without binding, our this value would be the div not the component
		this.handleSubmit = this.handleSubmit.bind(this);
	}


	handleSubmit(e){
		e.preventDefault();
		console.log('submitted the form');
	}

	render(){
		return (
			<div className="searchform">
				<form onSubmit={this.handleSubmit}>
					<input type="text" placeholder="Search Movies" />
					<input type="submit" value="Submit" />
				</form>
			</div>
		)
	}
}

We are instantiating our component here with any properties and their values from parent components aka 'props', as well as use this space to handle any creation of "state" or binding of functions (so their this value is correct and not a DOM element deep somewhere)

Let's also modify app.js to have "state" in its constructor -- again we'll come back to this

src/js/app.js

export default class App extends Component {
	constructor(props){
		super(props)
		
		this.state = {
			movies:[]
		}
	}

	render(){
		return (
			<div className="app">
				<h1>Search for Movies</h1>
				<SearchForm />
				<MovieListings movies={this.state.movies}/>
			</div>
		)
	}
}

Let's try the app out now:

Does it work for you? If not, check your code, you might have a typo somewhere

Let's also get the actual input value from our searchform, and then set it on our searchform's state object for "term".   We'll then submit "term" to our App Component, which will handle the AJAX call.

import React, { Component } from 'react'

export default class SearchForm extends Component {
	constructor(props){
		super(props)
		this.state = {
			term: ''
		}

		//without binding, our this value would be the div not the component
		this.updateTerm = this.updateTerm.bind(this);
		this.handleSubmit = this.handleSubmit.bind(this);
	}
	updateTerm(e){
		let term = e.target.value;
		console.log(term)
		this.setState({term:term})
	}

	handleSubmit(e){
		e.preventDefault();
		console.log('submitted the form', this.state.term);
	}

	render(){
		return (
	     <div className="searchform">
	        <form onSubmit={this.handleSubmit}>
		<input type="text" placeholder="Search Movies" onChange={this.updateTerm} 
                value={this.state.term}/>   			    
                <input type="submit" value="Submit" />
		</form>
	    </div>
		)
	}
}

src/js/searchform.js

Your Output Now:

From searchform.js, let's send up our input term submitted (available through this.props.onSubmit)

handleSubmit(e){
	e.preventDefault();
	console.log('submitted the form', this.state.term);
	this.props.onSubmit(this.state.term);
}

src/js/searchform.js

In app.js, let's create a property called onSubmit, that will be available to searchform (via this.props)

<SearchForm onSubmit={this.findMovies}/>

src/js/app.js

this.props allows components to access parent component properties and methods, through a 'property' on itself which can be useful as seen here.  It's not quite 'state', because state is actual data, that changes with time -- and based on change, re-renders the application.

We also need to write the findMovies method in our App component

constructor(props){
		super(props)

		this.state = {
			movies:[]
		}
		//don't forget to bind our findMovies function to our component
		this.findMovies = this.findMovies.bind(this);
	}
	findMovies(term){
		let url=`http://www.omdbapi.com/?s=${term}&r=json`;

		$.ajax({
	     	url:url,
	     	dataType:'json',
	     	cache:false,
	     	success:function(results){
	     		console.log(results)
	     		let movies = results.Search
	     		this.setState({movies:movies});
	     		console.log(this.state.movies);
	     	}.bind(this),
	     	error:function(xhr, status, err){
	     		console.error(status, err.toString());
	     	}.bind(this)
	    });
	}

Your Output Now:

Almost Done!

Pass the state to the MovieListings & MovieListing components

render(){
    let movies = this.props.movies.map((movie) => {
	if(movie.Poster == undefined){
		return 
	}
	return (
		<MovieListing poster={movie.Poster} 
                    title={movie.Title} year={movie.Year} key={movie.imdbID}/>
	)
    })

src/js/movielistings.js

<tbody>
    {movies}
</tbody>

Let's edit our MovieListings component to utilize the 'movies' props filled now with movies from our AJAX call at the App level.  

Using a "fat arrow function" (from ES6) aka anonymous function, we can create a new array of MovieListing components anytime state changes (e.g. we do a new search) that will then get passed to the table below.

Once the components are created, React will always recreate the view for us!

src/js/movielisting.js

One last step! Update MovieListing so it also can access each property given to it via this.props upon its creation in MovieListings.

import React, { Component } from 'react'

export default class MovieListing extends Component {
	render(){
		return (
			<tr className="movielisting">
				<td>
					<p><img src={this.props.poster} /></p>
				</td>
				<td>
					<p>{this.props.title}</p>
				</td>
				<td>
					<p>{this.props.year}</p>
				</td>
			</tr>
		)
	}
}

Your Output Now:

Congratulations! If you made it this far, you are a React hero :)

Where Do We Go From Here?

Try It Again -- This Time Yourself!

Summary & Overview

 

  • React is about code organization 
    • Our code is highly organized, we know what each component does now
    • Because it's organized, mistakes are easier to track down
       
  • Move away from just writing your apps in JQuery only -- sure it might be the easy way out, but it will definitely cause problems when trying to scale.
    • Components allow us to write HTML & JS once, that will just work no matter how many times we reuse it -- can you say the same for copying and pasting a bunch of raw HTML and JQuery?
       
  • React is about FUN, sure it's tough at first -- but once you nail it down, you'll always think smarter about real app development.  
    • In fact, if you master this, you can do real app development with React Native, a library that turns your code into Swift and Java (for iOS and Android)

Next Steps:

  • Try to create your own React app!  
  • Or just improve the movie app we made today -- you could:
    • Add more columns and data from the omdbAPI
    • Add more filters to the search component
    • Find mistakes in my code and submit a pull request -- I put this presentation together on a lot of missed sleep :P
  • Here's a link to my github and the repo for my Movie App, as well as today's slides:
  • Lost?  Hit me up or any of our developer friends on our JavaScriptLA Slack channel -- a great way to stay in touch, ask more questions and learn even though the meetup's over. 

Additional Resources

A Huge Thank You

  • A BIG THANK YOU to General Assembly today for helping us put this presentation together!
  • Finally, thank YOU THE AUDIENCE for making this our biggest MEETUP ever -- over 110 RSVPS!
  • And oh, one more thing...
    • ​We have a raffle!  Hang around, if you hear your name or email called, you are a winner for one of our giveaways!

Until The Next Meetup!

Stay tuned for Part II (React & Redux)

Intro to React

By JavaScriptLA

Intro to React

A simple intro to React for JavaScript learners

  • 3,632