Reactjs 将新的史诗懒洋洋地添加到Inner挂钩中是一种有效的做法吗?
当将redux observable与react router一起使用时,在路由更改期间,按照react router的Oneter挂钩内的文档中的说明异步添加新的EPIC是否有意义 ./epics/index.jsReactjs 将新的史诗懒洋洋地添加到Inner挂钩中是一种有效的做法吗?,reactjs,redux,redux-observable,redux-router,Reactjs,Redux,Redux Observable,Redux Router,当将redux observable与react router一起使用时,在路由更改期间,按照react router的Oneter挂钩内的文档中的说明异步添加新的EPIC是否有意义 ./epics/index.js import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { combineEpics } from 'redux-observable'; import { epic1 } from './epic1' imp
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
};
…routes/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非常新。这似乎有效,但令人疑惑:
1.在这种情况下,每次我们导航到/某个路径时,epic3是否会再次添加到rootEpic?
2.如果我想console.log哪些史诗已经添加到rootEpic中,我会怎么做
为响应@JayPhelps而编辑 我可否要求澄清几点
export const epic$=new BehaviorSubject(组合EEPICS(epic1,epic2)).distinct()
require.sure
code,但在其他地方,我在文件顶部使用import语句李>
因此,在顶部导入epics和registerEpic fn似乎是可行的,同时将路径放在require.sure第一个参数中似乎也是可行的。如果我使用require.sure和import语句,会把事情搞得一团糟吗?如果我使用require.survey加载路由所需的所有内容,这是否意味着我将删除该路由组件的嵌套(无路由)组件中的所有导入语句
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' ) )
} )
}
}
'./../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(),
}
}
./../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
}))
);
在这种情况下,每次我们导航到/某个路径时,epic3是否会再次添加到rootEpic
如果您使用react router并进行代码拆分,那么实际上您需要在getComponent
钩子中添加必要的史诗,而不是oneter
钩子。这是因为getComponent
钩子允许异步加载该路由所需的资源,不仅包括组件,还包括任何epics、Reducer等。如果使用require.sure()
,这会告诉webpack将这些项目拆分为一个单独的捆绑包,这样它们就不会包含在原始条目中——所以不要将这些文件导入其他任何地方,否则您将否定这一点
这大概是一个例子,它看起来像什么:
routes/SomePath/index.js
从'where/ever/this/is/epics/index.js'导入{registerEpic};
导出默认值{
路径:“某条路径”,
getComponent(位置,完成){
require.确保(['./components/SomePath',path/to/epics/epic3',require=>{
//这是你注册史诗、减速器等的地方
//它们是这个单独包的一部分
const-epic=require('path/to/epics/epic3')。epic3;
注册(epic);
完成(null,require(“./components/SomePath”);
});
}
};
where/ever/this/is/epics/index.js
从'rxjs/BehaviorSubject'导入{BehaviorSubject};
从'redux observable'导入{combinepics};
从“/epic1”导入{epic1};
从“/epic2”导入{epic2};
常量epicRegistry=[epic1,epic2];
const epic$=新的行为主体(combineEpics(…epicRegistry));
导出常量注册表项=(epic)=>{
//不要添加已注册/正在运行的epic
if(epicRegistry.indexOf(epic)=-1){
epicRegistry.push(epic);
epic$.next(epic);
}
};
//您的根epic需要在epic$so any上使用'mergeMap'
//新的史诗是和其他史诗一起创作的
导出常量rootEpic=(action$,store)=>
epic$.mergeMap(epic=>
epic(action$,商店)
);
我创建了一个注册函数,确保你没有添加已经添加的史诗;react router将在您每次进入该路由时调用getComponent
,因此这一点很重要,这样您就不会有两个相同epic的运行实例
但是请注意,我的代码做出了一些开箱即用的假设,当涉及到require('path/to/epics/epic3')。epic3
时,这些假设可能是错误的。您的epic3是否实际作为命名属性导出?我想是这样,但我注意到您正在做done(null,require(')./components/so