OneArticle: 使用React-Native開發,使用Redux,React-Redux,Redux-Persist,Redux-Saga。
爲什麼取這個名字呢,我也不想啊,App爲OneArticle,但發現數據源的官方應用以前就叫一文,讓後我叫一文就不好了。項目地址
一:應用介紹
- 我的項目地址Android端演示 – IOS端,模擬器測試過是沒有問題,打包出來?沒有開發者賬號(笑臉+尷尬),但模擬器測試是OK的。
- 我的數據來源: OneArticle
- 官方正版:觀止APP地址:IOS版 – Android版,產品介紹:不用登錄註冊,沒有複雜的算法,不猜你喜歡。和你一樣我們喜歡簡單,相信優美文字的力量,並樂於堅持。
- 在此聲明我什麼版也不是,只是使用他們數據做個演示,不得將此應用發佈和打包,違規者後果自負。
二 : 界面演示
三: 功能介紹
- 主題換膚 :實現了無縫換膚,這個算是Redux優勢,非常簡單。
- 收藏本地化和簡單緩存 :每篇收藏的文章都會被保存下來,最近瀏覽的十篇文章也會被緩存。
- 分享功能 : 實現了微信和朋友圈的分享。
- 無縫切換文章:無縫切換文章實現不會數據衝突。
可以下載個官方的對比下功能全部實現了,簡單改了下佈局,主要是實戰Redux。
四: redux-thunk 和 redux-saga
- 使用redux他們是必選的,一般都是二選一,redux-thunk redux-saga 兩個都可以很好的實現一些複雜情況下redux,本質都是爲了解決異步action而生,使redux保持完整性,不至於太過混亂。redux-saga 是一個用於管理 Redux 應用異步操作的中間件。 redux-saga 通過創建 Sagas 將所有的異步操作邏輯收集在一個地方集中處理,可以用來代替 redux-thunk 中間件。而且提供了takeLatest/takeEvery可以對事件的僅關注最近事件、關注每一次、事件限頻;reudx-saga更方便測試,等等太多了。
五:要求
- 本項目適合已經能熟練使用React-native基本控件。
- 這裏直接講項目裏redux的一些實戰問題,其他自己看。
六:redux-persist
項目中redux-persist主要是爲了保持數據而它的使用非常簡單,可以先簡單的看下官網就可以看懂主要也沒幾個方法,這裏只講開發時遇到的問題:redux-persist存儲是將整個redux都存儲的,但開發時會有一些臨時數據不需要存儲,如本項目的Modal的顯示,和請求狀態的存儲,不可能每次已進入還沒請求state的請求狀態就爲成功吧,這明顯是不對的,而且最新的版本V5+也重點優化這方面。
1. 一個是設置的適合設置blacklist黑名單,黑名單裏的數據不會保持起來。當然對應的還有白名單whitelist就是僅僅保持名單裏的數據,但有個問題開發時每個reducer都是複製單個模塊的,而白黑名單隻能爲一級對象,這樣單個reducer裏的狀態就不能進入名單了。
2. 將要忽略的狀態寫在一個單獨的reducer裏,這樣在寫黑名單是就可以將其寫進去進行忽略,但這將不太適合維護,例如有些狀態屬於styles,有些狀態屬於splash如果都寫一起,將會缺乏reducer的專一性。
3. persistCombineReducers和persistReducer進行單個reducer的添加白黑名單再設置stateReconciler爲reconciler(數據合併的意思),將可以操控到單個reducer的單個狀態。
七: redux-saga
如果你沒有學過redux-saga這篇中文文檔應該很適合你redux-saga中文文檔,裏面把redux-saga所以方法和用法和原理都講的很好,可以帶你熟練使用。這裏主要用到redux-saga進行數據請求和取消請求,下面是項目redux-saga使用的一部分。
/*
* 文章顯示只有一篇,請求數據時最多也只能有一種
* 1.解釋當請求今天文章花費10s,請求特定一天今天文章需要4s當請求今天文章後2s後請求特定一天文章結果是
* 6s後特定一天文章出來了,刷新。10s後今天文章刷新出來了,這結果顯然不對吧。
* 正常是2s後取消當前正在請求的所以文章,在進行新的請求這樣纔對,這就是下面的寫法的解釋。
* 2. 解釋下take加cancel可以編寫出takeLatest,fork第一個參數:需是 Generator 函數, 或者返回 Promise 的普通函數
* */
function* watchRequestArticle() {
let lastTask
while (true) {
const action = yield take(sagaRequestActions)
if (lastTask) {
yield cancel(lastTask)
}
yield put({type: REFRESH_ARTICLE_DOING})
switch (action.type) {
case SAGA_TODAY_ARTICLE:
lastTask = yield fork(dealtData,action)
break
case SAGA_PREV_ARTICLE:
lastTask = yield fork(dealtData,action)
break
case SAGA_NEXT_ARTICLE:
lastTask = yield fork(dealtData,action)
break
case SAGA_RANDOM_ARTICLE:
lastTask = yield fork(dealtData,action)
break
}
}
}
項目簡單明瞭,而且沒有太多複雜的邏輯,可以直接看項目源碼