Build a user interface with React

ECA React - November 21th 2018

Reference: https://codewithmosh.com/

What is React?

  • A library to build user interfaces

  • Facebook

  • Component-based

  • Popular

What is a component?

A component is a part of the UI

Root

Search

bar

Filters

Houses list

House

Description

Price

import React, { Component } from 'react'

class House extends Component {
    state = { }
    render() { 

    }
}

React Element

What is the virtual DOM?

  • "Virtual" representation of a UI kept in memory

  • Synced with the "real" DOM by ReactDOM

Real DOM

Virtual DOM

DOM Element

React Element

React

reacts to change

Tools

Must Have extensions

  • Simple react snippets

  • Prettier

Create React App

  • One Dependency: There is just one build dependency. It uses Webpack, Babel, ESLint, and other amazing projects

  • No Configuration Required

  • No Lock-In: You can “eject” to a custom setup at any time

├── node_modules/     # Installed necessary packages 
├── public/           # Static files
│   ├── favicon.ico
│   └── index.html
├── src/              # Application root
│   ├── components/   # Application components
│   │   ├── board.js
│   │   ├── game.js
│   │   └── square.js
│   ├── index.css
│   ├── index.js
│   ├── logo.svg
│   └── utils/        # Utility files
│       └── index.js
├── package.json
├── README.md
└── yarn.lock

4 directories, 12 files
 # Configuration files for Jest & Webpack
 # Polyfills for Promises and Object.assign()
 ├── config/
 │   ├── env.js
 │   ├── jest/
 │   │   ├── cssTransform.js
 │   │   └── fileTransform.js
 │   ├── paths.js
 │   ├── polyfills.js
 │   ├── webpack.config.dev.js
 │   └── webpack.config.prod.js
 ├── node_modules/     # Installed packages necessary for Create-React-App
 ├── package.json
 ├── public/
 │   ├── favicon.ico
 │   └── index.html
 ├── scripts/          # Exposed React Scripts
 │   ├── build.js
 │   ├── start.js
 │   └── test.js
 ├── src/
 │   ├── components/
 │   │   ├── board.js
 │   │   ├── game.js
 │   │   └── square.js
 │   ├── index.css
 │   ├── index.js
 │   ├── logo.svg
 │   └── utils/
 │       └── index.js
 └── yarn.lock

8 directories, 21 files

Practice time!

"Hello World"

import React from "react";
import ReactDOM from "react-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import PokeCounter from "./components/pokeCounter";

ReactDOM.render(<PokeCounter />, document.getElementById("root"));

index.js

import React, { Component } from "react";

class PokeCounter extends Component {
  render() {
    return <h1>Hello World</h1>;
  }
}

export default PokeCounter;

pokeCounter.jsx

Multiple children

import React, { Component } from "react";

class PokeCounter extends Component {
  render() {
    return (
      <React.Fragment>
        <h1>Hello World</h1>
        <button>Increment</button>
      </React.Fragment>
    );
  }
}

export default PokeCounter;

Necessary to have a parent element!

Embedding expressions

import React, { Component } from "react";

class PokeCounter extends Component {
  state = {
    count: 1
  };

  formatCount() {
    return this.state.count === 0 ? "Zero" : this.state.count;
  }

  render() {
    return (
      <React.Fragment>
        <h1>{this.formatCount()}</h1>
        <button>Increment</button>
      </React.Fragment>
    );
  }
}

export default PokeCounter;

Setting attributes

class PokeCounter extends Component {
  state = {
    count: 1
  };

  formatCount() {
    return this.state.count === 0 ? "Zero" : this.state.count;
  }

  render() {
    return (
      <React.Fragment>
        <span className="badge badge-primary m-2" style={{ fontSize: 20 }}>
          {this.formatCount()}
        </span>
        <button className="btn btn-secondary btn-sm">Increment</button>
      </React.Fragment>
    );
  }
}

Rendering classes dynamically

class PokeCounter extends Component {
  state = {
    count: 1
  };

  formatCount() {
    return this.state.count === 0 ? "Zero" : this.state.count;
  }

  getBadgesClasses() {
    let classes = "badge m-2 badge-";
    classes += this.state.count === 0 ? "warning" : "primary";
    return classes;
  }

  render() {
    return (
      <React.Fragment>
        <span className={this.getBadgesClasses()}>{this.formatCount()}</span>
        <button className="btn btn-secondary btn-sm">Increment</button>
      </React.Fragment>
    );
  }
}

Rendering lists

class PokeCounter extends Component {
  state = {
    tags: ["tag1", "tag2", "tag3"]
  };

  render() {
    return (
      <React.Fragment>
        <ul>
          {this.state.tags.map(tag => (
            <li key={tag}>{tag}</li>
          ))}
        </ul>
      </React.Fragment>
    );
  }
}

Conditional rendering

class PokeCounter extends Component {
  state = {
    tags: ["tag1", "tag2", "tag3"]
  };

  renderTags() {
    if (this.state.tags.length === 0) {
      return <h1>No element to be rendered</h1>;
    }
    return (
      <ul>
        {this.state.tags.map(tag => (
          <li key={tag}>{tag}</li>
        ))}
      </ul>
    );
  }

  render() {
    return (
      <React.Fragment>
        {this.state.tags.length === 0 && "Please create a new tag"}
        {this.renderTags()}
      </React.Fragment>
    );
  }
}

Handling Events

import React, { Component } from "react";

class PokeCounter extends Component {
  state = {
    count: 1
  };

 /** [...] */

  incrementCount = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <React.Fragment>
        <span className={this.getBadgesClasses()}>{this.formatCount()}</span>
        <button onClick={this.incrementCount} className="btn btn-secondary btn-sm">Increment</button>
      </React.Fragment>
    );
  }
}
export default PokeCounter;

pokeCounter.jsx

React elements have properties that are based

on standard DOM events

See you next wednesday!

Made with Slides.com