# 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); }; ``` * 匿名函數 ![](https://hackmd.io/_uploads/rkB_h0VZp.png) * UUID ``` crypto.randomUUID() //可以產生唯一的ID ``` ``` let uuid = self.crypto.randomUUID(); console.log(uuid); ``` ![](https://hackmd.io/_uploads/HkjuGA4Za.png) ### 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}); ``` ### 新增物件 ![](https://hackmd.io/_uploads/BkEO8m6lp.png) ### 移除物件 ![](https://hackmd.io/_uploads/ryFUeJBWa.png) ## use state ``` 變數型態 [state變數名稱, setState函式名稱] = useState(state變數初始值) ``` ![](https://hackmd.io/_uploads/Bku0IJHbT.png) // 函式在語法上沒有限定命名原則,但一般會以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