Build a user interface with React

ECA React - November 28th 2018

Reference: https://codewithmosh.com/

Last time...

  • Modules

  • React, Virtual DOM, JSX

  • Create-react-app Webpack, Babel...

  • Components

Let's continue !

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

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

  /** [...] */

  incrementCount() {
    console.log("Incremented");
  };

  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>
    );
  }
}
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>
    );
  }
}

What happens when State Changes ?

Passing event arguments

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

  /** [...] */

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

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

Composing Components

2

+

-

3

+

-

5

+

-

0

+

-

0

+

-

import React, { Component } from "react";
import PokeCounter from "./pokeCounter";

class PokeCounters extends Component {
  state = {};

  render() {
    return (
        <div>
            <PokeCounter />
            <PokeCounter />
            <PokeCounter />
            <PokeCounter />
            <PokeCounter />
        </div>
    );
  }
}

export default PokeCounters;

pokeCounters.jsx

import React, { Component } from "react";
import PokeCounter from "./pokeCounter";

class PokeCounters extends Component {
  state = {
    counters: [
        { id: 1, count: 0 }
        { id: 2, count: 0 },
        { id: 3, count: 0 },
        { id: 4, count: 0 },
        { id: 5, count: 0 }
    ]
  };

  render() {
    return (
        <div>
            {this.state.counters.map(counter => <PokeCounter key={counter.id}/>)}
        </div>
    );
  }
}

export default PokeCounters;

pokeCounters.jsx

Passing Data to components

  • Data can be passed through attributes

  • <PokeCounter key={counter.id} count={counter.count} anotherAttribute="a value I pass to my component"/>
  • You can then retrieve the data from a plain JavaScript object called props

  • key will not be passed as it is a special keywork used to identify elements in a list

pokeCounter.jsx

import React, { Component } from "react";
import PokeCounter from "./pokeCounter";

class PokeCounters extends Component {
  state = {
    counters: [
        { id: 1, value: 0 }
        { id: 2, value: 0 },
        { id: 3, value: 0 },
        { id: 4, value: 0 },
        { id: 5, value: 0 }
    ]
  };

  render() {
    return (
        <div>
            {this.state.counters.map(counter => 
                <PokeCounter 
                    key={counter.id} 
                    value={counter.value}
                />
            )}
        </div>
    );
  }
}

export default PokeCounters;
import React, { Component } from "react";

class PokeCounter extends Component {
  state = {
    value: this.props.value
  };

  /** [...] */

  incrementCount = () => {
    this.setState({ 
        value: this.state.value + 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>
    );
  }
}

pokeCounters.jsx

  • In case of a complexe element, you can pass data as children props

  • <PokeCounter key={counter.id} count={counter.count}>
    <h1>Hello world</h1>
    </PokeCounter>
  • data is then accessible in props.children

React dev tools

Available in Chrome and Firefox

State

  • Local to the component
  • Other components cannot access it
  • Some components do not need a state object

Props

  • Passed to a component
  • Once passed to the component, it cannot be modified

VS

See you next wednesday!

Build a user interface with React - 2nd part

By Issam Hammi

Build a user interface with React - 2nd part

ECA React - November 28th 2018

  • 549