Max Wolfen
Max Wolfen

Reputation: 2033

Redux/React. Getting a stackoverflow loop in Redux-Saga Middleware

I cannot understand what is the wrong with my Redux Saga middleWare, because every time when I try to start my Saga function and dispatch it in component MainComponent below - I gets a stackoverflow loop on the page and all elements becomes unclicable with memory leak.

I will be grateful for any help info!

=== My Redux Saga MiddleWare:

import { takeEvery } from 'redux-saga'; 
import addData from '../actions';

const createSaga = function* createSaga(dispatch) {
    try {
        yield takeEvery("ADD_DATA", (action) => {
            console.log(action); // getting a stackoverflow loop in this Saga function
            dispatch(action);
        });
    } catch (e) { 
        console.log(e) 
    }
}

export default createSaga;

=== My Action:

function addData(data) {
    return {
        type: "ADD_DATA",
        data
    }
};

export default addData;

=== My Index:

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import createSaga from './saga/saga'
import reducers from './reducers';
import createSagaMiddleware from 'redux-saga';

const sagaMidleWare = createSagaMiddleware();
const store = createStore(
    reducers,
    applyMiddleware(sagaMidleWare)
)

sagaMidleWare.run(createSaga, store.dispatch);

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
);

=== My Component (if needed):

import React, { Component } from 'react';
import { connect } from 'react-redux';

function addData(data) {
    return {
        type: "ADD_DATA",
        data
    }
};

class MainComponent extends Component {
    handleUpdate = () => {
        const { dispatch } = this.props;
        const data = 'hi';
        dispatch(addData(data));
    }

    render() {
        const { store } = this.props;
        return (
            <div>
                <button onClick={this.handleUpdate}>Click me!</button>
                <p>{store.state.toString()}</p>
            </div> 
        )
    }
}

export default connect(store => ({store}), dispatch => ({dispatch}))(MainComponent);

Upvotes: 0

Views: 151

Answers (1)

Martin Kadlec
Martin Kadlec

Reputation: 4975

The problem is here

yield takeEvery("ADD_DATA", (action) => {
    console.log(action);
    dispatch(action);
});

You are saying that every time ADD_DATA is dispachted another ADD_DATA should be dispatched again, and again, and again...

Also, on a sidenote, you should pass another saga as second argument of takeEvery so you can use the put effect rather than dispatch like so:

import { put, takeEvery } from 'redux-saga/effects'; 
yield takeEvery('ADD_DATA', function*(action) {
    yield put({type: 'ANOTHER_ACTION'});
});

Upvotes: 1

Related Questions