# React

React : Made from facebook. Used in spotify airbnb. Angular has angular specific grammar, but react has huge user population. Besides JSX, react is mostly javascript.

npm install npx -g

Once installed globally, no longer need to install everytime.

npx create-react-app movie_app

npm start

# DOM

The DOM is a Mess -John Resig

Standardized API that represents an HTML, XHTML or XML as a tree structure.

Each node on tree is an object representing an HTML element

Connects JS to HTML.

Browser's rendering engine(i.e. Webkit) constructs DOM tree from HTML

Parses and applies CSS to HTML creating a render tree

Render tree is painted to browser

image-20201221171552155

Changing the DOM is super expensive

# Virtual DOM

image-20201221170756950

image-20201221171104962

Instead of changing the real DOM, virtual DOM is first made.

Virtual DOM doesn't get rendered so computational cost is cheap.

Lightweight and only exists in memory and never actually rendered.

Tree data structure of plain JS objects.

JSX(template language) tells how to build virtual DOM.

Render() function creates virtual DOM tree.

Use the diff algorithm to find minimum number of operations needed to change the real DOM

Patch the update so that every DOM is only created once for its lifecycle.

# Diffing (Reconciliation)

Finding minimum number of modification is O(n3) problem.

React uses a heuristic that is O(n)

React's two assumptions

-  Different element type produce different trees -> React wil not diff them. Instead completely replaces them. BF traversal.
-  Child elements may be hinted as stable with "key" -> Which is why you must assign keys in for loops.

React Fiber uses parent-child node relationship as a singly linked list. Allows prioritizing rendering.

# Component

//potato.js

import React from "react";
// This line is crucial to let React know this is a component

// Uppercase for the first letter
function Potato() {
  return <h3>Potato</h3>;
}

export default Potato;
1
2
3
4
5
6
7
8
9
10
11

Component : function that returns HTML. Looks like

React application can only render one component which is . Inside App.js you can put more components.

# JSX

Combination between HTML and JS. It is the only thing very custom for react, the rest is JS.

Why use JSX?

<Food fav="kimchi" />
// Food=component prop=fav value-"kimchi"
1
2
function Food(props) {
  console.log(props);
  // gives us the props and values
  return <h1> I like props.fav </h1>;
}

//same thing as above
//props.fav = {fav}
function Food({ fav }) {
  console.log(fav);
  return <h1> I like {fav} </h1>;
}
1
2
3
4
5
6
7
8
9
10
11
12

# map function

friends = ["ki", "han", "gu"];
friends.map((friend) => {
  return friend + "!";
});

console.log(friends);
//friends = ['ki!', 'han!', 'gu!']
1
2
3
4
5
6
7

Iterate through iterables and apply callback functions and then return array of the iterables.

# PropTypes

npm i prop-types

Tells us if we're getting all the props that we need and helps debugging.

import PropTypes from "prop-types";

Food.propTypes = {
  name: PropTypes.string.isRequired,
  image: PropTypes.string.isRequired,
  rating: PropTypes.number.isRequired,
};
1
2
3
4
5
6
7

Error : if wrong type. If it's empty? No error. For better code quality.

# Dynamic Data

Changes constantly so props are no good.

//First, learn about class components
import React from "react";

class App extends React.Component {
  render() {
    return <h1>I am a class component </h1>;
  }
}

export default App;
1
2
3
4
5
6
7
8
9
10

Class components do not return they render . Inside render they have return.

It's extended from React component and put inside a render method.

Class component have something called state.

do not change state directly from function!

Because it will not refresh the render function.

You want to render again every time state changes.

setState() will change the value and render again. And it will change very quick.

import React from "react";

class App extends React.Component {
  state = {
    count: 0,
  };
  add = () => {
//    this.setState({ count: this.state.count + 1 });
    // This is a better way. Why?
    this.setState({ current => count: current.count + 1 });
  };
  minus = () => {
    this.setState({ count: this.state.count - 1 });
  };

  render() {
    return (
      <div>
        <h1>The number is {this.state.count} </h1>
        <button onClick={this.add}>add</button>
        <button onClick={this.minus}>minus</button>
      </div>
    );
  }
}

export default App;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# importing components

//Movie.js

import React from "react";
import PropTypes from "prop-types";

function Movie({ id, year, title, summary, poster }) {
  return <h1>{title}</h1>;
}

Movie.propTypes = {
  id: PropTypes.number.isRequired,
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
};

export default Movie;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//App.js

import Movie from "./Movie";
.
.
.
 render() {
    const { isLoading, movies } = this.state;
    return (
      <div>
        {" "}
        {isLoading
          ? "Loading"
          : movies.map((movie) => {
              return (
                <Movie
                  key={movie.id}
                  id={movie.id}
                  year={movie.year}
                  title={movie.title}
                  summary={movie.summary}
                  poster={movie.medium_cover_image}
                />
              );
            })}{" "}
      </div>
    );
  }
}
.
.
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# Using images in React

With webpack, using static assets like images and fonts works similarly to CSS.

import React from "react";
import logo from "./logo.png"; // Tell webpack this JS file uses this image

console.log(logo); // /logo.84287d09.png

function Header() {
  // Import result is the URL of your image
  return <img src={logo} alt="Logo" />;
}

export default Header;
1
2
3
4
5
6
7
8
9
10
11
// css
body {
  background-image: url("theater2.jfif");
}
//works. but requires jpg file at same location as CSS>



//Home.js
<img src={require("/af.png")}/>
//Module not found: You attempted to import /af.png which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. This is because it is not imported.
1
2
3
4
5
6
7
8
9
10
11
  • Scripts and stylesheets get minified and bundled together to avoid extra network requests.
  • Missing files cause compilation errors instead of 404 errors for your users.
  • Result filenames include content hashes so you don’t need to worry about browsers caching their old versions.

Alternative is to use public folder.

# Public folder

it will not be processed by webpack. Instead it will be copied into the build folder untouched. To reference assets in the public folder, you need to use an environment variable called PUBLIC_URL

// index.html
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />


// JS
render() {
  // Note: this is an escape hatch and should be used sparingly!
  // Normally we recommend using `import` for getting asset URLs
  // as described in “Adding Images and Fonts” above this section.
  return <img src={process.env.PUBLIC_URL + '/img/logo.png'} />;
}
1
2
3
4
5
6
7
8
9
10
11

It is recommended to import images instead of using public files.

But it is advisable to use public folder in case of,

  • You need a file with a specific name in the build output, such as manifest.webmanifest (opens new window).
  • You have thousands of images and need to dynamically reference their paths.
  • You want to include a small script like pace.js (opens new window) outside of the bundled code.
  • Some library may be incompatible with webpack and you have no other option but to include it as a <script> tag.

# manifest.json

This file exists to provide app and extension info, such as name, icon and description, in json format. This comes in handy when your website behaves like an app, for instance when a user adds your website to their mobile homescreen. The manifest.json file will be compiled and added as a link tag in the head of the HTML template in index.html

# Form and input in React

  • handleChange on input and handleSubmit on form!
  • Binding method is different from vue.
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>
    );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# Component Life Cycle

# #mounting #updating #unmounting

Until now render() was the only function from React we used. But they have more.

Life cycle method is how react component creates and destroys components.

  1. Mouting
    • constructor() : JS
    • render()
    • componentDidMount()
  2. Updating
    • render()
    • componentDidUpdate()
  3. Unmounting
    • componentWillUnmount()
import React from "react";

class App extends React.Component {
  componentDidMount() {
    console.log("Rendered");
  }
  componentDidUpdate() {
    console.log("Updated");
  }
  render() {
    console.log("Rendering");
    return (
      <div>
        <h1> Hello World</h1>
      </div>
    );
  }
}

export default App;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

image-20201217211006472

import React from "react";

class App extends React.Component {
  state = {
    isLoading: true,
  };
  componentDidMount() {
    setTimeout(() => {
      this.setState({ isLoading: false });
    }, 6000);
  }
  render() {
    //    return <div> {this.state.isLoading ? "Loading" : "Ready" </div>
    // Modern JS
    const { isLoading } = this.state;
    return <div> {isLoading ? "Loading" : "Ready"} </div>;
  }
}

export default App;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

image-20201217211426339

changes to

image-20201217211437263

in 6 seconds.

# axios vs fetch

npm i axios

axios is the chocolate fetch is the nuts

// aync await
  getMovies = async () => {
    const movies = await axios.get("https://yts.mx/api/v2/list_movies.json");
  };

  componentDidMount() {
    this.getMovies;
  }
1
2
3
4
5
6
7
8

# mount vs render

  1. "Rendering" is any time a function component gets called (or a class-based render method gets called) which returns a set of instructions for creating DOM.
  2. "Mounting" is when React "renders" the component for the first time and actually builds the initial DOM from those instructions.

# Router

npm i react-router-dom

<HashRouter>
    <Route path="/" exact={true} component={Home}/>
    <Route path="/about" component={About}/>
1
2
3

exactis needed so /about does not include /.

# Hash router vs Browser router

# Class vs Function component

# Deploy

// package.json

.
.
.
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  // Add homepage part
  "homepage": "https://keithkwon.dev/movie_app_react/"
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

npm i gh-pages

//package.json

.
.
.
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "deploy": "gh-pages -d build",
    "predeploy":"npm run build"
  },


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

``npm run build`

npm run deploy

# Template Language

# Webpack

image-20201221174241818

Similar to Gulp but better!

Makes multiple js files into one file.

Imports image files and saves as static asset.

Compiles sass to css.

Integrating multiple js, css, html into one file. Bundler.

webpack is an open-source JavaScript module bundler.

vue-cli does the babel and webpack job at the back-end.

# Babel

JS compiler

image-20201221174512891

Also used to translate jsx.

Both webpack and babel are replaced with create-react-app since 2016

# JSX

image-20201221174717346

Looks like HTML, but compiled into JS by babel.

Last Updated: 3/1/2021, 9:19:08 PM