Introduction to React


Why do we even want React?

Innovative Solutions and Technologies Center(ISTC)

Yerevan, Armenia

By Edgar Aroutiounian, Summer 2017

Progress:

What the browser gives us


The web browser provides us with an environment to run our JavaScript code, of course we have the standard JavaScript objects like Array, Date, but the browser also provides many more APIs, collectively this is called the DOM API, where DOM stands for Document Object Model

Many of the objects and functions that the DOM provides we will use in the front end of our web applications, for example here we used fetch, Headers, URLSearchParams and document; all four are provided by the DOM API and not by the JavaScript language.

// function to get new data, remember that fetch returns a Promise
fetch('/login', {
  method: 'post',
  headers: new Headers({
    'Content-Type': 'application/json',
    Accept: 'Content-Type': 'application/json'
  }),
  body: JSON.stringify({username: 'barev', password: 'dzez'})
});
// object that helps us extract query parameters from a string, can be used as:
const params = new URLSearchParams(document.location.search)

What about making elements


Sometimes though using the DOM APIs directly is tedious and error prone. for example, the API for controling and adding elements to the UI, things like document.createElement

const elem = document.createElement('p');
elem.textContent = 'Hello world';
document.body.appendChild(elem);

Of course we can build applications using the raw DOM API for making HTML element but the DOM API for creating elements is better not touched at all and instead we use JavaScript libraries.

Getting started with React project


Getting started with React used to be a bit harder as you had to deal with tools like webpack and babel. However now it is much easier and we will use yarn, the new JavaScript package manager. Install yarn on your respective platform as described here:

https://yarnpkg.com/lang/en/docs/install/

once you have yarn installed, you can make a new React project by doing:

$ yarn create react-app istc_web_app

where istc_web_app can be whatever name you want for your project.

now after cd into the project directory, we can start the project by running

$ yarn start

That will start a local development server, it will open a browser for you and tell you in the terminal what is the location of the server.

Model of React (Jargon)


First it is important to note that React just by itself is a library for making UI, it is the view layer of our application. React does not reimplement the browser environment the way that other libraries like Angular do, instead it emphasises using plain JavaScript idioms.

Because React is just a view library, you can integrate it into existing projects, like existing Angular, Backbone or whatever project. Often though we will pair React with other libraries, usually react-router for handling routing and redux or mobx for state management and some library to help us with CSS styling

In the Web version, React creates an abstraction layer for us over the DOM. We create something called 'Components' and these Components collectively create a tree that represents the UI.

The great thing about React is that it does not assume the existence of the DOM and hence we can use our React code on the server side, this lets us render our React components on the server, known as Server Side Rendering (SSR)

Components (JSX)


React uses a special syntax extension to JavaScript called JSX. JSX looks like HTML but it is not, it is a syntax transformation that is changed into React function calls

// We must have this import for JSX to work
import React from 'react';
class Header extends React.Component {
  render() {
    return (
      <section><h3>Hello World</h3></section>
    );
  }
}

And that is the same as

render() {
  return (
    React.createElement('section', {},
      React.createElement('h3', {}, 'Hello World'));
  );
}

JSX, a more complicated example


render() {
  const s = { backgroundColor:'red' };
  const header_s = { fontSize: '1rem' };
  return (
    <section style={s}>
      <h3 style={header_s}>Hello World</h3>
    </section>
  );
}

again, same as

render() {
  const s = { backgroundColor:'red' };
  const header_s = { fontSize: '1rem' };
  return (
    React.createElement('section', {style: { backgroundColor:'red' }},
      React.createElement('h3', {style: { fontSize: '1rem' }}, 'Hello World'))
  );
}

What's the point of JSX?


You can see that writing JSX is clearer than using the React.createElement function call. This way we can type less and you can 'see' the structure of the UI that you are creating, like the hierarchy and you can reference any JavaScript expression in the JSX, but you need to wrap it with {}

render () {
  const name = 'First name';
  const teacher = 'Edgar';
  return <p> My {name} is {teacher}</p>;
}
https://facebook.github.io/react/docs/introducing-jsx.html

Conditionally render


Sometimes we want to conditionally include a component, there's a few ways to do that but here is one way

render() {
  let content = null;
  if (this.props.showName === true) {
    content = <p>I am {this.props.first_name}</p>;
  } else {
    content = <p>Please provide your name</p>;
  }
  return <div>{content}</div>;
}
https://facebook.github.io/react/docs/jsx-in-depth.html

Component Lifecycles


Notice that we made Components by extending React.Component, why do we do that and what do we get from that?

First notice that we always define a render method. This is because every React component must provide a render method, the render must return something that says how this component must look on the UI, React is a view library afterall.

In general, the lifecycle methods are different hooks in the life of the Component, as it mounts, as it renders, when it receives props, when it unmounts. Implementing a lifecycle method will be your chance to hook onto that event

https://facebook.github.io/react/docs/react-component.html

Example of lifecycle method


One of the most important lifecycle methods is componentDidMount

import React from 'react';

class Profile extends React.Component {
  // CDM is also a place to put a call to fetch
  componentDidMount() {
    console.log('Component successfully mounted into DOM');
  }
  render() {
    return <p>I am {this.props.name}</p>;
  }
}

Look at the other lifecycle methods, not each of them run on the server side. For example CDM does not run on the server side, but componentWillMount does run on the server side.

Assignment: Implement each of the lifecycle methods, add a console.log there so that you see the order of lifecycle methods being called

Event handling


We can handle events as well with methods

class Header extends React.Component {
  constructor() {
    super();
    this.click_handler = this.click_handler.bind(this);
  }
  click_handler(e) { console.log(e.target.value); }
  render() {
    return (
      <div>
        <input type={'button'} value={'Hello World'} onPress={this.click_handler} />
      </div>
    );
  }
}

Event handling (Context issues)


Notice that we did

this.click_handler = this.click_handler.bind(this);

This is because ES6 classes do not autobind their context and hence we have to make a new function (Remember that .bind returns a new function) with the context (this) bound to the React Component

We don't have this problem is we use fat arrows class properties because class properties, as we have shown in lecture one, are really shortcuts for making properties on the instance itself

class Header extends React.Component {

  click_handler = e => {
    console.log(e.target.value);
  }
}

Using Components in other Components


We saw that the render method must give back a UI element, but we can also give back custom components that we make. React will just recursively ask each Component how it looks like, aka calling that Component's render method

class ShoppingItem extends React.Component {
  render() {
    return <p style={{backgroundColor:'aliceblue'}}>This is a shopping Item</p>;
  }
}
class Cart extends React.Component {
  render() {
    return (
    <div>
      <ShoppingItem/>
      <ShoppingItem/>
    </div>
    );
   }
}

Using Components in other Components cont...


Notice, to use custom Components as elements to render in another Component's render function, that Component must have a capital letter. ShoppingItem, not shoppingItem. This is how React knows whether it is a native HTML element or a custom component.