用于redux控制异步action
npm install --save redux-saga
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
});
}
在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会同时监控,不会等待先后
};
在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中的操作;
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';
使用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);