---
tags: JPLS
---
# Redux-Saga Todo App
## 前置任務
使用 [IQ-React2](https://github.com/Robin98727/React_init) React 初始包,將教學範例 [react-todo](https://github.com/Robin98727/React_todo-app)將 todo 的資料改以 Redux 的 store 進行控制,並且熟悉以下項目:
* props and state
* redux store
* dispatch
* reducer
## Redux-Saga 任務
資料不總是存放在 store 裡面,接下來將有所改變。
store 的資料將存在遠端 server,因此我們必須使用 API 來對它進行操作
#### ❗ 接下來請在原本的 redux-todo-app 開一個 branch 開始進行這個任務
### 任務 1 - JS Fetch API
請熟悉 [Fetch API](https://developer.mozilla.org/zh-TW/docs/Web/API/Fetch_API) 的語法,它是一個使用 Promise chain 來進行 AJAX 呼叫的新 API,將使用它來進行 API 呼叫
**任務重點**
* [Fetch 範例](https://developer.mozilla.org/zh-TW/docs/Web/API/Fetch_API/Using_Fetch)
* 如何進行 GET, POST, DELETE, PUT 四種 method 的呼叫?
* 如何傳遞 JSON 資料到 server?
* 如何判斷呼叫失敗?
* 如何接收 server 回傳的資料,轉換成 JS 的 Object?
### 任務 2 - 使用 Fetch API
使用 Fetch API 呼叫 Todo Server 的 API,你可以直接在 Chrome 的開發人員工具 Console 中直接執行這段語法
```js
fetch('http://192.168.1.130:3001/items')
.then(d=>d.json())
.then(d=>console.log(d))
```
你將會得到一包 todo 資料
```json
[
{
"title": "6666666",
"completed": true,
"id": 1
},
{
"id": 3,
"title": "some title 3",
"completed": true
},
{
"id": 4,
"title": "some title 4",
"completed": false
},
{
"title": "test",
"completed": false,
"id": 5
}
"
```
#### 請使用自己的 API Server 進行測試
#### ➡️ Robin Todo API Server: http://192.168.1.130:3001/
> 把 API 前面的 URL 換成自己的即可
### [API 文件](https://documenter.getpostman.com/view/1684185/SVfTNnCx?version=latest)
**任務重點**
* 學會看 API 文件
* 使用 Fetch API 呼叫 4 個 API (使用自己的 URL)
* 取得代辦清單
* 新增代辦事項
* 編輯代辦事項
* 刪除代辦事項
### 支線任務 - 使用 Postman 測試 API
這個任務自行斟酌完成,學會使用 Postman 測試 API 可以協助前端開發人員快速了解 API 的運作
* [Postman - 測試 API 神器 1/2](https://ithelp.ithome.com.tw/articles/10201503)
* [Postman - 測試 API 神器 2/2](https://ithelp.ithome.com.tw/articles/10201528)
### 任務 3 - 將 Redux-Saga 加入目前的 App
將 [Redux-Saga](https://github.com/redux-saga/redux-saga) 加入目前的 APP,並熟悉它的配置
**任務重點**
* 了解 Redux-Saga 運作機制
* 了解 Redux-Saga 設定與配置
* 將 Redux-Saga 加入目前的 APP
### 任務 4 - 將 TodoApp 改為 Redux-Saga 版本
**任務重點**
* TodoApp 的 Todo 資料改為存取遠端 Server 的資料
* 將 Fetch API 整合到 TodoApp
* 將每個 TodoApp 原先的操作改以對應到呼叫 API 來進行存取
* 撰寫 saga 流程
* 所有的 action 與對應的 state 都要附加三狀態
* GET
* SUCCESS
* FAIL
* 畫面上要根據三狀態來進行適當的切換,例如
* 取得資料時要顯示: 載入中
* API呼叫失敗要顯示: 無法取得資料或失敗
#### 程式碼提示
**加入 saga 到 store**
```javascript
export default function configureStore(initialState) {
// ...
return {
...createStore(
createRootReducer(history),
initialState,
compose(applyMiddleware(createSagaMiddleware())),
),
runSaga: sagaMiddleware.run,
}
}
```
**監聽 action**
`sagas/index.js`
```javascript
// 呼叫 API
function api(url){
return fetch(url).then(res=>{
if(res.ok) return res.json()
else return null
})
}
// 某個流程
function* my_saga(params) {
// params 可以拿到 action.GET 的資料
// const id = params.id
const data = yield call(api, 'http://www...')
if (data) {
yield put(action.success(data))
} else {
yield put(action.fail())
}
}
export default function* () {
// 監聽 action.GET
// 如果有人 dispatch(get({id:15}) 就會觸發流程
yield takeLatest(action.GET, my_saga)
}
```
接著只要將每個呼叫 API 的 Action 都加上三狀態,再配合上面的流程就完成了
* GET
* SUCCESS
* FAIL
### 任務 5 - 將 TodoApp 提交到 Gitlab
**任務重點**
* 寫完作業一定要有對應的技術 survey 學習文件 (hackmd)
* 將專案連結貼到 LINE 記事本
* [學習撰寫 README.md 來介紹你的專案](https://gitbook.tw/chapters/github/push-to-github.html)