當前位置:
首頁 > 知識 > React 實踐項目(三)

React 實踐項目(三)

- 首先我們來看看登陸的 Reducer

export const auth = (state = initialState, action = {}) => {
switch (action.type) {
case LOGIN_USER:
return state.merge({
"user": action.data,
"error": null,
"token": null,
});
case LOGIN_USER_SUCCESS:
return state.merge({
"token": action.data,
"error": null
});
case LOGIN_USER_FAILURE:
return state.merge({
"token": null,
"error": action.data
});
default:
return state
}
};

Sagas 監聽發起的 action,然後決定基於這個 action 來做什麼:是發起一個非同步調用(比如一個 Ajax 請求),還是發起其他的 action 到 Store,甚至是調用其他的 Sagas。

具體到這個登陸功能就是我們在登陸彈窗點擊登陸時會發出一個 LOGIN_USERaction,Sagas 監聽到LOGIN_USERaction,發起一個 Ajax 請求到後台,根據結果決定發起LOGIN_USER_SUCCESSaction 還是LOGIN_USER_FAILUREaction

接下來,我們來實現這個流程

  • 創建 Saga middleware 連接至 Redux store

在 package.json 中添加 redux-saga依賴

"redux-saga": "^0.15.4"

修改 src/redux/store/store.js

/**
* Created by Yuicon on 2017/6/27.
*/
import {createStore, applyMiddleware } from "redux";
import createSagaMiddleware from "redux-saga"
import reducer from "../reducer/reducer";

import rootSaga from "../sagas/sagas";

const sagaMiddleware = createSagaMiddleware;

const store = createStore(
reducer,
applyMiddleware(sagaMiddleware)
);

sagaMiddleware.run(rootSaga);

export default store;

Redux-saga 使用 Generator 函數實現

  • 監聽 action

創建 src/redux/sagas/sagas.js

/**
* Created by Yuicon on 2017/6/28.
*/
import { takeLatest } from "redux-saga/effects";
import {registerUserAsync, loginUserAsync} from "./users";
import {REGISTER_USER, LOGIN_USER} from "../action/users";

export default function* rootSaga {
yield [
takeLatest(REGISTER_USER, registerUserAsync),
takeLatest(LOGIN_USER, loginUserAsync)
];
}

我們可以看到在 rootSaga 中監聽了兩個 action 登陸和註冊 。

在上面的例子中,takeLatest 只允許執行一個 loginUserAsync 任務。並且這個任務是最後被啟動的那個。 如果之前已經有一個任務在執行,那之前的這個任務會自動被取消。

如果我們允許多個 loginUserAsync 實例同時啟動。在某個特定時刻,我們可以啟動一個新 loginUserAsync 任務, 儘管之前還有一個或多個 loginUserAsync 尚未結束。我們可以使用 takeEvery 輔助函數。

  • 發起一個 Ajax 請求
  • 獲取 Store state 上的數據

selectors.js

/**
* Created by Yuicon on 2017/6/28.
*/
export const getAuth = state => state.auth;

  • api

api.js

/**
* Created by Yuicon on 2017/7/4.
* https://github.com/Yuicon
*/

/**
* 這是我自己的後台伺服器,用 Java 實現
* 項目地址:https://github.com/DigAg/digag-server
* 文檔:http://139.224.135.86:8080/swagger-ui.html#/
*/
const getURL = (url) => `http://139.224.135.86:8080/${url}`;

export const login = (user) => {
return fetch(getURL("auth/login"), {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(user)
}).then(response => response.json)
.then(json => {
return json;
})
.catch(ex => console.log("parsing failed", ex));
};

  • 創建 src/redux/sagas/users.js

/**
* Created by Yuicon on 2017/6/30.
*/
import {select, put, call} from "redux-saga/effects";
import {getAuth, getUsers} from "./selectors";
import {loginSuccessAction, loginFailureAction, registerSuccessAction, registerFailureAction} from "../action/users";
import {login, register} from "./api";
import "whatwg-fetch";

export function* loginUserAsync {
// 獲取Store state 上的數據
const auth = yield select(getAuth);
const user = auth.get("user");
// 發起 ajax 請求
const json = yield call(login.bind(this, user), "login");
if (json.success) {
localStorage.setItem("token", json.data);
// 發起 loginSuccessAction
yield put(loginSuccessAction(json.data));
} else {
// 發起 loginFailureAction
yield put(loginFailureAction(json.error));
}
}

select(selector, ...args)用於獲取Store state 上的數據

put(action)發起一個 action 到 Store

call(fn, ...args)調用 fn 函數並以 args 為參數,如果結果是一個 Promise,middleware 會暫停直到這個 Promise 被 resolve,resolve 後 Generator 會繼續執行。 或者直到 Promise 被 reject 了,如果是這種情況,將在 Generator 中拋出一個錯誤。

Redux-saga 詳細api文檔

  • 結語

我在工作時用的是 Redux-Thunk, Redux-Thunk 相對來說更容易實現和維護。但是對於複雜的操作,尤其是面對複雜非同步操作時,Redux-saga 更有優勢。到此我們完成了一個 Redux-saga 的入門教程,Redux-saga 還有很多奇妙的地方,大家可以自行探索。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

包裝類、數組、string類淺析及練習
Hadoop源碼系列(一)FairScheduler申請和分配container的過程
Android系統——輸入系統(十五)實戰 使用GlobalKey一鍵啟動程序
MySql單表最大8000W+ 之資料庫遇瓶頸記
一顆簡單的JDBC栗子

TAG:達人科技 |

您可能感興趣

Accurate檢測項目和意義
Oculus啟動第三屆VR for Good計劃,繼續支持實驗性項目
項目評級——RewardMob
Blazor正式成為Microsoft官方.NET 和WebAssembly項目
Repulse Game Studio將推出第二個VR項目《伊拉貢》
Github 項目推薦 用PyTorch 實現 OpenNMT
Oculus公布首批VR影視創作者實驗室Creators Lab入選項目
一個lncRNA項目的實戰
谷歌Research和Google.ai合併 統一成全新AI項目
Exchange Union項目進展
Kickstarter升級Hardware Studio:讓投資者知道眾籌項目發展進度
GitHub項目 | PyTorch 中文手冊
SpaceX衛星互聯網項目Starlink大事記
Ether Universe項目評測:第四代跨鏈技術實現「異鏈」Tokens直接交換
lncRNA實戰項目-第五步-差異表達的mRNA和lncRNA
為刺激VR/AR領域發展 Digital Catapult再次啟動Augmentor項目
eBay推出「Always Open on eBay」項目
使用Jira software+Structure實現大規模跨團隊項目管理
教程 | 從零開始PyTorch項目:YOLO v3目標檢測實現(下)
國際 | Trump International Hotel & Tower New York(紐約)酒店翻新項目