Last active
October 17, 2018 09:23
-
-
Save terrierscript/8e08b4445a8874f41b922c713bb34b08 to your computer and use it in GitHub Desktop.
redux-observableで複数のActionを発火する方法をたくさん考える ref: https://qiita.com/terrierscript/items/0feecfcb61144e68d7ac
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Button = ({ dispatch }) => ( | |
<button onClick={(e) => dispatch({ type: "PING" })}> | |
Ping | |
</button> | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ボタンからPINGのActionが来たら中間のTEMP_PINGを発火 | |
const seedEpic = (action$) => | |
action$.pipe( | |
ofType("PING"), | |
filter(action => !!action.payload), // 例としてここでは事前処理のepicでfilterをしてみる | |
map((action: any) => ({ | |
type: "TEMP_PING", | |
payload: action.payload | |
})) | |
) | |
// TEMP_PINGを受けて値を2倍にするEpic | |
const doubleEpic = (action$) => | |
action$.pipe( | |
ofType("TEMP_PING"), | |
map((action: any) => ({ | |
type: "PONG", | |
payload: action.payload * 3 | |
})) | |
) | |
// TEMP_PINGを受けて値を3倍にするEpic | |
const tripleEpic = (action$) => | |
action$.pipe( | |
ofType("TEMP_PING"), | |
map((action: any) => ({ | |
type: "PUNG", | |
payload: action.payload * 4 | |
})) | |
) | |
export const pingEpic = combineEpics(debug(), seedEpic, doubleEpic, tripleEpic) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const pingEpic = (action$) => | |
action$.pipe( | |
ofType("PING"), | |
mergeMap((action: any) => { | |
return [ | |
{ | |
type: "PONG", | |
payload: action.payload * 2 | |
}, | |
{ | |
type: "PUNG", | |
payload: action.payload * 3 | |
} | |
] | |
}) | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const pingEpic = (action$) => { | |
const [even, odd] = action$.pipe( | |
ofType("PING"), | |
partition((action: any) => action.payload % 2 === 0) | |
) | |
return merge( | |
// 偶数の場合2倍 | |
even.pipe( | |
map((action: any) => ({ | |
type: "PONG", | |
payload: action.payload * 2 | |
})), | |
), | |
// 奇数の場合3倍 | |
odd.pipe( | |
map((action: any) => ({ | |
type: "PUNG", | |
payload: action.payload * 3 | |
})) | |
) | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const pingEpic = (action$) => | |
action$.pipe( | |
ofType("PING"), | |
mergeMap(action => { | |
const source$ = of(action) | |
return merge( | |
source$.pipe( | |
map((action: any) => ({ | |
type: "PONG", | |
payload: action.payload * 2 | |
})), | |
), | |
source$.pipe( | |
map((action: any) => ({ | |
type: "PUNG", | |
payload: action.payload * 3 | |
})) | |
) | |
) | |
}) | |
) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const pingEpic = (action$) => { | |
// ここまでが共通 | |
const source$ = action$.pipe( | |
ofType("PING"), | |
) | |
// 分岐するsourceをそれぞれ Observable.mergeで混ぜる。 | |
return merge( | |
source$.pipe( | |
map((action: any) => ({ | |
type: "PONG", | |
payload: action.payload * 2 | |
})), | |
), | |
source$.pipe( | |
map((action: any) => ({ | |
type: "PUNG", | |
payload: action.payload * 3 | |
})), | |
) | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const pingEpic = (action$) => { | |
const source$ = action$.pipe( | |
ofType("PING"), | |
) | |
return merge( | |
source$.pipe( // こっちはLOG出力だけ | |
map((action: any) => ({ | |
type: "LOG", | |
payload: action.payload | |
})), | |
), | |
source$.pipe( | |
bufferTime(1000), // 連打 | |
filter((items: any[]) => items.length > 0), | |
map((actions: any[]) => { // 受け取ったactionが配列になる | |
return { | |
type: "MASH", | |
payload: actions.length | |
} | |
}) | |
) | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Subjectを別に作る。 | |
// 本来redux-observableがSubjectを管理しているので、ここにわざわざ作るのはいったい、という感じ | |
const pongSubject = new Subject() | |
const pungSubject = new Subject() | |
const mainEpic = (action$) => { | |
return action$.pipe( | |
ofType("PING"), | |
// tapでそれぞれsubjectを発火 | |
tap((action: any) => pongSubject.next({ type: "PONG", payload: action.payload * 2 })), | |
tap((action: any) => pungSubject.next({ type: "PUNG", payload: action.payload * 3 })), | |
ignoreElements() // tapだけでそのまま返すと無限PINGで死ぬ | |
) | |
} | |
// SubjectをasObservableで変換してEpicと扱う | |
const pongEpic = () => pongSubject.asObservable() | |
const pungEpic = () => pungSubject.asObservable() | |
export const pingEpic = combineEpics(mainEpic, pongEpic, pungEpic) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const logSubject = new Subject() | |
const mainEpic = (action$) => { | |
return action$.pipe( | |
ofType("PING"), | |
tap((action: any) => logSubject.next({ type: "LOG", payload: action.payload })), | |
bufferTime(500), // 連打 | |
filter((items: any[]) => items.length > 0), | |
map((actions: any[]) => { // 受け取ったactionが配列になる | |
return { | |
type: "MASH", | |
payload: actions.length | |
} | |
}), | |
) | |
} | |
const logEpic = () => logSubject.asObservable() | |
export const pingEpic = combineEpics(mainEpic, logEpic) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment