# React
## props
```
'${}' //模板字符串
(prop)=>{
document.title = `hello, ${props.name}` //name='abc'
}
console:"hello, John"
```
```
{`${item?.title}`} //顯示指定字串或賦值
defaultValue={`${item?.title}`}
key={`Item${item?.id}`}
```
## JCX
### Function
* 箭頭函數
```
const FunctionName = () => {
console.log(123);
};
```
* 匿名函數

* UUID
```
crypto.randomUUID() //可以產生唯一的ID
```
```
let uuid = self.crypto.randomUUID();
console.log(uuid);
```

### disabled 寫法
```
//判斷式
const isButtonDisabled = newTitle === '' || newDept === '';
<Button
disabled={isButtonDisabled}>
</Button>
```
## State
### import
```
import React, { useState } from 'react';
```
### 修改 state
:::info
state 的變數為 read-only,並不能用 this.state.變數=值直接修改state,而是必須要透過 React 預寫好的函式 setState() 來更改
:::
```
changePercent(){
this.setState({ percent:"70%" })
//percent 是變數
}
```
### 移除 state
將 state 指定為 undefined
```
this.setState({mounted: undefined});
```
### 新增物件

### 移除物件

## use state
```
變數型態 [state變數名稱, setState函式名稱] = useState(state變數初始值)
```

// 函式在語法上沒有限定命名原則,但一般會以set做為開頭
## useEffect
當 useState 或變數變動時,可以透過 useEffect 來監聽執行,而 useEffect 也是個通用的 Hook,如果找不到對應的 Hook 時也可以使用
```
useEffect(() => {
console.log(123);
})
```
* useEffect() 的第一個參數是函數,元件載入時會執行,每渲染一次,此函式就自動執行一次,在第一次載入頁面時,也會執行。
* useEffect() 的第二個參數,可以使用一個 Array 來指定 useEffect() 的資料,那只有資料發生變化時,就會從新渲染。
### useEffect() 常見用途
* 獲取資料/call API
* 事件的監聽或訂閱
* 改變 DOM 元素
* 輸出日誌
## useContext
:::info
一次做一件事,不要在useEffect()裡做多件事,例如 TodoList 有讀取、寫入、刪除,這三件事就需要寫成三個 useEffect()
:::
## Redux
1. ==state==:類似宣告變數,存放資料和狀態的地方。
2. ==reducer==:要修改 state 的話一定要透過 reducer。
3. ==action==:如要 reducer 有作用的話需傳入一個 action 去判斷要啟動哪個 reducer。
4. ==Provider==:在所有組件的最外面(通常是 Index.js)包一層Provider,傳入 store,被包覆的組件則可使用 store 的狀態。
5. ==store==:就是 state、reducer、action 的集合,換句話說,放 state、reducer、action 的那隻檔案就叫 store。
### 流程
1. 創建 Store,用來放置集中處理的資料與方法的地方。
2. 在最外層使用 Privider 把整個 App 包起來,讓全部的組件皆可以使用 Store 內的資料與方法。
3. 撰寫 slice,存放 states (資料)和 reducers (方法)。
4. 在專案內讀取這些資料或更新這些資料。
### state
```
const initState = {
name: 'Jack',
}
```
```
const reducer = (state = initState, action) => {
switch (action.type){
default:
return state
}
}
```
每一個 Reducer 都會有兩個參數,第一個參數會將初始的資料狀態 initState 交由 Reducer 保管,第二個參數會傳入現在 reducer 要對 state 做什麼動作的指令及額外的參數。
> 以上程式碼沒有任何 action 指令描述的 Reducer,所以預設回傳了它所保管的 state ,在這裡就是上方的 initState。
> console.log() // {name: 'Jack'}
### store
Reducer 創建完成後,需要交由 store ,而 store 的工作就是在應用程式中負責整合所有的 Reducer。
首先在 redux 中 import 負責創建 store 的函式 createStore ,並將 Reducer 傳入以創建一個 store。
```
const store = configureStore({ reducer: allReducers });
```
:::info
注意!每個專案都只能有一個 store 存在
:::
### Provider
把 provider 包在最外面,讓整個專案都可以存取到
(放在index.js也可以,只要是最外層就好)
```javascript
import { Provider } from "react-redux";
import store from "@/store";
function App() {
return (
<Provider store={store}>
//...
</Provider>
);
}
export default App;
```
### Slice
slice 是 toolkit的 概念,能將 Redux 原生的 state、reducer、action 都合在一包,稱為 slice。
1. createSlice 是 toolkit 的工具,如沒有使用 toolkit,就需要自行創建 states、reducers、actions。
2. 從 toolkit 引入 createSlice,創建的時候需要的物件有:
* ==initialState== : 狀態初始值,slice 只需要設定initialState,則不需設定 state。
* ==reducers== : 可放許多函式,會有參數 state、action,state 用來修改狀態,可直接對 state 進行操作,action 則用來傳入參數。
```javascript
import { createSlice } from "@reduxjs/toolkit";
export const todoSlice = createSlice({
name: "todo",
initialState: {
//...
},
reducers: {
//...
},
});
export default todoSlice.reducer;
```
補充:==push(action.payload)==,這是一個數組方法,用於將新的元素添加到 state.items 數組的末尾。在Redux中,通常是通過Action的payload來提供新的數據,以便更新應用程序的狀態。
## React Redux 函數
### **dispatch()**
將動作傳遞給 Redux store,以便觸發應用程式中的狀態更新
### **combineReducers()**
1. **將多個 reducer 組合成一個**: 在大型應用程式中,通常會有多個不同的 reducer,每個負責管理狀態的不同部分。combineReducers 允許你將這些 reducer 組合成一個根 reducer,它負責整合和分發動作,並處理整個應用程式的狀態。
2. **拆分狀態**: 通應用程式的狀態可以分為多個部分,每個部分對應一個 reducer。combineReducers 讓你在根 reducer 中指定每個部分的 reducer,並自動將它們的輸出整合為一個狀態對象。
```javascript
import { combineReducers } from 'redux';
import TodoListReduer from './TodoList';
import CounterReducer from './Counter';
const allReducer = combineReducers({
counter: counterReducer,
user: userReducer,
});
export default allReducer;
```
呼叫元件:
```
const 變數名稱 = useSelector(state => state.counter);
```
## RESTful API
* useEffect Hook:
通常會使用 useEffect() 來發送 API 請求,頁面在渲染過後便會執行 useEffect() 中的指令。
```
useEffect(() => {
// 在此獲取數據
}, []);
```
* useState Hook:
請求數據時,需要宣告狀態用來儲存往返的數據。
```
const [posts, setPosts] = useState([]);
```
React Rudex:呼叫 api 寫在 action.js 的 try() 裡面
### Fetch
* Fetch() 裡是強制參數,需填入路徑或 URL,返回後可使用 then() 和 catch() 的方式去處理成功和失敗。
```
import {useEffect} from "react";
const fetchData = () => {
return fetch("https://randomuser.me/api/")
.then((response) => response.json())
.then((data) => console.log(data));}
useEffect(() => {
fetchData();
}, []);
```
### Axios
```
import axios from “axios”
const fetchData = () => {
return axios.get(“https://randomuser.me/api/")
.then((response) => console.log(response.data));}
```
### [範例參考](https://www.freecodecamp.org/chinese/news/how-to-consume-rest-apis-in-react/)
## Next.js
## onBlur