Skip to content

Latest commit

 

History

History
574 lines (483 loc) · 13.5 KB

summary.md

File metadata and controls

574 lines (483 loc) · 13.5 KB

Ironhack logo

React Summary

  1. Start a simple React project
  2. JSX
  3. React Components
  4. React Props
  5. React States
  6. React Lifecycle
  7. React Events
  8. React and forms
  9. Conditional rendering
  10. List rendering
  11. React Router
  12. Using Axios with React

Start a simple React project

With Codepen

With your code editor

Commands to launch

$ npm install -g create-react-app # Install globally the `create-react-app` command
$ create-react-app my-app # Create a React project folder "my-app"
$ cd my-app
$ rm -f src/*
$ touch src/index.js src/index.css # Create 2 files

Your src/index.js file

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class App extends React.Component {
  render() {
    return (
      <div>
        {/* Your application code */}
      </div>
    );
  }
}

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

JSX

Rule Example
A JSX is always wraped by a tag - <App />
- <MyCoponent>Hello</MyCoponent>
- <ul><li>Elt1</li><li>Elt2</li></ul>
To put JavaScript, you need to use { and }
...

React Components

React is based on Components, and each Component is a classe that extends React.Component.

// Definition of the ShoppingList component
class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.owner}</h1>
        <ul>
          <li>Instagram</li>
          <li>WhatsApp</li>
          <li>Oculus</li>
        </ul>
      </div>
    );
  }
}

class ShoppingList extends React.Component {
  render() {
    return (
      <div>
        <ShoppingList owner="Mark" />
      </div>
    );
  }
}
// Example usage: <ShoppingList name="Mark" />

React Functional Components

Component that only needs a render method can be simplified by a function that just returns a JSX.

Example

function Square(props) {
  return (
    <button className="square" onClick={props.onClick}>
      {props.value}
    </button>
  );
}

React Props

// To use in JSX
<MyComponent myProp={myValue} />

// To use inside MyComponent class
this.prop.myProp

Example

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />; // Pass a "value" prop to the Square 
  }
  // ...
}

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value} {/* Reuse the "value" prop */}
      </button>
    );
  }
}

React States

// You can initialize the state in the Component's constructor
this.state = { firstname: 'Maxence', age: 25 }

// You can get a state value with "this.state" property
this.state.firstname

// You MUST set some state value with "this.setState" method
// Be careful, this opereation is asynchronous
this.setState({firstname: 'Mickaël'})

Example

class Square extends React.Component {
  constructor(props) {
    super(props);
    this.state = { // Init the state
      value: null,
    };
  }

  render() {
    return (
      <button className="square" onClick={() => this.setState({value: 'X'})}> {/* Set the state */}
        {this.state.value} {/* Get the state */}
      </button>
    );
  }
}

React Lifecycle

Mounting:

Updating:

Unmounting:

Error Handling:

React Events

Handling events with React elements is very similar to handling events on DOM elements. There are some syntactic differences:

  • React events are named using camelCase
  • With JSX you pass a function as the event handler

Examples

<button onClick={myFunctionToTrigger}>
  Activate Lasers
</button>
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button> {/* The same with binding  */}
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>
    );
  }
}

List of events

Event Types Event Names
Clipboard Events onCopy onCut onPaste
Composition Events onCompositionEnd onCompositionStart onCompositionUpdate
Keyboard Events onKeyDown onKeyPress onKeyUp
Focus Events onFocus onBlur
Form Events onChange onInput onInvalid onSubmit
Mouse Events onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp
Selection Events onSelect
Touch Events onTouchCancel onTouchEnd onTouchMove onTouchStart
UI Events onScroll
Wheel Events onWheel
Media Events onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting
Image Events onLoad onError
Animation Events onAnimationStart onAnimationEnd onAnimationIteration
Transition Events onTransitionEnd
Other Events onToggle

Conditional rendering

class MyComponent extends React.Component {
  showButton() {
    if (this.props.isLoggedIn)
      return <LogoutButton />
    else 
      return <LoginButton />
  }
  render() {
    let button
    if (this.props.isLoggedIn)
      button = <LogoutButton />
    else 
      button = <LoginButton />
    return (
      <div>
        {/********** Method 1: Variable **********/}
        {button}
        {/********** Method 2: Function **********/}
        {this.showButton()}
        {/********** Method 3: Ternary **********/}
        {this.props.isLoggedIn ? <LogoutButton /> : <LoginButton />}
        {/********** Method 4: Inline If with Logical && Operator **********/}
        {this.props.isLoggedIn && <LogoutButton />}        
        {!this.props.isLoggedIn && <LoginButton />}        
      </div>
    )
  }
}

List rendering

const students = ['Alice', 'Bob', 'Charly', 'David']

class MyComponent extends React.Component {
  showList() {
    let list = []
    for (let i = 0; i < students.length; i++) {
      list.push(<li key={i}>{students[i]}</li>)
    }
    return list
  }
  render() {
    let list = []
    for (let i = 0; i < students.length; i++) {
      list.push(<li key={i}>{students[i]}</li>)
    }
    return (
      <ul>
        {/********** Method 1: Variable **********/}
        {list}
        {/********** Method 2: Function **********/}
        {this.showList()}
        {/********** Method 3: Map **********/}
        {students.map((student,i) => <li key={i}>{student}</li>)}
      </ul>
    )
  }
}

React and forms

Basic Example with 1 input

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

React Router

Installation

npm install --save react-router-dom

Import

import { BrowserRouter, Route, Link } from 'react-router-dom'

React Router Components

Component Description Main Props
<BrowserRouter> Router Component that should wrap your application
<Route> When the url matches its props path, it renders its content
  • path: string
  • component: Component
  • render: func
  • exact: bool
<Switch> Group <Route> together and display maximum 1
<Link> Replace the <a> tag of HTML in React Router
  • to: string
  • to: object
<NavLink> A special version of the <Link> that will add styling attributes to the rendered element when it matches the current URL
  • activeClassName: string
  • activeStyle: object
  • exact: bool

match

A component displayed with <Route> has access to match (as this.props.match or as ({ match }) => ()) and it is an object containing the following properties:

Property Type Description
params bool Key/value pairs parsed from the URL corresponding to the dynamic segments of the path
isExact bool true if the entire URL was matched (no trailing characters)
path string The path pattern used to match. Useful for building nested <Route>s
url string The matched portion of the URL. Useful for building nested <Link>s

Using Axios with React

Installation

npm install --save axios
import axios from 'axios'

Example of GET request

class PersonList extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      persons: []
    }
  }

  componentDidMount() {
    axios.get(`https://jsonplaceholder.typicode.com/users`)
      .then(res => {
        const persons = res.data;
        this.setState({ persons });
      })
  }

  render() {
    return (
      <ul>
        { this.state.persons.map(person => <li>{person.name}</li>) }
      </ul>
    )
  }
}

Example of POST request

class PersonList extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      name: ''
    }
  }

  handleChange(event) {
    this.setState({ name: event.target.value });
  }

  handleSubmit(event) => {
    event.preventDefault();
    const user = {
      name: this.state.name
    };
    axios.post(`https://jsonplaceholder.typicode.com/users`, { user })
      .then(res => {
        console.log(res);
        console.log(res.data);
      })
  }

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit.bind(this)}>
          <label>
            Person Name:
            <input type="text" name="name" onChange={this.handleChange.bind(this)} />
          </label>
          <button type="submit">Add</button>
        </form>
      </div>
    )
  }
}

Base instance

// src/api.js
import axios from 'axios';

export default axios.create({
  baseURL: `http://jsonplaceholder.typicode.com/`
});
// src/index.js
import API from './api';

// ...
API.delete(`users/${this.state.id}`)
  .then(res => {
    console.log(res);
    console.log(res.data);
  })
// ...