###### tags: `前端課程`
# React筆記
## DOM (Document Object Model)
文件物件模型,把HTML文件的各個標籤定義成物件,這些物件最終會形成一個樹狀結構。
例:
document.getElementById就是用id在向DOM取得元素

## JSX
JavaScript 的語法擴充,屬性名稱以小駝峰方是撰寫。
```javascript===
const element = <h1>你好,世界!</h1>;
```
上面的標籤語法不是一個字串也不是HTML。
而是把右邊的HTML當成一個物件存到變數中。
這種把HTML寫在JavaScript的程式碼中的技術
```javascript=
const showOne=true;
const element = <h1>{showOne?1:0}</h1>
```
可以在HTML標籤中利用「{}」寫JavaScript表示式
```javascript=
const styleArgument = { fontSize: '100px', color: 'red' };
ReactDOM.render(
<h1 style = { styleArgument } > Hello, world! </h1>,
document.getElementById('root')
);
```
style變為一物件、屬性名稱規則改用駝峰法(用大寫區隔)、屬性的值變成字串
## Scss
1. 巢狀結構
```javascript==
#banner{
...
#logo{ // 等同於 #banner #logo
...
img{ // 等同於 #banner #logo img
...
}
}
nav{ //等同於 #banner nav
...
}
}
```
2. &連接
```javascript==
a{
color:red;
&:hover{ //等同於 a:hover
color:red;
}
&:active{ //等同於 a:active
color:blue;
}
}
```
## ES5/ES6/ES7
### ES5
* 嚴格模式
https://medium.com/itsems-frontend/javascript-strict-mode-d0a3aa74458b
* Array/Object操作的方法
* Array.find
* Array.filter
* Array.map
* ...
### ES6
* **箭頭函式 Arrow Functions**
```javascript==
//不帶參數
//ES5
function func_name(){
console.log('Hello World!');
}
//ES6
func_name = () =>{
console.log('Hello World!');
}
//帶一個參數
//ES5
function func_name(e){
console.log(e);
}
//ES6
func_name = e =>{
console.log(e);
}
//帶兩個(含)以上參數
//ES5
function func_name(e,i){
console.log(e,i);
}
//ES6
func_name = (e,i) =>{
console.log(e,i);
}
//關於return
func_name = () => something
func_name = () =>{
return something;
}
```
* **參數預設 Default Parameters**
傳入function的參數沒有給定值時,會出現Exception,最快的解決方法就是給定預設值,在ES6中給定預設值的方式更為快速簡單
```javascript==
BMI=(height=1.75, weight=65) => {
let BMI=weight/(height^2);
console.log(BMI);
}
```
* **文字模板 Template Literals**
```javascript==
// ES5
var name='Jack';
var start = 'Hello'+name+'!';
//ES6
const name='Jack'
const start = `Hello ${name}!`
```
* **多行字串輸入 Multi-line Strings**
```javascript==
// ES5
var fruit =
'apple,' +
'banana'
//ES6
const fruit =
`apple,
banana`
```
* **解構賦值 Destructuring Assignment**
```javascript==
const Jack={age:40,gender:'male'};
//一般
console.log(Jack.age,Jack.gender);
//解構
const {age,gender}=Jack;
console.log(age,gender);
//console結果:40male
//賦值
const Jack {age:x} = {age:40}; //x=40
```
* **物件實字 Enhanced Object Literals**
假如object內的元素其key與value名稱一樣,可以省略key直接寫 value 名稱即可。
```javascript==
// ES5
var name = 'Jack';
var obj = {
name: name
};
// ES6
const name = 'Jack';
const obj = { name };
```
* **宣告 Let and Const**
* let可變動
* const不可變動,宣告時要給定initialize
```javascript==
//let
let a;
a=10;
console.log(a);
a=20;
console.log(a);
//const
const b=100;
console.log(b);
//下面可以拿掉註解測試看看
//b=200;
//console.log(b);
```
* **Modules**
import、export
## JSON
* **包含Array、Object**
* **成對的key:value,中間以:區隔**
* **value可以是:**
* 數字 (整數或浮點數)
* 字串 (請用 "" 括號)
* 布林函數 (boolean) (true 或 false)
* 陣列 (請用 [ ])
* 物件 (請用 { })
* NULL
## Node.js安裝環境
https://nodejs.org/en/

## Nvm安裝包
下載nvm-setup.zip
https://github.com/coreybutler/nvm-windows/releases/tag/1.1.7
## nvm(node version manger)
管理、切換node版本
#### 常用指令
* nvm ls:列出所有已安裝的node版本,前面有標`*`是目前使用的版本
* nvm install `<version>`:安裝某個版本的 node
* nvm uninstall `<version>`:解除安裝指定版本
* nvm --version:查看nvm版本
* nvm use `<version>`:切換node版本
## npm(node package manger)
套件管理工具可以下載各種應用,安裝nodejs的時候就會一起安裝了
#### 常用指令
* npm install:尋找該資料夾裡面的package.json去下載裡面定義好的所有套件
* npm init:專案初始化讀取package.json的資訊
* package.json
1. dependencies: 執行環境會需要
2. devDependencies: 開發或測試環境需要
* npm start:本地運行專案
* npm run build:將專案打包成webpack
## React
將程式元件化,由很多元件組成UI畫面,每個元件透過render渲染出樣式,渲染完成後根據資料的改變去變動網頁內容,不需要去刷新頁面
**優點:程式碼不用重複寫、網頁風格統一、修改方便**
https://ithelp.ithome.com.tw/m/articles/10271212
### Class Component
具有生命週期,具有State,需要引入React Component,一定要實作render
https://ithelp.ithome.com.tw/m/articles/10232421
https://ithelp.ithome.com.tw/m/articles/10219057
```javascript=
import React, { Component } from "react";
import "./index.scss"
export default class NewsCard extends Component {
constructor(props) {
super(props)
}
render() {
const { cardImg, cardTitle, cardContent } = this.props;
return (
<div className="card">
<div className="newsImg">
<img src={cardImg} />
</div>
<div className="cardTitle">{cardTitle}</div>
<span>{cardContent}</span>
<div className="link">
<a href="">VIEW MORE</a><div className="line"></div>
</div>
</div>
);
}
}
```
```javascript=
import NewsCard from "../../Component/NewsCard";
<NewsCard
cardImg={item.cardImg1}
cardTitle="滑順不偏移 上下導輪鉸鏈"
cardContent="台灣每年台灣每年台灣每年台灣每年台灣每年台灣每年都會迎來"
/>
<NewsCard
cardImg={item.cardImg2}
cardTitle="abcdefg"
cardContent="happy birthday to you"
/>
```
### Functional Component
沒有生命週期,沒有State
```javascript=
function Functional(props) {
const sayHi =()=>{
console.log('hi')
}
return <button onClick={sayHi}>btn</button>
}
```
不過在Hook出現後functional Componet 也具有生命週期以及State
### props & state
#### props
React父元件與子元件間溝通的橋樑,是靜態(唯讀)的
#### state
元件存放資料的地方,以物件的方式存放(key:value),需要在constructor建立自身state,並且利用setState去改變state的值
```javascript=
constructor(props) { //若要使用這個方法
super(props) //必須先執行super(props),若有用到props的話會找不到this.props,沒用到props也可以只寫super()
this.state = {
currentPage: 'one', //給預設值
}
}
this.setState({
currentPage:'two'
})
```
### 生命週期

[**React Component 官方文件**](https://zh-hant.reactjs.org/docs/react-component.html)
* constructor :用來初始化的地方,還沒渲染DOM的時候,假設沒有寫super() ,無法使用this
* render:會進行渲染的,回傳JSX
* componentDidMount: DOM已經渲染完成 ,在這個階段可以呼叫api來更新DOM ,適合做一些初始化的工作
* componentDidUpdate: 當props or state更新,就會觸發元件更新DOM,所以如果在這個階段setState會造成無限循環
* componentWillUnmount: 元件從DOM被移除 ,在這階段可以用來清除一些計時器
* getDerivedStateFromProps: 會在「每一次」跑 render() 之前被呼叫執行,當props、state改變就會觸發,在初始化的時候也會觸發一次
### Hook
不必寫class就可以使用state
#### useState & useEffect
```javascript=
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// 與 componentDidMount 和 componentDidUpdate 類似:
useEffect(() => {
// 使用瀏覽器 API 更新文件標題
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
```
### 專案架構 & 資料流 & Router
#### 專案架構
|
---- /node_modules 套件安裝在這裡面
|
---- /public 靜態網頁
|
---- /src
|
---- /assets 圖片
|
---- /components 元件庫
|
---- /layouts 頁面框架
|
---- /mixin 通用css
|
---- /pages 頁面
|
---- /reducers 存取api回傳的資料
|
---- /routes 設定網頁路徑資料
|
---- /sagas 之funciton
|
---- /services 存放api路徑及參數
|
---- /utils 工具庫(存放通用fuction)
|
---- /config.js 撰寫api路徑之前綴
|
---- /index.js 進入點
|
---- /index.scss
|
---- /Router.js 指路標
|
---- /.env 設定檔
|
---- /.env.exapmle 設定檔範例
|
---- .gitignore 忽略不上傳git的檔案
|
---- package-lock.json 記錄本次安裝的套件版本
|
---- package.json 記錄所有安裝的套件與版本
|
---- README.md
#### 資料流
npm start
index.js->Router(引入設定好的所有路徑/routes檔)->導向對應的layout和page->
saga->service->reducer->page
* connect(mapStateToProps, mapDispatchToProps)
* import { put, takeLatest, call, all } from "redux-saga/effects";
* yield
### 常用套件
#### Lodash
* _.find
* _.filter
* _.map
* _.get
#### moment
```javascript==
moment(<value>).format("YYYY-MM-DD HH:mm:ss")
```
#### PrimeReact
https://www.primefaces.org/primereact/setup/
#### Mantine
https://mantine.dev/getting-started/
#### Bootstrap
https://react-bootstrap.github.io/components/alerts
#### leaflet
https://react-leaflet.js.org/
