# 独立于 React 的 Epics
有的时侯我们可能希望让 Observable 的操作逻辑与 React 解耦,从而进一步在其它工具中复用。本文列举了一些方式以独立于 React 的方式编写 Observable 操作。
通常我们这么使用 useObservable
:
const enhanced$ = useObservable(
inputs$ => inputs$.pipe(
...
),
[props.a, stateB]
)
这非常好因为类 epic 的方法 inputs$ => inputs$.pipe(...)
与 React 以及 Observable Hooks 完全无关。我们可以这么复用:
// path/to/logic/text.js
export const transformText = inputs$ => inputs$.pipe(
...
)
import { transformText } from 'path/to/logic/text'
const enhanced$ = useObservable(
transformText,
[props.a, stateB]
)
但有时候组件中可能创建了多个 Observables:
const [onChange, textChange$] = useObservableCallback(event$ => event$.pipe(...))
const enhanced$ = useObservable(
inputs$ => inputs$.pipe(
withLatestFrom(textChange$)
...
),
[props.a, stateB]
)
这样开始不好复用了,因为存在本地依赖。
但是嘿,既然它们是依赖,那为何我们不直接把它们定义成“依赖”呢!
# 直接依赖
这个模式中 Observable 作为子流被传进去。
const [onChange, textChange$] = useObservableCallback(event$ => event$.pipe(...))
const enhanced$ = useObservable(
inputs$ => {
const textChange$ = inputs$.pipe(
distinctUntilKeyChanged(2)
switchMap(inputs => inputs[2])
)
return inputs$.pipe(
withLatestFrom(textChange$)
...
)
},
[props.a, stateB, textChange$]
)
但当 Observable 较多的时侯这么定义可能有些费劲。
# 高阶依赖
另一种模式是区分普通依赖与响应式依赖,类似在定义高阶依赖。
const [onChange, textChange$] = useObservableCallback(event$ => event$.pipe(...))
const metaValues$ = useObservable(identity, [props.a, stateB])
const enhanced$ = useObservable(
inputs$ => inputs$.pipe(
switchMap(([metaValues$, textChange$]) => metaValues$.pipe(
withLatestFrom(textChange$)
...
))
),
[metaValues$, textChange$]
)
这种方式在 Observable 较多的情况下会更简洁。