Redux:打开和关闭中间件
Redux: turn middleware on and off
我正在寻找一种打开和关闭中间件的方法。我介绍了一个教程功能 - 我通过使用 "guidance" 中间件检查每个操作来听用户使用 UI 做什么。如果用户点击正确的地方,他就会进入教程的下一步。但是,仅当教程模式打开时才需要此行为。有什么想法吗?
const store = createStore(holoApp, compose(applyMiddleware(timestamp, ReduxThunk, autosave, guidance),
window.devToolsExtension ? window.devToolsExtension() : f => f));
目前我的解决方案是将 "on" 开关保留在 guidanceState reducer 中并在中间件中对其进行脏检查:
const guidance = store => next => action => {
let result = next(action)
const state = store.getState();
const { guidanceState } = state;
const { on } = guidanceState;
if (on) {
....
但是,大约 95% 的时间教程模式会关闭,所以总是检查每个动作感觉有点脏,好吧,脏...;) 还有其他方法吗?
我不知道有什么方法可以通过 redux API 动态替换中间件。
相反,您可以创建一个全新的商店,将旧商店的状态作为初始状态,并使用一组新的中间件。这可能会与您的应用程序无缝配合。
不要在中间件中做有状态的事情(除非你有一个很好的模式来管理那个状态,比如 Sagas)。如果可以避免的话,根本不要对你的中间件堆栈做有状态的事情。 (如果你必须这样做,是正确的)。
相反,使用减速器管理您的游览:
const finalReducer = combineReducers({
// Your other reducers
tourState: tourReducer
});
function tourReducer(state = initalTourState, action) {
switch(action.type) {
case TOUR_LAST_STEP:
return /* compose next tour step state here */;
case TOUR_NEXT_STEP:
return /* compose last tour step state here */;
case TOUR_CLOSE:
return undefined; // Nothing to do in this case
default:
return state;
}
}
然后,在您的应用程序中使用 tourState
的当前状态移动突出显示,如果 tourState
中没有任何内容,请关闭游览。
store.subscribe(() => {
const state = store.getState();
if (state.tourState) {
tourManager.setTourStep(state.tourState);
} else {
tourManager.close();
}
});
您也不必使用有状态的巡回管理器 - 如果您使用的是 React,它可能只是一个组件,它使用 connect
包装器提取 tourState
并呈现 null
如果没有状态:
// waves hands vigorously
const TourComponent = (props) => {
if (props.currentStep) return <TourStep ...props.currentStep />;
return null;
}
您可以考虑的三个想法:
- 让中间件侦听 "GUIDANCE_START" 和 "GUIDANCE_STOP" 操作。当这些通过时,更新一些行为,而不是实际将它们传递给
next
。
- 您可以编写一个中间件,在内部构建自己的中间件管道,并根据需要动态添加和删除指导中间件(在 replaceMiddleware feature for use with lazy-loaded modules 有一些相关讨论)
- 对于像 saga 这样的东西,这可能是一个很好的用例,而不是中间件。我知道我已经看到关于将 sagas 用于入职工作流程的讨论,例如 Key&Pad app (source:key-and-pad)
我正在寻找一种打开和关闭中间件的方法。我介绍了一个教程功能 - 我通过使用 "guidance" 中间件检查每个操作来听用户使用 UI 做什么。如果用户点击正确的地方,他就会进入教程的下一步。但是,仅当教程模式打开时才需要此行为。有什么想法吗?
const store = createStore(holoApp, compose(applyMiddleware(timestamp, ReduxThunk, autosave, guidance),
window.devToolsExtension ? window.devToolsExtension() : f => f));
目前我的解决方案是将 "on" 开关保留在 guidanceState reducer 中并在中间件中对其进行脏检查:
const guidance = store => next => action => {
let result = next(action)
const state = store.getState();
const { guidanceState } = state;
const { on } = guidanceState;
if (on) {
....
但是,大约 95% 的时间教程模式会关闭,所以总是检查每个动作感觉有点脏,好吧,脏...;) 还有其他方法吗?
我不知道有什么方法可以通过 redux API 动态替换中间件。
相反,您可以创建一个全新的商店,将旧商店的状态作为初始状态,并使用一组新的中间件。这可能会与您的应用程序无缝配合。
不要在中间件中做有状态的事情(除非你有一个很好的模式来管理那个状态,比如 Sagas)。如果可以避免的话,根本不要对你的中间件堆栈做有状态的事情。 (如果你必须这样做,
相反,使用减速器管理您的游览:
const finalReducer = combineReducers({
// Your other reducers
tourState: tourReducer
});
function tourReducer(state = initalTourState, action) {
switch(action.type) {
case TOUR_LAST_STEP:
return /* compose next tour step state here */;
case TOUR_NEXT_STEP:
return /* compose last tour step state here */;
case TOUR_CLOSE:
return undefined; // Nothing to do in this case
default:
return state;
}
}
然后,在您的应用程序中使用 tourState
的当前状态移动突出显示,如果 tourState
中没有任何内容,请关闭游览。
store.subscribe(() => {
const state = store.getState();
if (state.tourState) {
tourManager.setTourStep(state.tourState);
} else {
tourManager.close();
}
});
您也不必使用有状态的巡回管理器 - 如果您使用的是 React,它可能只是一个组件,它使用 connect
包装器提取 tourState
并呈现 null
如果没有状态:
// waves hands vigorously
const TourComponent = (props) => {
if (props.currentStep) return <TourStep ...props.currentStep />;
return null;
}
您可以考虑的三个想法:
- 让中间件侦听 "GUIDANCE_START" 和 "GUIDANCE_STOP" 操作。当这些通过时,更新一些行为,而不是实际将它们传递给
next
。 - 您可以编写一个中间件,在内部构建自己的中间件管道,并根据需要动态添加和删除指导中间件(在 replaceMiddleware feature for use with lazy-loaded modules 有一些相关讨论)
- 对于像 saga 这样的东西,这可能是一个很好的用例,而不是中间件。我知道我已经看到关于将 sagas 用于入职工作流程的讨论,例如 Key&Pad app (source:key-and-pad)