Búsqueda de sitios web

reactjs - Error: Antes de ejecutar un Saga, debes montar el middleware de Saga en el Store usando applyMiddleware


Escribí una aplicación de contador simple. Intenté agregar un middleware de saga para registrar acciones. Aplicación muy básica, pero con una estructura agradable.

Cuando agrego un middleware, algo salió mal: tuve el error:

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...

Aquí mi tienda:

/**
 * 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();

Aquí mi 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>
    );
}

Aquí está mi banbel.rc (tuve que definir el preset de env):

 {
        "presets": [
            [
                "@babel/preset-env",
                {
                    "targets": {
                        "browsers": [
                            "last 2 Chrome versions"
                        ]
                    }
                }
            ],"@babel/react","@babel/Typescript"]
    }

Espero que mi contador funcione y que la acción se registre en la consola.

Respuesta #1

Estás creando dos middlewares de saga y aplicando uno al store y ejecutando tus sagas en el otro. Elimina const initialiseSagaMiddleware=createSagaMiddleware(); y cambia createAppStore a:

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

Artículos relacionados