React 實踐項目 (三)

来源:http://www.cnblogs.com/yuicon/archive/2017/07/16/7189942.html
-Advertisement-
Play Games

React在Github上已經有接近70000的 star 數了,是目前最熱門的前端框架。而我學習React也有一段時間了,現在就開始用 React+Redux 進行實戰! 上回說到使用Redux進行狀態管理,這次我們使用Redux-saga 管理 Redux 應用非同步操作 React 實踐項目 ( ...


React在Github上已經有接近70000的 star 數了,是目前最熱門的前端框架。而我學習React也有一段時間了,現在就開始用 React+Redux 進行實戰!

上回說到使用Redux進行狀態管理,這次我們使用Redux-saga 管理 Redux 應用非同步操作

React 實踐項目 (一)

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_USER action,Sagas 監聽到 LOGIN_USER action,發起一個 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 還有很多奇妙的地方,大家可以自行探索。
完整項目代碼地址:https://github.com/DigAg/digag-pc-react


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前兩篇《JVM入門——運行時數據區》《JVM常見垃圾回收演算法》所提到的實際上JVM規範以及常用的垃圾回收演算法,具體的JVM實現實際上不止一種,有JRockit、J9等待,當然最有名當屬HotSpot JVM。下麵是HotSpot JVM的整體架構圖,本文著重介紹HotSpot中的垃圾回收器(Garb ...
  • 1.何為列表 1.1 列表作為序列(sequence)的一種,是一組有順序的元素的集合。 1.2 列表是Python中最常用的內置數據類型,用中括弧[元素1,元素2...]括起,以逗號分隔,元素之間沒有任何關係,可以是任何類型。 2.列表的聲明與訪問 3.列表中元素的修改、添加和刪除 3.1 修改列 ...
  • Python網路數據採集3 數據存到CSV以及MySql 先熱熱身,下載某個頁面的所有圖片。 https://www.pythonscraping.com/sites/default/files/lrg_0.jpg http://pythonscraping.com/img/lrg%20(1).jp ...
  • 最近有人問我 系統設計的原則,事實上不論今天各個技術棧怎麼演化,那些本質的原則與方法不會變, 讓我們回顧一下 這些原則:•分散關註 Separation of concerns. Divide your application into distinct features with as littl... ...
  • javascript的面向對象 面向對象的特點分為三類:繼承 封裝 多態 首先你得理解面向過程:假如把一件東西放到一個箱子里,面向過程就是第一部打開箱子,然後把東西放進去,然後關閉箱子: 面向對象:就是把箱子看成一個對象,這個對象有屬性比如說長寬高尺寸這些,他還有一個功能就是裝東西.裝東西這個就I相 ...
  • 1.圖片放大鏡的思路: 當打開頁面時只有圖片 首先,說一下基本效果和調理,圖片放大鏡,也就是當你滑鼠移入當前的商品圖片時,會出現一個小灰色的觀察移動框,有點會出現一個對應部位的放大的圖片。 然後當滑鼠移動時,右邊的放大鏡會出現對應部位的放大圖片 最後當滑鼠移開後,小的觀察框和放大的圖片都會消失。 2 ...
  • 1. 你曾經是否說想要 高度占頁面或者占div百分比無效的問題,相信你也搜索過了,就是說 需要 設置父親父親一直到祖宗html都要設置百分比,才有效果。 總之一句話:想用百分比設置他的高度,則它的父親中至少有一個是固定高度,不然的話 全部父親直到祖宗html(因為html外面就是瀏覽器,它是有高度的 ...
  • 經常會用到的es6的知識點 提到es6我們就來說說javascript,es6也是ES2015 1. 1995:JavaScript誕生,它的初始名叫LiveScript。 2. 1997:ECMAScript標準確立。 3. 1999:ES3出現,與此同時IE5風靡一時。 4. 2000–2005 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...