React在Github上已經有接近70000的 star 數了,是目前最熱門的前端框架。而我學習React也有一段時間了,現在就開始用 React+Redux 來實戰吧!
React 實踐專案(一)
#React實作專案(二)
React 實作專案(三)
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_SUCCESS
action 或LOGIN_USER_FAILURE
action
redux-saga 依賴
修改
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:java;toolbar:false;">/**
* Created by Yuicon on 2017/6/27.
*/
import {createStore, applyMiddleware } from &#39;redux&#39;;
import createSagaMiddleware from &#39;redux-saga&#39;
import reducer from &#39;../reducer/reducer&#39;;
import rootSaga from &#39;../sagas/sagas&#39;;
const sagaMiddleware = createSagaMiddleware();
const store = createStore(
reducer,
applyMiddleware(sagaMiddleware)
);
sagaMiddleware.run(rootSaga);
export default store;</pre><div class="contentsignin">登入後複製</div></div>
Redux-saga 使用 Generator 函數實作
/** * 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 輔助函數。
/** * Created by Yuicon on 2017/6/28. */ export const getAuth = state => state.auth;
/** * Created by Yuicon on 2017/7/4. * */ /** * 这是我自己的后台服务器,用 Java 实现 * 项目地址: * 文档: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)); };
/** * 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)); } }
put(action)
發起一個action 到Storecall(fn, ...args)
呼叫fn 函數並以args 為參數,如果結果是一個Promise,middleware 會暫停直到這個Promise 被resolve,resolve 後Generator會繼續執行。 或者直到 Promise 被 reject 了,如果是這種情況,將在 Generator 中拋出錯誤。 Redux-saga 詳細api文檔
以上是關於React 實作專案的範例詳解 (三)的詳細內容。更多資訊請關注PHP中文網其他相關文章!