Является ли эффективной практикой лениво добавлять новые эпики в ловушки реакции-маршрутизатора onEnter?
При использовании redux-observable с реагирующим маршрутизатором, имеет ли смысл асинхронно добавлять новые эпики согласно инструкциям в документацииВот внутри onEnter перехватывает реакции-роутера при изменении маршрута?
./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 и наблюдаемый редукс. Кажется, это работает, но интересно: 1. В этом случае будет ли epic3 снова добавляться в rootEpic каждый раз, когда мы переходим к / some-path? 2. Если бы я хотел console.log, какие эпики были добавлены в rootEpic, как бы я это сделал?
Отредактировано в ответ на @JayPhelps
Могу ли я запросить разъяснения по нескольким пунктам?
RegisterEpic fn прекрасно работает. Я использовал оператор .distinct () для решения проблемы с регистрацией дубликатов эпосов, например:
export const epic$ = new BehaviorSubject(combineEpics(epic1, epic2)).distinct()
Является ли это одинаково верным / хорошим способом обработки отложенной эпической регистрации, и если нет, то не могли бы вы объяснить, почему?
Я использую приложение create-реагировать на приложение, которое требует require.ensure, а также импорт ES6 (это разные способы импорта, верно?), И, в основном, я вставил копиюПример огромных приложений реакции-роутера который имелrequire.ensure
код, но везде, я использую операторы импорта в верхней части файла.Таким образом, импорт epics и registerEpic fn вверху, похоже, работает, а размещение путей внутри первого аргумента require.ensure также, похоже, работает. Не мешает ли это, если я использую операторы require.ensure И import? Если я использую require.ensure для загрузки ВСЕГО, в чем нуждается маршрут, означает ли это, что я удаляю все операторы импорта внутри вложенных (без маршрутизации) компонентов этого маршрута?
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' ) )
} )
}
}
Что касается регистрации эпиков в fn 'getComponent' для асинхронной загрузки - я подумал, что на самом деле здесь желательно иметь синхронную загрузку, чтобы компонент маршрута не отображался до тех пор, пока эпик не будет зарегистрирован. Что произойдет, если пользователь попытается что-то сделать на маршруте, например получить некоторую подробную информацию или отправить форму, которая требует регистрации эпоса, а эпопея еще не зарегистрирована?
Есть ли какое-либо другое место за пределами объявлений о реакциях 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 () является синхронным, и я знаю, что избыточный является синхронным - я не уверен, является ли registerEpics () синхронным, но использование редуктора для регистрации epics SEEMS работает нормально - означает ли это, что 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
}))
);