Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 将新的史诗懒洋洋地添加到Inner挂钩中是一种有效的做法吗?_Reactjs_Redux_Redux Observable_Redux Router - Fatal编程技术网

Reactjs 将新的史诗懒洋洋地添加到Inner挂钩中是一种有效的做法吗?

Reactjs 将新的史诗懒洋洋地添加到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

当将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'
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而编辑

我可否要求澄清几点

  • 注册的fn工作得很好。我一直在使用.distinct()运算符来解决重复epic注册问题,如下所示:

    export const epic$=new BehaviorSubject(组合EEPICS(epic1,epic2)).distinct()

  • 这是一种同样有效/良好的方法来处理这个问题吗?如果不是,你能解释一下原因吗

  • 我正在使用create react app,它有require.sure和ES6 import(它们是不同的导入方式,对吗?),基本上,我复制了粘贴,其中包含
    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' ) )
            } )
        }
    }
    
  • 关于在'getComponent'fn中注册epic以进行异步加载,我认为在这里进行同步加载实际上是可取的,这样在epic注册之前,路由的组件不会呈现。如果用户试图在路线上执行某些操作(如获取一些详细信息或提交表单),要求注册epic,但epic尚未注册,会发生什么情况

  • 在react router module.export声明之外,是否还有其他适合延迟注册EPIC的地方?由于我的项目中的许多路由不需要登录,因此登录并不总是触发路由更改。但是,在用户登录后,应该注册一组EPIC。目前,我在authReducer中设置了一个令牌变量,这是一种非常愚蠢而且可能是错误的方法,但它所做的只是调用一个注册新epics的函数:

    './../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(),
                }
    
            }
    
  • 我想,罗吉内皮克将是一个更好的地方来登记史诗,而不是减速器。(我发现它看起来很熟悉)。这是正确的,还是我完全错了?我知道.concat()是同步的,我知道redux是同步的-我不确定registerEpics()是否是同步的,但是使用reducer来注册epics似乎可以-这是否意味着registerEpics是同步的?或者这仅仅意味着事情发展得如此之快以至于无关紧要?或者,这仅仅是因为我对导入语句以及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
                    }))
            );
    
    在这种情况下,每次我们导航到/某个路径时,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