2017-03-19 42 views
0

我是新來Redux的觀測:https://github.com/redux-observable/redux-observableRedux Observables:對於相同的動作,但不同的過濾器,分開史詩?

我有一個簡單的例子,我想這樣做基於用戶的signedIn狀態2個不同的東西。

  1. 如果登錄,添加RSVP
  2. 如果沒有登錄,模態

顯示標誌我在app/redux/epics/addRSVP.js文件中有這樣的:

import 'rxjs'; 
import * as scheduleActions from '../ducks/schedule'; 

export default function searchUsers(action$, store) { 
    return action$.ofType(scheduleActions.ADD_RSVP) 
    .filter(() => store.getState().user.signedIn) 
    .map(action => scheduleActions.rsvpAdded(action.payload)); 
}; 

我的問題是,應該我正在爲註銷的用例創建另一個app/redux/epics/preventRSVPIfNotSignedIn.js史詩?是這樣的:

import 'rxjs'; 
import * as authenticationActions from '../ducks/authentication'; 

export default function searchUsers(action$, store) { 
    return action$.ofType(scheduleActions.ADD_RSVP) 
    .filter(() => !store.getState().user.signedIn) 
    .map(action => authenticationActions.show()); 
}; 

或者有沒有辦法我可以把兩者都放在同一個文件中?我覺得如果它是前者,它最終會成爲很多史詩。知道一般慣例是什麼會很棒。

回答

2

如果您不確定,請始終創建單獨的史詩。稍後測試和更改會更容易。此外,這種方法幾乎沒有缺點(性能方面)。將兩個史詩結合起來可以增加抽象而不知道它是否真的有必要。

另外,由看起來它的鴨子,這兩個(側面)效果的領域是不同的。我想說這是一個強有力的指標,使用單獨的史詩在這裏是一個好主意,並且會更有前途。這就是說,如果你確定你的史詩不會改變或者變得更加複雜(目前是if/else),我想這也沒關係。


採取了第二次看後,我想你想要做的是「如果用戶沒有登錄,顯示我是一個登錄頁面,等到他(她)的登錄和登錄成功後,發起RSVP行動「。如果這是你的用例,你可能想看看delayWhen。這可能是更好的解決方案,但它更像是RxJS的高級功能。也許這是一個很好的重構任務,當你更加適應redux-observables :)

3

塞巴斯蒂安給出了很好的建議,通常我會分裂它們並複製邏輯。然而,如果你真的做了很多,你可以創建自己的抽象,所以你不需要重複自己。

您可以創建一個像requireAuth這樣的助手,它會採取您期望的操作,以及一個只有在有效的身份驗證時纔會接收這些操作的史詩。然後它會返回一個包裝它的新史詩。

// Helper to abstract the common auth requirement checks 
// which will also dispatch authenticationActions.show() 
// when they attempt to do something they can't 
const requireAuth = (type, epic) => (action$, store) => { 
    // matching actions which they have permission for 
    const valid$ = action$ 
    .ofType(type) 
    .filter(() => store.getState().user.signedIn); 

    // matching actions they do NOT have permission for 
    const invalid$ = action$ 
    .ofType(type) 
    .filter(() => !store.getState().user.signedIn); 

    return Observable.merge(
    epic(valid$, store), 
    invalid$.map(action => authenticationActions.show()) 
); 
}; 

const searchUsersEpic = requireAuth(scheduleActions.ADD_RSVP, (action$, store) => 
    action$.map(action => scheduleActions.rsvpAdded(action.payload)) 
); 

// You can then use requireAuth for any epics that require it 
// as an example: 
const searchMoviesEpic = requireAuth(scheduleActions.SEARCH_MOVIE, (action$, store) => 
    action$.mergeMap(action => 
    ajax(`/search/for/the/movie/${action.id}`) 
     .map(resp => scheduleActions.searchMoviesFulfilled(resp)) 
) 
); 

根據需要調整 - 但要小心,將抽象可以使你的代碼難以以後理由或引入錯誤,當有人後來調整的抽象沒有意識到它如何影響其他codepaths。

相關問題