Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
301 lines (231 sloc) 5.49 KB

React Intro

Topics

  1. Compiling with Webpack and Babel
  2. JSX
  3. Components - functional vs class-based
  4. Props vs State
  5. Virtual Dom

Why React?

  1. Flexible
  2. Fast
  3. Component-based
  4. Declarative
  5. Simple error handling (with create react app)
  6. Strong community

Create React App

GitHub Repo

Getting Started

Install:

$ npm install -g create-react-app

Quick start:

$ create-react-app node-jobs-react
$ cd node-jobs-react
$ npm start

NOTE: Make sure you understand what's happening beneath the scenes with webpack and babel. For more, check out React Intro.

Structure

Your app structure should look like:

├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   └── index.html
├── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── index.css
│   ├── index.js
│   └── logo.svg
└── yarn.lock

Navigate through the "src" folder. What's happening with each one of these files?

  1. App.css
  2. App.js
  3. App.test.js
  4. index.css
  5. index.js

Take a look at the package.json. What do each of these commands do?

  1. "start": "react-scripts start",
  2. "build": "react-scripts build",
  3. "test": "react-scripts test --env=jsdom",
  4. "eject": "react-scripts eject"

Step 1

Remove everything except the index.js:

import React from 'react';
import ReactDOM from 'react-dom';

const App = () => {
  return (
    <div className="container">
      <h1>Node Jobs</h1>
    </div>
  )
}

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

What's happening?

  1. We created a functional component called App, which returns the JSX
  2. We then use render() to mount the App to the DOM

Add bootstrap to the index.html.

Step 2

Update index.js:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';

class App extends Component {
  constructor() {
    super()
    this.getJobs()
  }

  getJobs() {
    axios.get(`http://localhost:8080/api/v1/jobs`)
    .then((res) => { console.log(res); })
    .catch((err) => { console.log(err); })
  }

  render() {
    return (
      <div className="container">
        <h1>Node Jobs</h1>
      </div>
    )
  }
}

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

What's happening?

  1. constructor - runs automatically when an instance is created
  2. super() calls constructor of Component, which we're extending from
  3. getJobs() makes an AJAX call to our server
  4. React is handling the creation of the instance:
    const Test = new App()
    Test.getJobs()
    test.render()

Why is it a class?

Step 3

Update getJobs():

getJobs() {
  axios.get(`http://localhost:8080/api/v1/jobs`)
  .then((res) => { this.setState({ jobs: res.data.data }); })
  .catch((err) => { console.log(err); })
}

Add this to the constructor:

this.state = {
  jobs: []
}

What's happening?

  1. this.state adds state property and sets jobs to an empty array
  2. setState() async function to update state

Step 4

Update the render():

render() {
  return (
    <div className="container">
      <h1>Node Jobs</h1>
      <ul>
        {
          this.state.jobs.map((job) => {
            return <li key={ job.id }>{ job.title }</li>
          })
        }
      </ul>
    </div>
  )
}

What's happening?

  1. Iterated over the jobs and created a new element
  2. key? for react to keep track of each element

Step 5

Let's create a new component for the job list. Add a new folder called "components" to "src". Add a new file to that folder called JobList.jsx:

import React from 'react';

const JobList = (props) => {
  return (
    <ul>
      {
        props.jobs.map((job) => {
          return <li key={ job.id }>{ job.title }</li>
        })
      }
    </ul>
  )
}

export default JobList;

What's happening?

  1. We created a functional component called JobList, which returns the JSX

Why is this component a function and not a class? Props? Props vs State?

  1. Props - data flows down via props (from state to props), read only
  2. State - data tied to a component, read and write

Add the import to index.js:

import JobList from './components/JobList';

Update render():

render() {
  return (
    <div className="container">
      <h1>Node Jobs</h1>
      <JobList jobs={ this.state.jobs }/>
    </div>
  )
}

What's happening?

  1. State is being passed to the JobList component as a prop

Step 6

Let's convert the list to a table and add some style:

import React from 'react';

const JobList = (props) => {
  return (
    <table className="table table-hover">
    <thead>
      <tr>
        <th>ID</th>
        <th>Title</th>
        <th>Description</th>
        <th>Company</th>
        <th>Email</th>
        <th>Contacted?</th>
      </tr>
    </thead>
    <tbody>
      {
        props.jobs.map((job) => {
          return <tr key={job.id}>
          <td>{ job.id }</td>
          <td>{ job.title }</td>
          <td>{ job.description }</td>
          <td>{ job.company }</td>
          <td>{ job.email }</td>
          <td>{ job.contacted ? 'yes' : 'no' }</td>
          </tr>
        })
      }
    </tbody>
  </table>
  )
}

export default JobList;