React 实践项目 (三) Redux-Saga

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_SUCCESS action 照样LOGIN_USER_FAILURE action

接下来,我们来完成这个流程

  • 建立 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 另有许多巧妙的处所,人人能够自行探究。

完全项目代码地点

    原文作者:Yuicon
    原文地址: https://segmentfault.com/a/1190000010205210
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞