# 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
Changing the DOM is super expensive
# Virtual DOM
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;
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
# 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"
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>;
}
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!']
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,
};
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;
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;
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;
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>
);
}
}
.
.
.
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;
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.
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'} />;
}
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>
);
}
}
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.
- Mouting
- constructor() : JS
- render()
- componentDidMount()
- Updating
- render()
- componentDidUpdate()
- 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;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
changes to
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;
}
2
3
4
5
6
7
8
# mount vs render
- "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. - "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}/>
2
3
exact
is 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/"
}
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"
},
2
3
4
5
6
7
8
9
10
11
12
13
14
15
``npm run build`
npm run deploy
# Template Language
# Webpack
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
Also used to translate jsx.
Both webpack and babel are replaced with create-react-app since 2016
# JSX
Looks like HTML, but compiled into JS by babel.