
---
# (E)尊絕不凡 React 教學
## - 第一週
---
### 很感謝大家都「願意」來上課。
---
### 忍忍,很快就過去了。
---
我是接下來的講者
### 吳其聯 Robby
- Github [https://github.com/explooosion](https://github.com/explooosion)
- Blog [https://dotblogs.com.tw/explooosion](https://dotblogs.com.tw/explooosion)
---
### 在開始前
1. 盡量不要晃動。
2. 如果覺得很難是正常的。
3. 如果看不懂沒關係,再讀一次,相信我。
4. 建議做筆記。
---
### 學習目標
1. 現代WEB開發觀念(since 2009)
2. React 介紹與環境
3. React TodoList
---
### 環境確認
1. node.js
2. git
3. yarn
4. vscode
5. wifi
6. Windows 關閉自動更新
---
### VScode Extension
1. Auto Rename Tag
2. Babel ES6/ES7
3. DotENV
4. ESLint (`npm install eslint -g`)
5. FileNameComplete
6. HTML Snippets
7. IntelliSense for CSS class names in HTML
8. Path Intellisense
9. Sass
---
### Chrome Extension
1. [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)

---
# 開始上課囉
---

---
### 在什麼都不懂前
我們先體驗看看 React
- [facebook/create-react-app](https://github.com/facebook/create-react-app)
請大家輸入以下指令:
```shell=
npx create-react-app my-app
cd my-app
npm start
```
---
#### 靜態不好看,給你看動態的。

---
#### 指令說明

---
## 到 vscode 介紹環境
小抄:
1. 目錄結構
2. package
3. entrypoint
4. index.html
5. index.js
---
## 現代化 Web 開發觀念
---
### 名詞與套件解釋
1. 模組化
2. ES6+
3. SPA
4. Webpack
5. Babel
6. ESLint
---
#### 開始講歷史

---
#### 1. 模組化 - 無模組化
- jQuery 2006年1月釋出
- 嚴重的污染問題。
```htmlmixed=
<script src="jquery.js"></script>
<script src="jquery_scroller.js"></script>
<script src="main.js"></script>
<script src="other1.js"></script>
<script src="other2.js"></script>
<script src="other3.js"></script>
```
---
#### 1. 模組化 - CommonJS 規範

---
#### 1. 模組化 - CommonJS 規範
- Mozilla 工程師Kevin Dangoor 於2009年1月創建 ServerJS
- 2009年8月,改名為CommonJS(革命)
- 為了解決JavaScript 作用域問題
- 適用於伺服器端,同步處理
- Node.js 使用此規範
---
#### 1. 模組化 - CommonJS 規範
在JS中新增「require」以及「export」物件。
建立
```javascript=
// a.js
var x = 5;
var addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX;
```
引入
```javascript=
var example = require('./a.js');
console.log(example.x); // 5
console.log(example.addX(1)); // 6
```
---
### 1. 模組化 -ES6 規範
- 2015年6月,ECMAScript2015 發布 ES6
- 利用 import、export 就可以模組化
- 但目前大多(99%)瀏覽器和Node.js 不支援...
- 可以通過Babel 將寫好的 ES6 轉換為 ES5
---
#### 1. 模組化 - ES6 規範
```javascript=
import store from '../store/index'
import { mapState, mapMutations, mapActions } from 'vuex'
import axios from '../assets/js/request'
import util from '../utils/js/util.js'
export default {
created () {
this.getClassify();
this.RESET_VALUE();
console.log('created' ,new Date().getTime());
}
```
---
#### 2. ES6 - map
- map() 方法會建立一個新的陣列,其內容為原陣列的每一個元素經由回呼函式運算後所回傳的結果之集合。
```javascript=
var array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// expected output: Array [2, 8, 18, 32]
```
---
#### 2. ES6 - filter
- filter() 方法會建立一個經指定之函式運算後,由原陣列中通過該函式檢驗之元素所構成的新陣列。
- 如果條件都不符合,**會是一個空的陣列**
```javascript=
var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]
```
---
#### 2. ES6 - find
- find() 方法會回傳第一個滿足所提供之測試函式的元素值。
- 都找不到則為 **undefined**。
```javascript=
var array1 = [5, 12, 8, 130, 44];
var found = array1.find(element => element > 10);
console.log(found);
// expected output: 12
```
---
#### 2. ES6 - 簡化屬性描述 (Shorthand Property Names)
```javascript=
function getStudent(chemistry, biology, mathematics) {
return {
// [屬性名稱] 與 [屬性值變數名稱] 相同的時候
chemistry: chemistry, // ES5 只能這樣做
biology, // ES6 可以此表示 biology: biology
math: mathematics , // 不同名稱當然就只能這樣囉
}
}
```
---
#### 2. ES6 - 解構賦值 (Destructuring Assignment)

---
#### 2. ES6 - 解構賦值 (Destructuring Assignment)
```javascript=
// [範例1] 在 function 中只取出需要的傳入值
var student = { name: 'chris', age: 15 }
showStudentInfoES6(student)
function showStudentInfoES6 ({ name, age: hisAge }) {
console.log('name: ', name) // -> name: chris
console.log('hisAge:', hisAge) // -> hisAge: 15
}
```
---
#### 2. ES6 - 模組 (Module)
```javascript=
/* utility.js */
const timeout = 200
function addNumber(...nums){
var result = 0
nums.forEach(function (number) {
result += number
})
return result
}
export {timeout, addNumber}
```
```javascript=
/* other.js */
import { addNumber } from './utility.js'
console.log(addNumber(1, 2)) // -> 3
```
---
#### 2. ES6 - 模組 (Module)
```javascript=
/* myComponent.js */
export default class MyComponent extends React.Component {
// ...
}
```
```javascript=
/* header.js */
import MyOwnNameComponent from './myComponent'
const header = props => {
return <div>
<MyOwnNameComponent />
</div>
}
export default header
```
---
#### 2. ES6 - 字串樣板 (String Template)
或稱文字樣板、樣版引擎
```javascript=
var first = 'chris', last = 'chen'
var _name = 'your name is ' + first + ' ' + last
var name = `your name is ${first} ${last}.`
console.log(name) // -> 'your name is chris chen.'
```
---
#### 2. ES6 - 箭頭函數 (Arrow Functions)
```javascript=
// 傳統的方法宣告方式
function square(value){
return value*value
}
// 使用 arrow function 改寫
// 參數: 使用 () 包住
// 內容: 寫在 {} 裡面
var square1 = (value) => {return value*value}
// 特定情境下使用 arrow function 可以更加精簡
// 參數: 只有在單個參數時才可以省略 ()
// 內容: 只有在單個 statement 且是回傳值時才可以省略 {} 及 return 文字
var square2 = value => value*value
// 若要直接回傳物件時,使用 () 包住物件即可
// 順便複習使用簡寫特性表示 {name:name, phoneNo:phoneNo}
var buildContact = (name, phoneNo) => ({name, phoneNo})
// 測試一下囉
console.log(square1(2)) // -> 4
console.log(square2(2)) // -> 4
console.log(buildContact('chris','0911123123'))
// -> {name:"chris", phoneNo: "0911123123"}
```
---
#### 3. SPA
Single Page Application(SPA)
單一頁面應用程式
1. Bundle
2. Router
3. SEO
4. F12
5. AJAX
---
#### 4. Webpack

---
#### 4. Wepback - 功能
1. 將你的 js 檔案 Bundle 變成單一的檔案
2. 在你的前端程式碼中使用 npm packages
3. 撰寫 JavaScript ES6 或 ES7+(需要透過 babel 來幫助)
4. Minify 或優化程式碼
5. 將 LESS 或 SCSS 轉換成 CSS
6. 使用 HMR(Hot Module Replacement)
---
#### 5. Babel@7.x.x
Babel is a JavaScript compiler.
Use next generation JavaScript, today.

---
#### 6. ESLint
ESLint 是一個 Javascript Linter,
他能確保你的程式碼品質在一定的水準之上。

---
#### 6. ESLint - 功能
1. 幫你找出語法錯誤
2. 確保你遵循最佳實踐
3. 提醒你刪掉多餘的程式碼
4. 統一基本的 coding style
---
#### 6. ESLint - 安裝
```shell=
npm install eslint -g
```

---
#### 6. ESlint - 規則
airbnb code style
```javascript=
// bad
var a = 1;
var b = 2;
// good
const a = 1;
const b = 2;
```
```javascript=
// bad
const item = new Object();
// good
const item = {};
```
---
#### 6. ESlint - 規則
```javascript=
const lukeSkywalker = 'Luke Skywalker';
// bad
const obj = {
lukeSkywalker: lukeSkywalker,
};
// good
const obj = {
lukeSkywalker,
};
```
---
#### 6. ESlint - 規則
```javascript=
// bad
const items = new Array();
// good
const items = [];
```
---
#### 6. ESlint - 規則
```javascript=
// bad
const name = "Capt. Janeway";
// bad - template literals should contain interpolation or newlines
const name = `Capt. Janeway`;
// good
const name = 'Capt. Janeway';
```
---
#### 6. ESlint - 參考聖經
[https://github.com/airbnb/javascript](https://github.com/airbnb/javascript)
---
### React 生態系(Ecosystem)入門簡介
---
#### React - logo

---
#### React - 簡介
- React專注於UI(View)。
- Facebook於2013年開源React。
---
#### React - 設計理念
1. Component-Based
2. Learn Once, Write Anywhere
---
### React 生態系(Ecosystem)入門簡介
---
#### React 生態系(Ecosystem)

- webpack
- react
- redux/flux
- react-router
---
### ReactJS 與 Component 設計入門介紹
---
### ReactJS 特性簡介
1. 基於元件(Component)化思考
2. 使用 JSX
3. 使用 Virtual DOM
4. Component 狀態機(State Machine)&生命週期(Life Cycle)
5. 一律重繪(Always Redraw)和單向資料流(Unidirectional Data Flow)
6. 在 JavaScript 裡寫 CSS:Inline Style
---
#### 1. Component

---
#### 1. 一般 React Component 撰寫
使用 ES6 的 Class
```jsx
// 注意元件開頭第一個字母都要大寫
class MyComponent extends React.Component {
// render 是 Class based 元件唯一必須的方法(method)
render() {
return (
<div>Hello, World!</div>
);
}
}
// 將 <MyComponent> 元件插入 id 為 app 的 DOM 元素中
ReactDOM.render(<MyComponent>, document.getElementById('app'));
```
---
#### 1. 一般 React Component 撰寫
使用 Functional Component 寫法
```jsx
const MyComponent = () => (
<div>Hello, World!</div>
);
// 將 <MyComponent> 元件插入 id 為 app 的 DOM 元素中
ReactDOM.render(
<MyComponent>,
document.getElementById('app')
);
```
---
#### 2. JSX 聲明式(Declarative)設計
```jsx
// 使用宣告式(Declarative)UI 設計很容易可以看出這個元件的功能
<MailForm>
```
```jsx
// <MailForm /> 內部長相
<form>
<input type="text" name="email" />
<button type="submit"></button>
</form>
```
---
#### 3. 使用 Virtual DOM

---
#### 4. Component 特性
1. State Machine: state 和 props(由父元素傳入)
2. Life Cycle: 可以在對應的時間點進行 Component 需要的處理
---
#### 5. 重繪和資料流
1. props 都是由父元素所傳進來,不能更改,若要更改 props 則必須由父元素進行更改
2. 當 React 發現 props 或是 state 更新時,就會重繪整個 UI
3. Flux, Redux
---
#### 6. CSS:Inline Style
```jsx=
const imgUrl = 'https://imgur/react.png'
const divStyle = {
color: 'red',
backgroundImage: 'url(' + imgUrl + ')',
}
ReactDOM.render(
<div style={divStyle}>Hello World!</div>,
document.getElementById('app')
)
```
---
#### 6. CSS:Inline Style
1. 駝峰式命名
2. 物件型式
```jsx=
const divStyle = {
color: 'red',
margin: '2px',
paddingLeft: '.5rem',
backgroundColor: '#0f0',
}
```
```jsx=
ReactDOM.render(
<div style={{ color: '#f00' }}>Hello World!</div>,
document.getElementById('app')
)
```
---
## JSX 簡明入門教學指南
---
#### JSX 結構
JSX並非一種全新的語言,而是一種語法糖(Syntatic Sugar)。
```htmlmixed=
// HTML 寫法
<form class="messageBox">
<textarea></teextarea>
<button type="submit"></button>
</from>
```
有開始和關閉。
```jsx=
// JSX 寫法
<MessageBox />
<MessageBox>
```
---
#### JSX 表達式
```jsx
var text = 'Hello React';
<h1>{text}</h1>
<h1>{'text'}</h1>
```
---
#### React Component
```jsx=
class App extends React.Component {
render() {
const msg = 'Hello React!';
return (
<div>
<p>{msg}</p>
<MessageList>
</div>
);
}
}
```
---
#### 結合原生 JavaScript 語法
```jsx
// const 為常數
const lists = ['JavaScript', 'Java', 'Node', 'Python'];
class App extends React.Component {
render() {
return (
<ul>
{lists.map((result, index) => {
return (<li key={index}>{result}</li>);
})}
</ul>);
}
}
```
---
#### 註解
由於 JSX 最終會編譯成 JavaScript,註解也一樣使用 // 和 /**/ 當做註解方式
```jsx
// 單行註解
/*
多行註解
*/
var content = (
<List>
{/* 若是在子元件註解要加 {} */}
<Item
/* 多行
註解
喔 */
name={window.isLoggedIn ? window.name : ''} // 單行註解
/>
</List>
);
```
---
#### 屬性
在 JSX 中使用 `className` 和 `htmlFor` 替代。
```jsx
class App extends React.Component {
render() {
return (
<div className="message">
<p id="pHello">Hello React!</p>
<label htmlFor="pHello">Hi</label>
</div>
);
}
}
```
---
#### 樣式使用
在 JSX 中使用外觀樣式方法如下,第一個 {} 是 JSX 語法,第二個為 JavaScript 物件。與一般屬性值用 - 分隔不同,為駝峰式命名寫法:
```jsx
<div
style={{ color: '#FFFFFF', fontSize: '30px'}}
>
</div>
```
---
#### 事件處理
事件處理為前端開發的重頭戲,在 JSX 中透過 inline 事件的綁定來監聽並處理事件(注意也是駝峰式寫法)
```jsx
<HelloMessage onClick={this.onBtn} />
```
更多事件: [Supported Events](https://reactjs.org/docs/events.html#supported-events)
---
#### Props, State

---
#### Props, State

---
#### Props, State

---
## 讓我們回到程式
#### 小抄
1. 介紹 react es6 class
2. 利用 state.title 設定 h1 text
3. 利用 state.counter 設定 input value
4. 利用 inline style 設定 h1 color
5. 建立 button onClick alert
6. 利用 button onClick 改變 input value
7. 顯示計數器增減
8. 設定倒數計時器 10秒後 alert
9. 展示各種不同的事件處理方式
---
#### 題外插曲,改使用 SCSS
- 官方的 create-react-app 已經幫我們寫好 webpack 設定。
- 今天不管是用哪一套預處理,直接安裝 node-sass 就可。
- 可以混搭 scss, sass, less ... 任你用。
```shell=
yarn add node-sass -D
```
---
#### SCSS 基礎知識
- Variables 變數

---
#### SCSS 基礎知識
- Nesting 巢狀結構

---
#### SCSS 基礎知識
- Mixins

---
#### SCSS 基礎知識
- Inheritance 繼承

---
#### SCSS 基礎知識
- @import

```sass=
@import "base/head";
@import "base/body";
@import "base/foot";
```
---
#### SCSS 基礎知識
- 算數

---
#### 撰寫 Todo

---
#### Todo 步驟
1. 靜態 todo
2. 動態列表
3. 新增
4. 刪除
5. 勾選
---
#### 學習總整理
1. JSX
2. Components
3. state, props
4. Inline-style
5. scss
---

---

---
# END
{"metaMigratedAt":"2023-06-14T20:22:03.427Z","metaMigratedFrom":"YAML","title":"(E)尊絕不凡 React 教學","breaks":true,"contributors":"[{\"id\":\"36ba3409-97a0-4c0c-b357-4b738f6b17ad\",\"add\":17737,\"del\":4236}]"}