Spring 2019 。 Ric Huang
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
// Compared to –-
function Rectangle(height, width) {
this.height = height;
this.width = width;
}
const p = new Rectangle(); // ReferenceError!!
class Rectangle {}
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Method
calcArea() {
return this.height * this.width;
}
}
const a = new Rectangle(10, 20);
a.calcArea(); // 200
// Compared to –-
function Rectangle(height, width) {
this.height = height;
this.width = width;
this.calcArea = function () {
return this.height * this.width;
}
}
const a = new Rectangle(10, 20);
a.calcArea();
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
get area() { return this.calcArea(); }
// Method
calcArea() { return this.height * this.width; }
}
const a = new Rectangle(10, 20);
a.calcArea(); // 200
a.area; // 200
// See "getter/setter methods for objects"
(not for "functions")
class Point {
constructor(x, y) { this.x = x; this.y = y; }
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.hypot(dx, dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
console.log(Point.distance(p1, p2)); // 7.0710678118654755
class Animal {
constructor(name) { this.name = name; }
speak() { console.log(this.name + ' makes a noise.'); }
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and
// pass in the name parameter
}
// Overload parent class' method
speak() { console.log(this.name + ' barks.'); }
}
let d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
function Animal(name) {
this.name = name;
this.speak = function () {
console.log(this.name + ' makes a noise.');
}
}
function Dog(name) {
Animal.call(this, name);
this.speak = function() {
console.log(this.name + ' barks.');
}
}
Dog.prototype = Object.create(Animal.prototype);
let d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
console.log(new Food('cheese', 5).name);
// expected output: "cheese"
function Animal (name) { this.name = name; }
Animal.prototype.speak = function () {
console.log(this.name + ' makes a noise.');
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
let d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
const Animal = {
speak() {
console.log(this.name + ' makes a noise.');
}
};
// Error!!
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and
// pass in the name parameter
}
speak() { console.log(this.name + ' barks.'); }
}
Object.setPrototypeOf(Dog.prototype, Animal);
let d = new Dog('Mitzie');
d.speak(); // Mitzie makes a noise.
class Cat {
constructor(name) { this.name = name; }
speak() { console.log(`${this.name} makes a noise.`); }
}
class Lion extends Cat {
speak() { super.speak(); console.log(`${this.name} roars.`);}
}
let l = new Lion('Fuzzy');
l.speak();
// Fuzzy makes a noise.
// Fuzzy roars.
<!-- <thead> -->
<tr>
<th>Subject</th>
<th>Score</th>
</tr>
<!-- <tbody> -->
<tr>
<td>Math</td>
<td>100</td>
</tr>
<tr>
<td>Chinese</td>
<td>87</td>
</tr>
<!-- <thead> -->
<tr>
<th>Subject</th> <th>Score</th>
</tr>
<!-- <tbody> -->
<tr>
<td>Math </td> <td>100 </td>
</tr>
<tr>
<td>Chinese</td> <td>87 </td>
</tr>
Install "create-react-app"
In case you encounter any problem, use CodePen instead for now…
如果說,前四個星期教的 HTML, CSS, JavaScript 讓你學會怎麼去寫一個簡單的網頁程式,那麼,從這星期開始教的 React, 以及後面眾多單元,將會真正帶你進入 "Web Applications" 的奇幻旅程!
不只是學寫程式,而要去 「了解整個技術生態系,從服務設計的思維出發,學會使用最佳的工具與資源,進行最有效率的設計與開發!」
> create-react-app hello-world
> cd hello-world
> npm start
public/index.html
src/index.js
src/App.js
npm init projectName
npm install
// what you need to run React,
// including all the modules, webpack configure, Babel... etc
And prepare all scripts for you to run React Apps
Delete lines 8-23
Change returned context to "<h1>Hello, world!</h1>"
Save it, and you will see the webpage automatically reloaded!
ReactDOM.render(
<App / >, document.getElementById('root'));
// App.js won't be called
ReactDOM.render(
<h1>Hello, world!</h1>, document.getElementById('root'));
// In JavaScript/React
ReactDOM.render(
<h1>Hello, world!</h1>, document.getElementById('root'));
<!-- In HTML -->
<body>
<div id="root"></div>
</body>
class Hello extends React.Component {
// 一定要有一個 render() method
render() {
// 回傳很像是 html 的 jsx
return <h1>Hello, World</h1>;
}
}
ReactDOM.render(
<Hello / >, document.getElementById('root'));
// expression
<tag>text or { expression }</tag>
// or class
class ClassName extends React.Component {
render() { ... return...; }
}
ReactDOM.render(element, container[, callback]);
let e = <h1>Hello, world!</h1>;
ReactDOM.render(e, document.getElementById('root'));
而 container 則是一個 DOM node
callback 顧名思義則是在 render() 完成後被呼叫
// Input (JSX):
var app = <Nav color="blue" />;
// Output (JS):
var app = React.createElement(Nav, {color:"blue"});
// Input (JSX):
var app = <Nav color="blue"><Profile>click</Profile></Nav>;
// Output (JS):
var app = React.createElement(
Nav,
{color:"blue"},
React.createElement(Profile, null, "click")
);
const e1 = <h1> Hello, {iAmAFunction(pp)}! </h1>;
const e2 = <img src={user.avatarUrl}></img>;
const e3 = <p> 2 + 3 = { 2+3 } </p>
let e4;
if (someExp) e4 = <h1>Hello, {iAmAFunction(pp)}!</h1>
else e4 = <h1>Hello, world!</h1>
<div className="foo" /> // as "class" in HTML
<label htmlFor="username">Username</label> // as "for" in HTML
<MyButton disabled={false} onClick={() => {}} />
render() { // 不能回傳並列的 elements
return (
<div>Hello 1</div>
<div>Hello 2</div>
);
}
render() { // 包進 div
return (
<div>
<div>Hello 1</div>
<div>Hello 2</div>
</div>
);
}
<A disabled="{false}" onClick={() => {}} /> // extra { }
<A> ({ "World!" }) </A> // extra ( ); output: (World!)
<A> ("World!") </A> // Missing { }; output: ("World!")
<A> { "World!"; } </A> // NO statement; ERROR: extra ';'!
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
import React, { Component } from 'react';
class Welcome extends Component {
render() { return <h1>Hello, {this.props.name}</h1>; }
}
const element = <Welcome name="Ric" / >;
ReactDOM.render(element, document.getElementById('root'));
const columnIndex = [ 'Subject', 'Score' ];
const scoreCard = {
name: 'Ric',
records: [
[ 'Math', 100 ],
[ 'Chinese', 87 ],
[ 'English', 100 ],
[ 'Science', 100 ],
[ 'Social', 0 ]
]
};
<body>
<!-- will insert ReactDOM component here -->
<!-- wrap the <table> with a <div> -->
<div id="root"></div>
</body>
// In "index.js"
ReactDOM.render(<ScoreCard scoreCard = {scoreCard}
columnIndex = {columnIndex} / >,
document.getElementById('root'));
// in App.js
class ScoreCard extends Comonent {
render() {
return (
<table>
...
</table>
);
}
}
const columnIndex = [ 'Subject', 'Score' ];
const scoreCard = {
name: 'Ric',
records: [
[ 'Math', 100 ],
[ 'Chinese', 87 ],...
]
};
return (
<table>
<caption> Ric's Score </caption>
<thead>
<tr><th> Subject </th><th> Score </th></tr>
</thead>
<tbody>
<tr><td> Math </td><td> 100 </td></tr>
<tr><td> Chinese </td><td> 87 </td></tr>...
</tbody>
</table>
);
<caption> {this.prop.scoreCard.name}'s Score </caption>
// From
cosnt columnIndex = [ 'Subject', 'Score' ];
// To
<thead>
<tr><th> Subject </th><th> Score </th></tr>
</thead>
// Commnet out solution for lecture
// From
const scoreCard = {
name: 'Ric',
records: [
[ 'Math', 100 ],
[ 'Chinese', 87 ],...
]
};
// To
<tbody>
<tr><td> Math </td><td> 100 </td></tr>
<tr><td> Chinese </td><td> 87 </td></tr>...
</tbody>
// From
const scoreCard = {
name: 'Ric',
records: [
[ 'Math', 100 ],
[ 'Chinese', 87 ],...
]
};
// Or put it this way...
<tbody>
[ <tr>[ Math, 100 ]</tr>,
<tr>[ Chinese, 87 ]</tr>,...
]
</tbody>
// Commnet out solution for lecture
Make a static blog page.
You don't need to implement "edit", "post", "add/delete", "search", or any kind of interactions.
Just a static page that is composed of title, menu, sections, articles or photos, etc.
Use React to make it component-based so that you can add more interactions later!
propTypes
props and state
React Event Handlers
Component Lifecycle