错误:在运行 Saga 之前,您必须使用 applyMiddleware 在 Store 上挂载 Saga 中间件

Mat*_*oni 5 typescript reactjs redux redux-saga

我写了一个简单的计数器应用程序。我尝试添加一个 saga 中间件来记录操作。非常基本的应用程序,但我的结构很好。

当我添加中间件时出现问题:我遇到了错误:

redux-saga-core.esm.js:1442 Uncaught Error: Before running a Saga, you must mount the Saga middleware on the Store using applyMiddleware
    at Function.sagaMiddleware.run (redux-saga-core.esm.js:1442)
    at createAppStore (Store.tsx:66)
    at eval (Store.tsx:70)
    at Module../src/store/Store.tsx (bundle.js:1175)
    at __webpack_require__ (bundle.js:20)
    at eval (App.tsx:6)
    at Module../src/components/App.tsx (bundle.js:1127)
    at __webpack_require__ (bundle.js:20)
    at eval (index.tsx:6)
    at Module../src/index.tsx (bundle.js:1151)

I found the problem is the  initialiseSagaMiddleware.run(sagaLogger);
but why? It comes just after createStore...
Run Code Online (Sandbox Code Playgroud)

这是我的商店:

/**
 * This is the global store, where the magic appens. Here I have a redurcer who generates
 * the new application state and the global state.
 * Store = cotainer of reducer and state.
 */

import react from "react";
import { createStore, applyMiddleware,  } from "redux";
import {IState,IAction, actionType} from '../types/types'
import createSagaMiddleware from "redux-saga";
import {sagaLogger} from '../middleware/sagaLogger'

const initialiseSagaMiddleware = createSagaMiddleware();

/**
 * Application initial state. TODO: may be loaded from an API?
 */
const initialState : IState = {
    count: -10
}

/**
 * Reducer: function that create a new state. I must be a pure function, no side effects.
 * It works only on his parameter and return the new state. Reducer parameter are always the same.
 * @param state application global state, ad default it has initialState value.
 * @param action action fired by components. 
 */
  const reducer = (state: IState = initialState, action: IAction): IState => { //Set default to initialState
   // console.log(state, action);
    const newState : IState = { count: state.count}
    switch(action.type){
        case actionType.INCREMENT:
            newState.count= newState.count+1;
            break;
        case actionType.DECREMENT:
            newState.count=newState.count-1;
            break;
        default:
            newState.count= newState.count;
            break;
    }
    return newState;
  };



  /**
   * AppStore is my store. createStore create my Redux Store.
   * TODO: change any to <IState,IAction>
   * For use with redux dev tool use: storeEnhancers, compose
   */
  const sagaMiddleware = createSagaMiddleware();
  const createAppStore = (): any => {

        const Store = createStore(
          reducer,
          applyMiddleware(sagaMiddleware)
        );
       initialiseSagaMiddleware.run(sagaLogger);
        return Store;
  }


export const AppStore = createAppStore();
Run Code Online (Sandbox Code Playgroud)

这是我的 app.tsx

import React from 'react'
import {Provider} from 'react-redux'
import  {AppStore} from "../store/Store";
import Counter from "./counter";

/**
 * Provider is part of the Redux magic. It connect react to redux providing to all the children components (all levels) the state.
 */

export default function App():JSX.Element {
    return (
      <Provider store = {AppStore}>
        <div>
          <Counter />
        </div>
      </Provider>
    );
}
Run Code Online (Sandbox Code Playgroud)

这是我的 banbel.rc (我必须定义 env 预设):

 {
        "presets": [
            [
                "@babel/preset-env",
                {
                    "targets": {
                        "browsers": [
                            "last 2 Chrome versions"
                        ]
                    }
                }
            ],"@babel/react","@babel/Typescript"]
    }
Run Code Online (Sandbox Code Playgroud)

我希望我的计数器可以工作并且操作会记录在控制台上。

azu*_*ndo 10

您正在创建两个 saga 中间件,并将一个应用到商店,并在另一个上运行您的 saga。删除const initialiseSagaMiddleware = createSagaMiddleware();并更改createAppStore为:

  const sagaMiddleware = createSagaMiddleware();
  const createAppStore = (): any => {

        const Store = createStore(
          reducer,
          applyMiddleware(sagaMiddleware)
        );
       // use the same saga middleware that you have enhanced your store with
       sagaMiddleware.run(sagaLogger);
        return Store;
  }
Run Code Online (Sandbox Code Playgroud)