React Basics

CSCI-UA.0480-008

React

React, by itself, is a library for generating the user interface of an application.

  • it's essentially the view in an MVC app
  • it provides an API for creating and rendering reusable view components
    • including state management
    • …and event handling

React (Again)

What did all of that mean? What functionality does React actually give us? It's actually pretty similar to what we've been doing with vanilla client side JavaScript:

  • manipulate the DOM (well, indirectly, via a virtual DOM)
  • work with events
  • changing the DOM based on state

Getting Started

We can use jsbin or codepen to learn the React API.

  • for codepen:
    • set Babel as the JavaScript preprocessor
    • add the react library as external JavaScript
    • add the react DOM library as external JavaScript
  • for jsbin:
    • use Add Library to add react
    • select JSX (React) in the JavaScript drop down

From there, you can use the React object in your JavaScript as your entry point to the React API.

Render an Element

First… let's try something that should look really familiar. What do you think this code will do?


ReactDOM.render(
    React.createElement('div', {className: 'foo'}, 'Hey... familiar!'), 
	document.body
);
  • create a div with class="foo"
  • the div will have "Hey… familiar!" as text content
  • …and the whole div will be rendered into the body (react components are usually rendered into another containing element, not just document.body)

A Bit More About createElement and render

React.createElement:

  • first parameter… element that you want to create as a string
  • second parameter… its attributes (note className instead of class)
  • third parameter… its text content
  • it'll return a ReactElement object


ReactDOM.render

  • first parameter… element
  • second parameter… insertion point (where to add element as a child)

Another Way to Render an Element

Let's try this…


ReactDOM.render(
	
Um, whut?
, document.body );

Another Way Explained….

What looks strange about this code?


ReactDOM.render(
	
Um, whut?
, document.body );

It looks like there's an unquoted string of markup in the JavaScript!

JSX

JSX is an extension to JavaScript syntax that allows XML-like syntax without all of the fussy quoting!

  • JSX is not a templating language
  • you can think of it as a preprocessor
    • it takes in JavaScript with JSX syntax
    • and compiles JSX to plain vanilla JavaScript
  • you don't have to use JSX with React, but it seems to be a common practice

JSX Continued

So that means… this JSX


Um, whut?

…is equivalent to this vanilla JavaScript


React.createElement('div', {className: 'foo'}, 'Um, whut?'), 

They both produce a ReactElement!

Why JSX

Er. Didn't we spend half of the semester separating our HTML from JavaScript? Why is JSX the standard? Did the react devs pull a prank on us?

  • mainly because it's familiar (no need to remember another API)
  • it can be more concise than using the regular API (less code!)

Components

You can bundle elements together into a single component. Here's an example.


var MyComponent = React.createClass({
  render: function() {
    return (
      

A Message

{this.props.message}
); } });

ReactDOM.render(
  <MyComponent message="Hi there!" />,
  document.getElementById('root');
);
// assuming element with id="root"

Alternatives for Defining Components

Using shorthand method definitions:


const MyComponent = React.createClass({
    render() {
        return(
            

A Message

{this.props.message}
); } });

Using ES6 Classes

You can also use ES6 classes to create components by extending React.Component


class MyComponent extends React.Component {
    render() {
        return (
            

A Message

{this.props.message}
); } }

Components and Props

To make a component, use React.createClass, which takes an object as a parameter.

  • you must define a render property in the object, and that property should be a function that returns/generates elements
  • note that a component variable must start with uppercase
  • once you have a component, you can pass it to render using JSX, with the variable name as the tag name
  • you can access attributes defined in JSX via this.props in your component
  • use curly braces to add the result of a javascript expression into JSX

Too Many Greetings

Let's try to create a component that…

  • displays "hello" some number of times in a div
  • however, when creating the component with JSX, you can add an attribute called times that will specify the number of times "hello" should be repeated in the div


For example… rendering…


<MyComponent times="5" />,

Gives us


hello hello hello hello hello

Too Many Greetings


const MyComponent = React.createClass({
  render: function() {
    var text = "";
    for(var i = 0; i < this.props.times; i++) {
      text += "hello ";
    }
    return (
      
{text}
) } });

ReactDOM.render(
  <MyComponent times="5" />,
  document.body
);

A Bit About Looping

What if we wanted to surround our hello with markup and add a number?


const Greeting = React.createClass({
  render: function() {
    const paragraphs = [];
    for(let i = 0; i < this.props.times; i++) {
      paragraphs.push(<p key={i} >hello {i}</p>);
    }
    return (
      
{paragraphs}
); } });
  • it turns out that you can render a list of elements (but you have to wrap it in a containing single element)
  • in the example above, we generate a few paragraph elements
  • a render a div that contains all of those elements by dropping the Array in curly braces

Using Map

It's also pretty common to use map to generate elements.

  • in the example below…
  • map creates an Array of paragraph elements
  • that is nested within a div



const Greeting = React.createClass({
  render: function() {
    const greetings = ['hi', 'hello', 'hola'];
    const greetingElements = greetings.map((g, i) => {
        <p key={i}>{g}</p>
    });
    return (
      
{greetingElements}
); } });

Keys

Hey - did you notice that weird key attribute in both examples in the previous slides?


for(let i = 0; i < this.props.times; i++) {
  paragraphs.push(<p key={i} >hello {i}</p>);
}

const greetingElements = greetings.map((g, i) => {
    <p key={i}>{g}</p>
});

When adding an Array of elements, the key attribute should be defined so that React can determine DOM changes more easily. Check out the [details on why to use keys] (https://facebook.github.io/react/docs/reconciliation.html#recursing-on-children), and an in-depth article on Arrays and keys.

Arrays in React Elements

When adding an Array of elements to a component, you must keep the following things in mind…

  1. when defining render, only one react element can be returned, but you can have multiple elements nested within that initial element
    
    return (
     
    only one element

    but you can nest!

    );
  2. a common pattern add an Array of elements is to use map
  3. …but regardless of which method you use to generate an Array of elements, add a key attribute to each element!

Events

To add an event handler in JSX… add an inline attribute (wait, what!?). For example, click events would be represented by onClick:


const MyButton = React.createClass({
  onButtonClick: function(evt) {
    alert("OMG! OMG!");
  },

  render: function() {
    return <div onClick={this.onButtonClick}>Press This Button</div>;
  }
});

ReactDOM.render(
  <MyButton />,
  document.body
)

Callbacks, ES6 Classes, and this (Again!)

If you're using ES6 classes and want to use this in your click handler, remember to bind to this (or use arrow functions)

Here's an alert that uses this.props:


onButtonClick: function(evt) {
  alert(this.props.someProp);
},

To enable the above code access this, though, bind it when you assign the callback function for onClick.


render: function() {
    return <div onClick={this.onButtonClick.bind(this)}>Press This Button</div>;
}

We'll see more about this later on…

Resources