一个现代的、使用了redux的前端应用架构可以这样描述:
const render = (state) => components
const reducer = (oldState, action) => newState
现在,测试这个saga就非常的容易了:
import { call, put } from 'redux-saga';
const mySaga = loadTodos();
const myTodos = [{ message: 'text', done: false }];
mySaga.next();
expect(mySaga.next().value).toEqual(put({ type: 'FETCH_TOTOS' }));
expect(mySaga.next().value).toEqual(call(fetch, '/todos'));
expect(mySaga.next().value).toEqual(put({ type: 'FETCH_TODOS', payload: myTodos }));
thunk的action creator在分发它返回的方法的时候就会触发。saga不同,它们就像是运行在后台的守护任务(daemon task)一样有自己的运行逻辑(by Yasine Elouafi redux-saga的作者)。
所以,我们来看看如何在redux应用里添加saga。
import { createStore, applyMiddleware } from 'redux';
import sagaMiddleware from 'redux-saga';
const createStoreWithSaga = applyMiddleware(
sagaMiddleware([loadTodos])
)(createStore);
let store = createStoreWithSaga(reducer, initialState);
一个saga本身就是一个副作用,就如同redux的reducer一样,绑定saga非常简单(但是很好的理解ES6的generator是非常有必要的)。
在之前的例子里,loadTodos
saga在一开始就会触发。但是,如果我们想要每次一个action分发到store的时候触发saga要怎么做呢?看代码:
import { fork, take } from 'redux-saga';
function* loadTodos() {
yield put({ type: 'FETCHING_TODOS' });
const todos = yield call(fetch, '/todos');
yield put({ type: 'FETCHED_TODOS', payload: todos });
}
function* watchTodos() {
while(yield take('FETCH_TODOS')) {
yield fork(loadTodos);
}
}
// 我们需要更新saga常量 createStoreWithSaga = applyMiddleware(
sagaMiddleware([watchTodos])
)(createStore);
上例用到了两个特殊的effect:
take
effect,它会等待分发redux action的时候执行fork
effect, 它会触发另外一个effect,在子effect开始之前就会执行给前端应用添加redux和redux-saga的流程是这样的:
const render = (state) => components
const reducer = (oldState, action) => newState
原文链接:https://riad.blog/2015/12/28/redux-nowadays-from-actions-creators-to-sagas/
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。