Web Apps With React.js

Mantas Kaveckas

Senior Software Engineer

The Internet is a global system of interconnected computer networks that use the Internet protocol suite (TCP/IP) to link several billion devices worldwide.

What is The Internet?

How Does The Internet Work?

How Does The Internet Work?

Simplified Version

HTTP - The Hypertext Transfer Protocol (HTTP) is an application protocol for distributed, collaborative, hypermedia information systems. HTTP is the foundation of data communication for the World Wide Web.

HTTP/Networks

The Definition

HTTP/Networks

Going Deeper

Text

A web browser (commonly referred to as a browser) is a software application for retrieving, presenting, and traversing information resources on the World Wide Web.

Web Browsers

The Definition

Web Browsers

The Glue Between The User & The Website

Web Browsers

The Glue Between The User & The Website

What is Front-End Development?

Front-end web development, also known as client-side development is the practice of producing HTML, CSS and JavaScript for a website or Web Application so that a user can see and interact with them directly.

Text

What is Front-End Development?

What is Front-End Development?

Text

HTML

Hyper Text Markup Language

Text

CSS

Cascading Style Sheets

Text

CSS

Cascading Style Sheets

JavaScript

JavaScript is the programming language of HTML and the Web.

JavaScript

  • Creates Interactivity (click, drag, swipe, etc.)
  • Communicates with Backend (PHP, Java, etc.)
  • Manages User Behaviour (form, input changes)
  • Embedded into HTML (via <script> tag)
  • Interpreted Language (no compilation required)

JavaScript

Most Popular Programming Language In The World

JavaScript vs. HTML & CSS

JavaScript vs. HTML & CSS

JavaScript vs. HTML & CSS

Frameworks & Libraries

More Frameworks & Libraries

But Different in Some Way...

And Lots More...

More Frameworks & Libraries

There's No One Best...

Single Page Applications (SPA)

Single page apps are distinguished by their ability to redraw any part of the UI without requiring a server roundtrip to retrieve HTML.

Single Page Applications (SPA)

Single Page Applications (SPA)

Single Page Applications (SPA)

But Why?

  • Better User Experience (UX)
  • More like Native Mobile or Desktop App
  • Communicate with Back-End servers without doing a full page refresh
  • Rich Interactions

Single Page Applications (SPA)

Why Not? Cons.

  • The browser does most of the heavy lifting, which means performance can be a problem — especially on less capable mobile devices.
  • Hard to do Search Engine Optimization (SEO) so your content can be discoverable by search engines and social media websites that provide a link preview.

React.js

React.js

Why?

  • Declarative
  • Component-Based
  • Learn Once, Write Anywhere

React.js

Widely Used

React.js

A Simple Component

class HelloMessage extends React.Component {
  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

ReactDOM.render(<HelloMessage name="Jane" />, mountNode);

React.js

A Stateful Component

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {secondsElapsed: 0};
  }

  tick() {
    this.setState((prevState) => ({
      secondsElapsed: prevState.secondsElapsed + 1
    }));
  }

  componentDidMount() {
    this.interval = setInterval(() => this.tick(), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return (
      <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
    );
  }
}

ReactDOM.render(<Timer />, mountNode);

Installation

React.js

Installation

npm install -g create-react-app
create-react-app my-app

cd my-app
npm start

Using Node.js & npm:

React.js

Installation

<script src="https://unpkg.com/react@15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>

Using CDN:

Hello World

React.js

Hello World

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);

JSX

React.js

JSX

const element = <h1>Hello, world!</h1>;

React.js

Embedding Expressions in JSX

function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};

const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);

ReactDOM.render(
  element,
  document.getElementById('root')
);

React.js

JSX is an Expression Too

function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

React.js

Specifying Attributes with JSX

const element = <div tabIndex="0"></div>;
const element = <img src={user.avatarUrl}></img>;

React.js

Specifying Children with JSX

const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

React.js

JSX Prevents Injection Attacks

const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;

React.js

JSX Represents Objects

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

React.js

JSX Represents Objects

React.js

JSX Represents Objects

// Note: this structure is simplified
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world'
  }
};

React.createElement() performs a few checks to help you write bug-free code but essentially it creates an object like this:

Rendering Elements

React.js

Rendering Elements

<!DOCTYPE html>
<html>
    <head>
    <title>Page Title</title>
    </head>
<body>

    <div id="root">
        <!-- This element's contents will be replaced with your component. -->
    </div>

</body>
</html>
const element = <h1>Hello, world</h1>;
ReactDOM.render(
  element,
  document.getElementById('root')
);

React.js

Updating the Rendered Element

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

It calls ReactDOM.render() every second from a setInterval() callback.

React.js

React Only Updates What's Necessary

Components and Props

React.js

Functional and Class Components

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

React.js

Functional and Class Components

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

React.js

Functional and Class Components

React.js

Rendering a Component

const element = <div />;

Previously, we only encountered React elements that represent DOM tags:

const element = <Welcome name="Sara" />;

However, elements can also represent user-defined components:

React.js

Component Props

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

When React sees an element representing a user-defined component, it passes JSX attributes to this component as a single object. We call this object "props".

React.js

Composing Components

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

State and Lifecycle

React.js

State and Lifecycle

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

Consider the ticking clock example from one of the previous sections. So far we have only learned one way to update the UI.

React.js

State and Lifecycle

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

We can start by encapsulating how the clock looks:

React.js

State and Lifecycle

However, it misses a crucial requirement: the fact that the Clock sets up a timer and updates the UI every second should be an implementation detail of the Clock.

React.js

State and Lifecycle

Ideally we want to write this once and have the Clock update itself:

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

React.js

State and Lifecycle

State and Lifecycle is only available for Component Classes.

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

React.js

Adding Local State to a Class

1) Replace this.props.date with this.state.date in the render() method:

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

React.js

Adding Local State to a Class

2) Add a class constructor that assigns the initial this.state:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

React.js

Adding Local State to a Class

3) Remove the date prop from the <Clock /> element:

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

React.js

Adding Local State to a Class

The result looks like this:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

React.js

Adding Lifecycle Methods to a Class

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {

  }

  componentWillUnmount() {

  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

React.js

Adding Lifecycle Methods to a Class

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

The componentDidMount() hook runs after the component output has been rendered to the DOM. This is a good place to set up a timer:

React.js

Adding Lifecycle Methods to a Class

componentWillUnmount() {
    clearInterval(this.timerID);
}

We will tear down the timer in the componentWillUnmount() lifecycle hook:

React.js

Adding Lifecycle Methods to a Class

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

Finally, we will implement the tick() method that runs every second.

Handling Events

React.js

Handling Events

<button onClick={activateLasers}>
  Activate Lasers
</button>

React.js

Handling Events

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

Conditional Rendering

React.js

Conditional Rendering

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
  );
}

Lists and Keys

React.js

Lists and Keys

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);

Rendering Multiple Components

React.js

Lists and Keys

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

Basic List Component

React.js

Lists and Keys

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);

Keys should be given to the elements inside the array to give the elements a stable identity:

Component Composition

Thank You!

Questions?

CodinGame @ .NFQ

https://www.eventbrite.com/e/codingame-nfq-tickets-33809316576

  • Vieta: NFQ ofisas, Brastos g. 15, Kaunas
  • Laikas: Gegužės 13 d. 10 val. (trukmė 5 val.)
  • Registruokis iki gegužės 5 d. (vietų skaičius ribotas)

Web aplikacijų kūrimas naudojant React ir Redux

By Mantas Kaveckas

Web aplikacijų kūrimas naudojant React ir Redux

  • 952