React: Redux saga

Redux saga(Alternative to Thunk)

用于redux控制异步action

npm install --save redux-saga

saga+generator

auth.js

import {put} from 'redux-saga/effects';
import * as actionTypes from '../actions/actionTypes';

export function* logoutSaga(action){
  yield localStorage.removeItem('token');
  yield localStorage.removeItem('expirationDate');
  yield localStorage.removeItem('userId');
  yield put({
    //调用dispatch action
    type:actionTypes.AUTH_LOGOUT
  });
}

hook Saga to Store

在index中对astore设置middleware——saga;
index.js

import createSagaMiddleware from 'redux-saga';
import {logoutSaga} from './store/sagas/auth';

run单个函数;

const sagaMiddleware = createSagaMiddleware()

const store = createStore(rootReducer, composeEnhancers(
    applyMiddleware(thunk,sagaMiddleware)
));

sagaMiddleware.run(logoutSaga);

将run中的函数写为多个监听——takeevery

const sagaMiddleware = createSagaMiddleware()

const store = createStore(rootReducer, composeEnhancers(
    applyMiddleware(thunk,sagaMiddleware)
));

sagaMiddleware.run(watchAuth);

watchauth中的监听:

import {takeEvery} from 'redux-saga/effects'
import {logoutSaga, checkAuthTimeout, authUserSaga} from './auth';
import * as actionTypes from '../actions/actionTypes';

export function* watchAuth(){
  yield takeEvery(actionTypes.AUTH_INITIATE_LOGOUT, logoutSaga);
          //每次调用该action  运行logoutSaga函数
  yield takeEvery(actionTypes.AUTH_CHECK_TIMEOUT,checkAuthTimeout);

  yield takeEvery(actionTypes.AUTH_USER,authUserSaga);
  //yield会同时监控,不会等待先后
};

sideEffects——localstorage

在sagas中设置index.js,使用takeevery对action进行监控

import {takeEvery} from 'redux-saga/effects'
import {logoutSaga} from './auth';
import * as actionTypes from '../actions/actionTypes';

export function* watchAuth(){
  yield takeEvery(actionTypes.AUTH_INITIATE_LOGOUT, logoutSaga);
          //每次调用该action  运行logoutSaga函数
}

对actiontypes中的action进行监控,每次dispatch该action,执行logoutsaga中的操作;

将checkauthtime转为saga

thunk中的checkauthtime

export const checkAuthTimeout = (expirationTime) => {
    return dispatch => {
        setTimeout(() => {
            dispatch(logout());
        }, expirationTime * 1000);
    };
};

在auth.js中建立saga
delay相当于settimeout——进行异步等待;

export function* checkAuthTimeout(action){
    yield delay(action.expirationTime * 1000);//传入function
    yield put(actions.logout());
    //加括号,因为logout为action creator,需要先运行create一个action
}

在index.js saga中进行监听

import {takeEvery} from 'redux-saga/effects'
import {logoutSaga, checkAuthTimeout} from './auth';
import * as actionTypes from '../actions/actionTypes';

export function* watchAuth(){
  yield takeEvery(actionTypes.AUTH_INITIATE_LOGOUT, logoutSaga);
          //每次调用该action  运行logoutSaga函数
  yield takeEvery(actionTypes.AUTH_CHECK_TIMEOUT,checkAuthTimeout);

  //yield会同时监控,不会等待先后
};

原本的checkauthtime作为简单的actioncreator,返回一个action

export const checkAuthTimeout = (expirationTime) => {
    // return dispatch => {
    //     setTimeout(() => {
    //         dispatch(logout());
    //     }, expirationTime * 1000);
    // };
    return {
        type:actionTypes.AUTH_CHECK_TIMEOUT,
        expirationTime:expirationTime
    }
};

在actiontype中增加saga的actiontype即可

export const AUTH_CHECK_TIMEOUT='AUTH_CHECK_TIMEOUT';

将axios调用转为saga

使用yield进行异步调用;
使用try——catch进行异常捕获;

export function* authUserSaga(action){
    yield put(actions.authStart());//dispatch(authStart());
        const authData = {
            email: action.email,
            password: action.password,
            returnSecureToken: true
        };
        let url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=AIzaSyAgMGjA4YKyl3D957SXERhcyGEgUbqZUwk';
        if (!action.isSignup) {
            url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=AIzaSyAgMGjA4YKyl3D957SXERhcyGEgUbqZUwk';
        }
        try{
          const response= yield axios.post(url, authData)
          const expirationDate =yield new Date(new Date().getTime() + response.data.expiresIn * 1000);
          yield localStorage.setItem('token', response.data.idToken);
          yield localStorage.setItem('expirationDate', expirationDate);
          yield localStorage.setItem('userId', response.data.localId);
          yield put(actions.authSuccess(response.data.idToken, response.data.localId));
          yield put(actions.checkAuthTimeout(response.data.expiresIn));
        }catch(err){
          yield put(actions.authFail(err.response.data.error));
        }
}

将所需参数传入该type;

export const auth = (email, password, isSignup) => {
    return{
        type:actionTypes.AUTH_USER,
        email:email,
        password:password,
        isSignup:isSignup
    }
};

监听type,运行函数;

  yield takeEvery(actionTypes.AUTH_USER,authUserSaga);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值