当使用终极版,可观察到有react的路由器,这将是有意义的异步的文档中添加新的史诗按照指示在这里中路由变化中的OnEnterreact-router的钩子?
./epics/index.js
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { combineEpics } from 'redux-observable';
import { epic1 } from './epic1'
import { epic2 } from './epic2'
export const epic$ = new BehaviorSubject(combineEpics(epic1, epic2));
export const rootEpic = (action$, store) =>
epic$.mergeMap(epic =>
epic(action$, store)
);
export {
rootEpic
};
...路由/SomePath/index.js
import { epic$ } from './../../../../epics/index'
import { epic3 } from './../../../../epics/epic3'
module.exports = {
path: 'some-path',
getComponent( location, cb ) {
require.ensure( [], ( require ) => {
cb( null, require( './components/SomePath' ) )
} )
},
onEnter() {
epic$.next(epic3)
}
}
Rxjs 和 redux-observable 非常新。这似乎有效,但想知道: 1. 在这种情况下,每次导航到 /some-path 时,epic3 是否会再次添加到 rootEpic 中?2. 如果我想在 console.log 中记录哪些史诗被添加到 rootEpic 中,我该怎么做?
编辑以回应@JayPhelps
我可以要求澄清几点吗?
registerEpic fn 很好用。我一直在使用 .distinct() 运算符来解决重复的史诗注册问题,如下所示:
export const epic$ = new BehaviorSubject(combineEpics(epic1, epic2)).distinct()
这是处理懒惰史诗注册的同样有效/好的方法,如果不是,请解释一下原因吗?
- 我使用的创建-react-应用程序,它具有require.ensure以及ES6进口(它们是进口权的不同方式?),基本上,我复制粘贴react,路由器的巨大的应用程式例如其中有
require.ensure
代码,但无处不在否则,我在文件顶部使用 import 语句。
因此,在顶部导入史诗和 registerEpic fn 似乎有效,同时将路径放在 require.ensure 第一个参数中似乎也有效。如果我使用 require.ensure AND import 语句,会不会把事情搞砸?如果我使用 require.ensure 来加载路由需要的所有东西,这是否意味着我删除了该路由组件的嵌套(无路由)组件中的所有 import 语句?
import { epic3 } from './../../epics/epic3'
import { epic4 } from './../../epics/epic4'
import { registerEpic } from './../../epics/index'
module.exports = {
path: 'my-path',
getComponent( location, done ) {
require.ensure( [], ( require ) => {
registerEpic(addYoutubeEpic)
registerEpic(linkYourSiteEpic)
done( null, require( './components/Edit' ) )
} )
}
}
关于在 'getComponent' fn 中注册史诗以进行异步加载 - 我认为在这里进行同步加载实际上是可取的,这样路由的组件在注册史诗之前不会呈现。如果用户尝试在路由上执行某些操作,例如获取一些详细信息或提交表单,需要注册史诗,而史诗尚未注册,会发生什么情况?
在 react-router module.export 声明之外还有其他适合懒惰注册史诗的地方吗?由于我项目中的许多路由不需要登录,因此登录并不总是会触发路由更改。但是,应该在用户登录后注册一堆史诗。目前,我通过在我的 authReducer 中设置令牌变量来以一种非常愚蠢且可能是错误的方式进行操作,但它所做的只是调用一个函数注册新的史诗:
'./../reducers/authReducer.js' import { greatEpic } from './../epics/fetchFollowListEpic' import { usefulEpic } from './../epics/fetchMyCollectionsEpic' // and a few more import { registerEpic } from './../epics/index' const addEpics = () => { registerEpic(greatEpic) registerEpic(usefulEpic) ...etc } export default function reducer( state = { loggingIn: false, loggedIn: false, error: '', }, action ) { switch ( action.type ) { case "LOGIN_SEQUENCE_DONE": { return { ...state, aid: setAuthToken(action.payload), loginFailed: false, addEpics: addEpics(), } }
我认为 loginEpic 将是一个更好的地方来注册史诗,而不是减速器。(我在 github 上找到了你的登录示例,所以它可能看起来很熟悉)。这是正确的,还是我完全偏离了基地?我知道 .concat() 是同步的,我知道 redux 是同步的——我不确定 registerEpics() 是否是同步的,但是使用 reducer 来注册史诗 SEEMS 可以正常工作——这是否意味着 registerEpics 是同步的?还是仅仅意味着事情发展得如此之快以至于无关紧要?还是仅仅因为我对 import 语句以及 webpack 如何处理代码拆分的一些基本误解才起作用,我必须进一步研究?
./../epics/loginEpic
export const loginEpic = action$ =>
action$.ofType("LOGIN")
.mergeMap(action =>
Observable.fromPromise(axios.post('webapi/login', action.payload))
.flatMap(payload =>
// Concat multiple observables so they fire sequentially
Observable.concat(
// after LOGIN_FULILLED
Observable.of({ type: "LOGIN_FULFILLED", payload: payload.data.aid }),
// ****This is where I think I should be registering the epics right after logging in. "ANOTHER_ACTION" below depends upon one of these epics****
Observable.of({type: "ANOTHER_ACTION", payload: 'webapi/following'}),
Observable.of({type: "LOGIN_SEQUENCE_DONE"}),
)
)
.startWith({ type: "LOGIN_PENDING" })
.takeUntil(action$.ofType("LOGIN_CANCELLED"))
.catch(error => Observable.of({
type: "LOGIN_REJECTED",
payload: error,
error: true
}))
);