【问题标题】:Redux: turn middleware on and offRedux:打开和关闭中间件
【发布时间】:2016-11-02 15:04:06
【问题描述】:

我正在寻找一种打开和关闭中间件的方法。我介绍了一个教程功能——我通过使用“指导”中间件检查每个操作来倾听用户对 UI 所做的事情。如果用户单击正确的位置,他将转到教程的下一步。但是,只有在教程模式打开时才需要此行为。有什么想法吗?

const store = createStore(holoApp, compose(applyMiddleware(timestamp, ReduxThunk, autosave, guidance),
window.devToolsExtension ? window.devToolsExtension() : f => f)); 

目前我的解决方案是在 guideState reducer 中保留“on”开关,并在中间件中对其进行脏检查:

const guidance = store => next => action => {

    let result = next(action)

    const state = store.getState();
    const { guidanceState } = state;
    const { on } = guidanceState;

    if (on) {

 ....

但是,大约 95% 的时间教程模式会关闭,所以一直检查每个动作都感觉有点脏,嗯,脏……;)还有其他方法吗?

【问题讨论】:

    标签: javascript reactjs redux middleware


    【解决方案1】:

    不要在中间件中做有状态的事情(除非你有一个很好的模式来管理那个状态,比如 Sagas)。如果可以避免的话,根本不要用你的中间件堆栈做有状态的事情。 (如果您必须这样做,@TimoSta's solution 是正确的)。

    相反,使用 reducer 管理您的游览:

    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;
    }
    

    【讨论】:

    • 这不是说我还在脏检查订阅回调中的每个动作吗?我现在正在考虑如何将您的建议与在教程开始和结束时订阅和取消订阅的方式结合起来。
    • 好的,最终使用了路由 {path: '/session/:sessionId/tutorial', component: App, onEnter: tutorialEnter} 与 subscribe 混合
    【解决方案2】:

    我不知道有什么方法可以通过 redux 的 API 即时替换中间件。

    相反,您可以创建一个全新的商店,将旧商店的状态作为初始状态,并使用一组新的中间件。这可能与您的应用程序无缝协作。

    【讨论】:

    • 这可能是一个聪明的方法。但是,我仍然需要以某种方式发现教程开始的那一刻并创建一个新商店。你会怎么做?
    • 好的,最终使用了路由 {path: '/session/:sessionId/tutorial', component: App, onEnter: tutorialEnter}
    【解决方案3】:

    您可以考虑的三个想法:

    • 让中间件监听“GUIDANCE_START”和“GUIDANCE_STOP”操作。当这些通过时,更新一些行为,并且实际上不要将它们传递给next
    • 您可以编写一个中间件,在内部构建自己的中间件管道,并根据需要动态添加和删除指导中间件(replaceMiddleware feature for use with lazy-loaded modules 上的相关讨论)
    • 这可能是一个很好的用例,比如 saga,而不是中间件。我知道我已经看到关于使用 sagas 进行入职工作流程的讨论,例如 Key&Pad app(来源:key-and-pad

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 2013-07-01
      • 2022-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多