![Page 1: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/1.jpg)
React
Shan-Hung Wu & DataLab
CS, NTHU
![Page 2: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/2.jpg)
Separation of Concerns
• HTML: noun
• CSS: adjective
• JS: verb
• Applies well to static pages
• But for dynamic content, JS usually “crosses the line”
2
el.textContent = '...';
![Page 3: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/3.jpg)
Modern Frontend Framework
• Write JS in HTML • Write HTML in JS
3
![Page 4: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/4.jpg)
• Component-based
• Debug-friendly
– Syntax errors fails at compile time
– Declarative properties make runtime debugging easy
• Extends to mobile landscape (React Native)
4
![Page 5: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/5.jpg)
Hello React
• *.jsx are JS files with HTML embedded
5
$ npm install --save react react-dom
$ npm install --save-dev babel-preset-react
// in webpack.config.js
entry: {
index: './index.jsx',
vendor: ['react', 'react-dom']
}
module: {
rules: [{
test: /\.(js|jsx)$/,
exclude: [/node_modules/],
use: [{
loader: 'babel-loader',
options: {
presets: [
['es2015', {'modules': false}],
'react'
]
}
}]
}], ...
}
![Page 6: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/6.jpg)
// under "module.exports" in webpack.config.js
resolve: {
alias: {
components: path.resolve(srcPath, 'components')
}
}, ...
// in index.js
import ... from 'components/Component.jsx';
Webpack Aliasing
• Components are move to src/components
– Component.jsx by convention
• Use aliasing to resolve path dependency:
6
![Page 7: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/7.jpg)
Development Server
• React requires a web server to run
7
$ npm install --save-dev \
webpack-dev-server
// in webpack.config.js
module.exports = {
...,
devServer: {
contentBase: distPath,
compress: true,
port: 8080
}
}
// under "scripts" in package.json:
"start": "webpack-dev-server",
![Page 8: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/8.jpg)
Outline
• React components and JSX– States and data flows
– Forms
– More JSX
• Thinking in React: WeatherMood– Routing
– Promises and AJAX requests
– UI
• Debugging
8
![Page 9: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/9.jpg)
Outline
• React components and JSX– States and data flows
– Forms
– More JSX
• Thinking in React: WeatherMood– Routing
– Promises and AJAX requests
– UI
• Debugging
9
![Page 10: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/10.jpg)
Hello React
• JSX allows writing HTML in JS
• Compiled to normal objects by Babel
10
// in index.js
import React from 'react';
import ReactDOM from 'react-dom';
window.onload = function() {
let name = 'Bob';
ReactDOM.render(
<h1>Hello {name}</h1>, // JSX, no quotes
document.getElementById('root')
);
};
const el = <h1>Hello {name}</h1>;
// compiled to
const el = React.createElement('h1', ...);
![Page 11: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/11.jpg)
• Everything is converted to a string before rendered• Prevents injection attacks, e.g., cross-site-scripting
(XSS)11
// embedded expressions
const el = <div>Number {1+1}</div>;
// multi-line with nested elements
const el = (
<div>
<h1>Title</h1>
<p>Paragraph.</p>
</div>
); // use (...) to prevent auto ';' insertion
// attributes (in lower-camel-case)
const url = '...';
const el = <img className='fliud' src={url}>;
JSX Basics
![Page 12: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/12.jpg)
Fast Re-rendering
• React keeps a virtual DOM in memory
– Updates only changed elements in real ROM
12
function tick() {
const date = new Date().toLocaleTimeString();
const el = (
<div>
<h1>Hello</h1>
<h2>It's {date}.</h2>
</div>
);
ReactDOM.render(el, document.getElementById('root');
}
setInterval(tick, 1000);
![Page 13: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/13.jpg)
Components & Props
• render() accepts only a single root element
• Multiple instances created
13
// functional component
function Component(props) {
return <h2>This is {props.name}<h2>;
}
// class component
class Component extends React.Component {
constructor(props) {
super(props); ...
}
render() {
return <h2>This is {this.props.name}<h2>;
}
}
// in index.js
ReactDOM.render(
<div>
<Component name='Alice'>
<Component name='Bob'>
</div>,
document.getElementById('root');
);
![Page 14: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/14.jpg)
Never change props in a component!
• So, React can efficiently detect whether a component should be re-rendered
14
![Page 15: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/15.jpg)
Outline
• React components and JSX– States and data flows
– Forms
– More JSX
• Thinking in React: WeatherMood– Routing
– Promises and AJAX requests
– UI
• Debugging
15
![Page 16: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/16.jpg)
States
• A component may have its own states
• Keep track of e.g., user input or program status
16
![Page 17: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/17.jpg)
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 5
};
}
render() {
return <h2>Countdown: {this.state.count}</h2>;
}
// lifecycle methods
componentDidMount() {
this.countdownId = setInterval(() => {
this.setState({ // triggers re-rendering
count: this.state.count - 1
}); // obj merged to this.state
}, 1000);
}
componentWillUnmount() {
clearInterval(this.countdownId);
}
}
Example: Counter
• More lifecycle methods
17
![Page 18: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/18.jpg)
Data Flows
• Downward:
18
Main
Component
// in Main.render()
<Component count={this.state.count}>
// in Component.render()
<h2>Countdown: {this.props.count}</h2>
![Page 19: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/19.jpg)
Data Flows
• Upward:
19
Main
Component
// in Main.render()
<Component onReset={this.handleReset}>
// in Component.render()
<button onClick={this.props.onReset}>Reset</button>
![Page 20: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/20.jpg)
Advantages• Data flows are declarative
– JSX declares both downward and upward flows
– Simplifies debugging (by investigating props)
• States are local to component objects
– Simplifies state management in complex UIs
20
// in index.js
ReactDOM.render(
<div>
<Main />
<Main />
</div>,
document.getElementById('root');
);
![Page 21: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/21.jpg)
Bug 1: this in handleReset()
• this does not bind to Main when called
• Fix:
21
// in Main.render()
<Component onReset={this.handleReset}>
// in Component.render()
<button onClick={this.props.onReset}>Reset</button>
// in Main.constructor()
this.handleReset = this.handleReset.bind(this);
// or use ES7 property initializer
class Main extends React.Component {
handleReset = () => {
...
};}
![Page 22: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/22.jpg)
Bug 2: setState() is Asynchronous
• React batches multiple setState calls for better rendering performance
• If new state depends on previous one (or props):
• Actions assuming new state is set:
22
setState({
count: this.state.count - 1
});
... // uses new count
setState((prevState, props) => ({
count: prevState.count - 1
}));
setState({
count: prevState.count - 1
}, () => {
... // uses new count
});
![Page 23: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/23.jpg)
Outline
• React components and JSX– States and data flows
– Forms
– More JSX
• Thinking in React: WeatherMood– Routing
– Promises and AJAX requests
– UI
• Debugging
23
![Page 24: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/24.jpg)
Form Elements
• Form elements manages their own state in normal JS
• Uncontrolled form elements:// JSX in render()
<form>
<input type='text' ref={el => {this.inputEl = el}} />
</form onSubmit={this.handleSubmit}>
// method
handleSubmit(e) {
const v = this.inputEl.value;
this.inputEl.blur();
...
}
![Page 25: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/25.jpg)
Controlled Form Elements
• States managed explicitly (recommended)– More declarative in JSX
// JSX in render()
<form>
<input type='text' value={this.state.inputValue}}
onChange={this.handleInputChange} />
</form onSubmit={this.handleSubmit}>
// methods
handleInputChnage(e) {
this.setState({inputValue: e.target.value});
}
handleSubmit(e) {
const v = this.state.inputValue;
...
}
![Page 26: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/26.jpg)
Outline
• React components and JSX– States and data flows
– Forms
– More JSX
• Thinking in React: WeatherMood– Routing
– Promises and AJAX requests
– UI
• Debugging
26
![Page 27: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/27.jpg)
Conditions
• Only expressions in {}: no if, for, etc.
• {} must be evaluated to DOM element(s)
27
// if
<h1>Hello</h1> {
unreadMsgs.length > 0 && // short circuit
<h2>You have {unreadMsgs.length} messages.</h2>
}
// if else
<h1>Hello</h1> {
unreadMsgs.length == 0 ? <h2>No message.</h2> :
<h2>You have {unreadMsgs.length} messages.</h2>
}
![Page 28: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/28.jpg)
Loops
• Arrays/lists of elements can be rendered directly
• Key per item is necessary for fast re-rendering
– Only needs to be unique among siblings
– Added to the composing component (that calls map), rather than individual element components
28
// for
<h1>Unread messages:</h1>
<ul> {
unreadMsgs.map((m => <li key={m.id}>{m.title}</li>))
}
</ul>
![Page 29: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/29.jpg)
Attributes
• Default to true
• Spread
29
<Message isRead /> // same as
<Message isRead={true} />
const props = {name: 'Bob', age: 18}
<User {...props} />
![Page 30: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/30.jpg)
Composition
• Facebook favors composition over inheritance
30
function GeneralComponent {
return (
<div>
<h1>Welcome</h1>
{props.children} // provided by React
</div>
);
}
function SpecializedComponent {
return (
<GeneralComponent>
<p>Content</p>
<p>Footer</p>
</GeneralComponent>
);
}
![Page 31: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/31.jpg)
Outline
• React components and JSX– States and data flows
– Forms
– More JSX
• Thinking in React: WeatherMood– Routing
– Promises and AJAX requests
– UI
• Debugging
31
![Page 32: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/32.jpg)
Clone lab-react-weathermood
32
![Page 33: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/33.jpg)
Setup
• React Router– Loads different components based on different URL paths– Declarative (in JSX)
• Axios– Makes AJAX (in-page HTTP) requests – ES6 Promise-based API
• Reactstrap– Bootstrap with JS replaced by React– Uses React animation add-ons
33
$ npm install --save react-router axios
$ npm install --save reactstrap \
react-addons-transition-group \
react-addons-css-transition-group
![Page 34: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/34.jpg)
ES7 Spread in Object Literals
34
$ npm install --save-dev \
babel-plugin-transform-object-rest-spread
// in webpack.config.js
loader: 'babel-loader',
options: {
presets: [...],
plugin: [..., 'transform-object-rest-spread']
}
// merge objects
const obj1 = {
p1: 1,
p2: 2
};
const obj2 = {
...obj1,
p3: 3
}; // obj2 now has p1, p2, and p3
![Page 35: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/35.jpg)
Turning off URL Translation in CSS
• By default, Babel CSS-loader translates url(…)'s into module imports
• Problematic when setting, e.g., background images
• To turn this off:
35
background-image: url('...');
// in rules of webpack.config.js
test: /\.css$/,
use: ['style-loader', {
loader: 'css-loader',
options : {
url: false
}
}]
![Page 36: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/36.jpg)
36
• Sign up to get an App ID
![Page 38: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/38.jpg)
Step 1: Component Hierarchy
38
WeatherForm
WeatherDisplay
Main
Navbar
Today /Forecast
![Page 39: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/39.jpg)
Step 2: Static Version (Downward Data Flow)
39
WeatherForm {city, unit
}
WeatherDisplay {temp, unitweather, desc
}Main
Navbar { link1, link2 }
Today { weather }Forecast { weather }
![Page 40: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/40.jpg)
Step3: Identifying States
• The “changing parts” of a component– By user or program logic
• Passed in from a parent via props? – Not a state
• Remain unchanged over time? – Not a state
• Can be computed based other states/props?– Not a state
40
![Page 41: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/41.jpg)
Step 3: Identifying States
41
WeatherForm {city, unit
}
WeatherDisplay {temp, unitweather, desc
}Main
Navbar { link1, link2 }
Today { weather }Forecast { weather }
![Page 42: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/42.jpg)
Step 4: Lifting States Up
• What if several components need to reflect the same/corresponding states?
• Lift the states up to the closest common ancestor
42
![Page 43: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/43.jpg)
Step 4: Lifting States Up
43
WeatherForm {city, unit
}
WeatherDisplay {temp, unitweather, desc
}Main {unit
}
Navbar { link1, link2 }
Today { weather, temp, desc, city }Forecast { weather, temp, desc, city }
![Page 44: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/44.jpg)
Step 5: Upward Data Flow
44
WeatherForm {city, unit
}
WeatherDisplay {temp, unitweather, desc
}Main {unit
}
Navbar { link1, link2 }
Today { weather, temp, desc, city }Forecast { weather, temp, desc, city }
![Page 45: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/45.jpg)
Outline
• React components and JSX– States and data flows
– Forms
– More JSX
• Thinking in React: WeatherMood– Routing
– Promises and AJAX requests
– UI
• Debugging
45
![Page 46: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/46.jpg)
Client-Side Routing
• A single-page app may want to load different components based on different URL paths
– At client side to minimize latency
• Implementation: a Link component that
– Fires an event when clicked
– Tells which path to go
• Container component can then mount/unmount relevant components
46
![Page 47: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/47.jpg)
React Router
• Declarative client-side routing:
47
// in Main.jsx
render() {
return (
<Router>
<Link to='/'>Today</Link>
<Link to='/forecast'>Forecast</Link>
...
<Route exact path='/'
render={() => <Today />}></Route>
<Route path='/forecast'
render={() => <Forecast />}></Route>
</Router>
);
}• More matching rules
![Page 48: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/48.jpg)
Outline
• React components and JSX– States and data flows
– Forms
– More JSX
• Thinking in React: WeatherMood– Routing
– Promises and AJAX requests
– UI
• Debugging
48
![Page 49: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/49.jpg)
ES6 Promise
• A value available in the future
• Separation of concerns– Handlers can be
written in different places
• Use arrow funcfor this
49
// in method1()
const p = new Promise((resolve, reject) => {
... // do asynchronous job here
if (success) resolve(data);
else reject(err);
});
return p;
// in method2(p)
const p2 = p.then(data => {
... // process data
return data2
}); // always returns a new Promise
return p2;
// in method3(p2)
p2.then(data2 => {
... process data2
}).catch(err => {
... // handle err
}); // always returns a new Promise
![Page 50: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/50.jpg)
Execution Flow
• Chain then and/or catch as long as you like
• Reject mode: – throw new Error()
• Resolve mode:– return
50
resolve() reject()
return throw
return throw
![Page 51: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/51.jpg)
Axios and AJAX Requests
• Requests can be canceled
51
// GET request
axios.get('...url...').then(res => {
res.status // HTTP response code (e.g., 200, 401)
res.data // object parsed from HTTP response body
res.headers // HTTP presonse headers
}).catch(err => {
console.log(err);
});
// POST request
axios.post('...url...', {
... // request body
}).then(...).catch(...);
![Page 52: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/52.jpg)
Outline
• React components and JSX– States and data flows
– Forms
– More JSX
• Thinking in React: WeatherMood– Routing
– Promises and AJAX requests
– UI
• Debugging
52
![Page 53: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/53.jpg)
Reactstrap
• More components
53
import {Button} from 'reactstrap';
// JSX
<Button color='primary'
onClick={this.handleClick}>primary</Button>
handleClick(e) {
...
}
• Bootstrap with JS replaced by React
– Integrates to virtual DOM for better performance
![Page 54: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/54.jpg)
More React UI Libraries
• Material-UI
• React-Bootstrap
• and more
54
![Page 55: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/55.jpg)
Outline
• React components and JSX– States and data flows
– Forms
– More JSX
• Thinking in React: WeatherMood– Routing
– Promises and AJAX requests
– UI
• Debugging
55
![Page 56: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/56.jpg)
React DevTools
• Breakpoints: debugger;
56
![Page 57: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/57.jpg)
Type Checking
• More type checking
57
class WeatherForm extends Ract.Component {
// ES7 property initializer
static propTypes = {
city: React.PropTypes.string,
unit: React.PropTypes.string
// bool, number, array, object, func, ...
};
constructor(props) {...}
render() {...}
}
![Page 58: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/58.jpg)
Source Map
• Options & speed
• Usually, 'cheap-source-map' is a good compromise
58
// in webpack.config.js
module.exports = {
...
devtool: 'source-map'
};
![Page 59: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/59.jpg)
Assigned Readings
• Tic Tac Toe in React
• JSX in depth (optional)
• Controlled form elements (optional)
• Refs and uncontrolled components (optional)
59
![Page 60: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/60.jpg)
Assignment: 5-Days Forecast
60
WeatherTable
Forecast
![Page 61: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/61.jpg)
Requirements
• Use the 5-days forecast API
• Show “tomorrow” in WeatherDisplay
• WeatherTable for the rest days
• Each day in WeatherTable:– Day of week: “Sat,” “Sun ,” “Mon,” and so on
– Temperature in correct unit
– Weather condition icon (based on code)
• Responsive: show only 2 days in WeatherTable on portrait mobile devices
61
![Page 62: More Inside the Classes - GitHub Pages•React Router –Loads different components based on different URL paths –Declarative (in JSX) •Axios –Makes AJAX (in-page HTTP) requests](https://reader030.vdocument.in/reader030/viewer/2022040205/5f02c7df7e708231d405fa06/html5/thumbnails/62.jpg)
Bonus
• Query OWM using users' current geo-coordinates (latitudes and longitudes):
– Read this tutorial first– Watch out the privacy settings
• Change background to Google Map, and allow “pin to query”– You can use react-google-maps or similar
62
navigator.geolocation
.getCurrentPosition(function(position) {
// called back asynchronously
const lat = position.coords.latitude;
const lng = position.coords.longitude; ...
})