React 实践项目 (三) Redux-Saga
上回说到使用Redux进行状态管理,这次我们使用Redux-saga 管理 Redux 应用异步操作React 实践项目 (一) - 首先我们来看看登陆的 Reducerexport 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。 具体到这个登陆功能就是我们在登陆弹窗点击登陆时会发出一个 接下来,我们来实现这个流程
在 package.json 中添加
修改 /** * 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 函数实现
创建 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 辅助函数。
selectors.js /** * Created by Yuicon on 2017/6/28. */ export const getAuth = state => state.auth;
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)); };
/** * 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)); } }
Redux-saga 详细api文档
完整项目代码地址 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |