Colin Ricardo
Colin Ricardo

Reputation: 17239

Redux Saga action crashes app

I have a simple React / Redux / Redux Sagas app which uses an API to show a random picture of a dog upon clicking a button.

dogSagas.js

import { put, call, takeEvery, all } from 'redux-saga/effects';
import * as types from '../actions/types';
import * as actions from '../actions/dogActions';
import { DOG_API } from '../constants/variables';

function* getDogAsync() {
  try {
    yield put(actions.getDog);

    const data = yield call(() =>
      fetch(DOG_API)
        .then(res => res.json())
        .catch(err => console.error(err)),
    );

    yield put(actions.getDogOk(data));
  } catch (error) {
    yield put(actions.getDogFail());
  }
}

function* watchGetDog() {
  yield takeEvery(types.GET_DOG, getDogAsync);
}

export default function* rootSaga() {
  yield all([watchGetDog()]);
}

dogActions.js

import * as types from '../actions/types';

export const getDog = () => ({
  type: types.GET_DOG,
});

export const getDogOk = data => ({
  type: types.GET_DOG_OK,
  payload: data.message,
});

export const getDogFail = () => ({
  type: types.GET_DOG_FAIL,
});

errors

However, I have two different errors.

1.) When I do yield put(actions.getDog); the app works, but in the console I get the error:

uncaught at getDogAsync Error: Actions must be plain objects. Use custom middleware for async actions.

2.) If instead I do: yield put(actions.getDog()); the app consumes a lot of CPU and effectively crashes.

questions

So, my questions are:

1.) Why does this approach cause Redux to complain about non-plain objects?

2.) Why does this seemingly innocuous statement cause the app to crash?

full code

Full code on StackBlitz here.

Upvotes: 0

Views: 1043

Answers (1)

Colin Ricardo
Colin Ricardo

Reputation: 17239

The issue was that I was calling the getDog() action creator within the async generator getDogAsync(). Since we had a watcher, this was leading to an infinite number of calls to getDog().

So, to fix, just remove:

yield put(actions.getDog);

within the getDogAsync().

Upvotes: 3

Related Questions