在上一篇 redux在react-native上使用(一)--加入redux 已成功把redux
添加到項目, 如今再把redux-saga
添加進來.react
這篇 redux在react-native上使用(三)--加入redux-thunk 是使用redux-thunk
, 能夠跟這篇作個對比看下redux-thunk
和redux-saga
使用上的區別.npm
這一次作個跑秒器. 點擊開始
按鈕就開始跑秒,點擊中止
按鈕中止跑秒, 點擊重置
按鈕時間就清零. 跑秒狀態下數字爲藍色,中止狀態下爲黑色.json
先在package.json
裏添加redux-saga
庫, 並在目錄下npm install
:redux
"dependencies": { ... "redux-saga": "^0.11.0" },
把action
名字改得更有意義點, actionsTypes.js
:segmentfault
export const START = 'START'; export const STOP = 'STOP'; export const RESET = 'RESET'; export const RUN_TIMER = 'RUN_TIMER';
actions.js
跟着改:react-native
import { START, STOP, RESET, RUN_TIMER } from './actionsTypes'; const start = () => ({ type: START }); const stop = () => ({ type: STOP }); const reset = () => ({ type: RESET }); const runTime = () => ({ type: RUN_TIMER }); export { start, stop, reset, runTime }
reducers.js
在action
改變後也須要調整:promise
import { combineReducers } from 'redux'; import { START, STOP, RESET, RUN_TIMER } from './actionsTypes'; // 原始默認state const defaultState = { seconds: 0, runStatus: false } function timer(state = defaultState, action) { switch (action.type) { case START: return { ...state, runStatus: true }; case STOP: return { ...state, runStatus: false }; case RESET: return { ...state, seconds: 0 }; case RUN_TIMER: return { ...state, seconds: state.seconds + 1 }; default: return state; } } export default combineReducers({ timer });
添加一個sagas.js
文件, 處理項目的業務邏輯:app
import { takeEvery, delay, END } from 'redux-saga'; import { put, call, take, fork, cancel, cancelled } from 'redux-saga/effects'; import { START, STOP, RESET, RUN_TIMER } from './actionsTypes'; import { stop, runTime } from './actions'; function* watchStart() { // 通常用while循環替代 takeEvery while (true) { // take: 等待 dispatch 匹配某個 action yield take(START); // 一般fork 和 cancel配合使用,實現非阻塞任務,take是阻塞狀態,也就是實現執行take時候,沒法向下繼續執行,fork是非阻塞的,一樣能夠使用cancel取消一個fork 任務 var runTimeTask = yield fork(timer); yield take(STOP); // cancel: 取消一個fork任務 yield cancel(runTimeTask); } } function* watchReset() { while (true) { yield take(RESET) yield put(stop()); } } function* timer() { try { while(true) { // call: 有阻塞地調用 saga 或者返回 promise 的函數,只在觸發某個動做 yield call(delay, 1000); // put: 觸發某個action, 做用和dispatch相同 yield put(runTime()); } } finally { if (yield cancelled()) { console.log('取消了runTimeTask任務'); } } } export default function* rootSaga() { yield fork(watchStart); yield fork(watchReset) }
把saga
做爲中間件添加進store
, store.js
以下:函數
import { createStore, applyMiddleware, compose } from 'redux'; import createSagaMiddleware, { END } from 'redux-saga'; import createLogger from 'redux-logger'; import rootReducer from './reducers'; import sagas from './sagas'; const configureStore = preloadedState => { const sagaMiddleware = createSagaMiddleware(); const store = createStore( rootReducer, preloadedState, compose ( applyMiddleware(sagaMiddleware, createLogger()) ) ) sagaMiddleware.run(sagas); store.close = () => store.dispatch(END); return store; } const store = configureStore(); export default store;
OK, 大功告成, commond+R
運行.spa