
---
# (H)尊絕不凡 React 教學
## - 第二週
---
#### 你好啊
#### 真沒想到你可以到四樓來呢
#### 不過就到這裡為止了
#### 接下來由我 Robby 來當你們的講師!
- Github [https://github.com/explooosion](https://github.com/explooosion)
- Blog [https://dotblogs.com.tw/explooosion](https://dotblogs.com.tw/explooosion)
---
week2
- [本次上課專案](https://github.com/explooosion/react-tutorial)
---
### 今天の學習目標
- ㄧ、 Components 進階
- 二、 Elements 常用元素
---
首先,補充教學一下 Class
---
### 類別 Class - 宣告與建構
```javascript=
class Person {
// 建構式
constructor(name, age) {
this.name = name;
this.age = age;
}
}
```
```javascript=
// 實體化
const man = new Person('Jack', 18);
```
---
### 類別 Class - 方法與屬性
```javascript=
class Person {
level = 1;
constructor(name, age) {
this.name = name;
this.age = age;
}
eat(){
console.log('eat');
}
}
```
```javascript=
const man = new Person('Jack', 18);
man.eat(); // eat
console.log(man.level) // 1
```
---
### 類別 Class - 進階屬性與方法
```javascript=
class User {
name = 'Jack';
todo = ['sleep', 'eat', 'work']
height = 1.75;
weight = 65;
BMI = function () {
return this.weight / Math.pow(this.height, 2);
}
getBMI() {
return this.BMI();
}
}
```
---
### 類別 Class - 靜態方法
```javascript=
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.sqrt(dx*dx + dy*dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
console.log(Point.distance(p1, p2));
// 7.0710678118654755
```
---
### 類別 Class - 繼承 extend
```javascript=
class Car {
constructor(color) {
this.color = color;
}
}
class Tesla extends Car {
constructor(color) {
super(color);
}
}
const tesla = new Tesla('red');
console.log(tesla.color); // red
```
---
### 類別 Class - 調用自身 method
```javascript=
class Tesla extends Car {
run() { }
autoDrive() {
this.run();
}
}
const tesla = new Tesla();
tesla.run();
tesla.autoDrive();
```
---
### 類別 Class - 在方法中撰寫函式
```javascript=
class Tesla extends Car {
run() { }
autoDrive(mode='') {
this.run();
function fast(){ console.log('fast') }
function slow(){ console.log('fast') }
if(mode==='fast'){
fast()
}else(mode==='slow'){
slow()
}
}
}
const tesla = new Tesla();
tesla.run();
tesla.autoDrive('fast'); // fast
```
---
### 類別 Class - 試著做做看
1. 建立一個老師的類別,老師的屬性有名字、性別,然後方法有上課
2. 新增一個老師,並且給予名字與性別
3. 老師上課
4. 試著新增方法:吃東西
5. 試著讓老師上課時吃東西
6. 設定屬性:名字預設為Jack
7. 不透實體化,直接從老師類別呼叫上課的方法
---
### 試著應用觀念在 React 上
1. state 是屬性還是方法?
2. render 是屬性還是方法?
3. App 組件繼承誰?
4. 在 App 組件中新增一個方法 greet
5. 在 greet 方法中可以 console.log('hi')
6. 在 render 方法中呼叫 greet
---
### 回頭看看今天の學習目標
- ㄧ、 Components 進階
- 二、 Elements 常用元素
---
### ㄧ、Components 進階
---
### ㄧ、Components 進階
學習項目:
1. Default Props
2. Props Validation
3. render
---
### 1.Default Props
props 接收資料大致可以分成三種方式:
- 直接給 props 資料
- 預設 props 有資料
- 從狀態傳給 props 使用
---
### 1.Default Props
直接給 props 資料,把資料寫死。
App.js
```jsx=
<Example list={['吃', '喝', '拉', '撒', '睡']} />
```
Example.js
```jsx=
class Example extends React.Component {
render() {
return (
<div>
{this.props.list}
</div>
);
}
}
```
---
### 1.Default Props
defaultProps:預設 props 有資料
App.js
```jsx=
<Example />
```
Example.js
```jsx=
class Example extends React.Component {
render() {
return (
<div>
<p>NAME: {this.props.name}</p>
</div>
);
}
}
Example.defaultProps = {
name: 'Jack',
}
```
---
### 1.Default Props
state:從狀態傳給 props 使用
App.js
```jsx=
<Example list={this.state.list}>
```
Example.js
```jsx=
class Example extends Component {
render() {
return (
<ul>
{this.props.list.map(l => <li>{l}</li>)}
</ul>
)
}
}
export default TodoList;
```
---
### 1.Default Props 小試身手
1. 從 App.js 中新增一個狀態:todo項目清單物件陣列 [{name:'掃地', check: fasle}, ...]
2. 將 todo 傳入子組件(自行新增)
3. 在子組件中,利用 ul li 以及 checkbox 來顯示傳入的待辦清單
4. 在子組件中,如果沒傳入陣列則預設 props [{name:'拖地', check: true}]
---
### 2.Props Validation
用於 props 型別定義與檢查。
---
### 2.Props Validation
很不幸的是... 15.5 之後版本已經.....[棄用](https://react.docschina.org/docs/typechecking-with-proptypes.html)

---
### 2.Props Validation
[prop-types](https://www.npmjs.com/package/prop-types) - 定義 Props 的型態
```shell=
yarn add prop-types
```
---
### 2.Props Validation
- PropTypes.資料型態(.isRequire)
- isRequire 是代表這個資料必須要有對應值
Example.js
```jsx
Example.propTypes = {
name: PropTypes.string,
list: PropTypes.array.isRequired,
isDone: PropTypes.bool.isRequired,
onAdd: PropTypes.func,
age: PropTypes.number,
}
```
---
### 2.Props Validation
如果不符合規範:

---
### 3.render
五種不同的條件渲染(Conditional Rendering)
ps. 切換到程式碼
1. javascript if
2. element variables
3. logical && operator
4. conditional operator
5. preventing component from rendering
6. (補充) method
---
### 3.render 自己做做看
- 建立組件 Header
- 根組件 App.js 狀態有 login
- 將根組件 App.js 的狀態 login 傳入 Header
- 當有登入時 Header 顯示 Hello Jack
- 沒登入時 Header 顯示 Welcome
- 都沒有傳入 login 狀態時,利用 defaultProps 設定 login 來預設顯示 Welcome
---
### 二、Elements 常用元素
---
### 二、Elements 常用元素
程式實作:
1. checkbox
2. radio
3. select ... option
---
### 二、Elements 常用元素 - 哩做跨買ㄟ拉
1. 在 App 根組件中建立狀態: gender 預設男, pass 預設false
2. 在 App 根組件中建立 性別 radio 男女 綁定 gender
3. 在 App 根組件中建立 歐趴 checkbox 綁定 pass
4. 建立 Message 組件
5. 當性別是男生時,Message 顯示「先生您好」,否則顯示「小姐您好」
6. 當歐趴時,Message 顯示「恭喜」,否則顯示「明年當學弟」
7. 當歐趴時,Message 所有字體顏色為綠色,否則紅色
---
### 學習重點整理
- ㄧ、 Components 進階
- 二、 Elements 常用元素
---
### 今天你都學會了嗎
- [ ] 我知道怎麼用 Class 寫類別,以及屬性與方法。
- [ ] 我會在 render 方法中渲染 JSX
- [ ] 我會解釋何謂 state 和 props
- [ ] 如果 props 提取不到我要的屬性,我會寫預設屬性
- [ ] 我會使用 state 來綁定 button, input, select
- [ ] 我會建立父子組件,並利用 props 傳資料
- [ ] 我知道方法與以及函式的差異
---
### 方法的呼叫你清楚了嗎?
```javascript=
class App extends Component {
hi() {
console.log(this)
}
hello = () => {
console.log(this)
}
render() {
return (
<div>
<button onClick={() => console.log('hi')}>Button</button>
<button onClick={() => this.hi()}>Button</button>
<button onClick={() => this.hello()}>Button</button>
<button onClick={this.hi}>Button</button>
<button onClick={this.hello}>Button</button>
</div>
)
}
}
```
---
# END
{"metaMigratedAt":"2023-06-14T20:22:38.804Z","metaMigratedFrom":"YAML","title":"(H)尊絕不凡 React 教學","breaks":true,"contributors":"[{\"id\":\"36ba3409-97a0-4c0c-b357-4b738f6b17ad\",\"add\":12378,\"del\":5849}]"}