question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Saga runs twice for a single action

See original GitHub issue

I have a saga to handle like requests. The user clicks a button to toggle the liked status of a photo.

The saga listens for an action of type SUBMIT_LIKE. My problem is that the submitLikeSaga is running twice for each SUBMIT_LIKE action. e.g. In the api-error case one SUBMIT_LIKE action triggers two api calls and four RECEIVE_LIKE actions.

(using react-boilerplate if that helps.)

export function* submitLikeSaga(action) {

  // optimistically update the UI
  // action shape: {
  //    type: RECEIVE_LIKE,
  //    like: {id: 1, liked: true}
  //  }
  yield put(receiveLike(action.like));

  // POST like data to api
  const response = yield call(
    request,
    `${API_ENDPOINT}/user_likes.json`,
    {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${action.token}`,
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(action.like),
    }
  );

  // if api call failed, reverse change made to UI
  if (response.err) {
    yield put(receiveLike({
      id: action.like.id,
      liked: !action.like.liked,
    }));
  }
}

export function* watchSubmitLike() {
  yield* takeEvery(SUBMIT_LIKE, submitLikeSaga);
}

// All sagas to be loaded
export default [
  watchFetchUsers,
  watchSubmitLike,
];

ProfileGrid.js

const ProfileGrid = ({
  users,
  submitLike,
  token,
}) =>
  <div className={styles.profileGrid}>
    {users.map((user, i) => (
      <div key={i} className={styles.gridTile}>
        <GridTile
          title={user.username}
          actionIcon={<ActionIcon
            onIconClick={() => { submitLike(user.id, !user.liked, token); }}

            isActive={user.liked}
            activeColor="yellow"
            defaultColor="white"
          />}
        >
          <img style={{ width: '100%', height: 'auto' }} src={user.avatar} alt="profile" />
        </GridTile>
      </div>
    ))}
  </div>;

ActionIcon.js

const ActionIcon = ({

  onIconClick,
  isActive,
  activeColor,
  defaultColor,
}) =>
  <IconButton onClick={onIconClick} >
    <StarBorder
      color={isActive ? activeColor : defaultColor}
    />
  </IconButton>;

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

10reactions
Andaristcommented, Sep 19, 2016

That’s probably cause you are running somehow watchSubmitLike twice. Could you post a snippet with the moment you are starting your root saga and this one?

6reactions
cusxiocommented, Feb 16, 2017

Just faced this issue, however I realised that my sagas were being instantiated twice instead of being called twice by LOCATION_CHANGE.

Turns out, it’s a bug from react-router-redux, leaving it here so that someone finds it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Redux-Saga is running twice for a single action - Stack Overflow
The saga listens for an action of type SUBMIT_LIKE . My problem is that the submitLikeSaga is running twice for each SUBMIT_LIKE action....
Read more >
Concurrency - Redux-Saga
takeLatest doesn't allow multiple Saga tasks to be fired concurrently. As soon as it gets a new dispatched action, it cancels any previously-forked...
Read more >
Control when Saga Generators are Called with TakeLatest
[01:09] If there's already an instance of the generator function running when it sees this dispatched type, it will cancel it and start...
Read more >
Handling Side Effects in Redux: Redux-Saga - Soshace
In redux-saga, we move our side-effects from the action-creators to generator functions called sagas. What redux-saga does is to run our ...
Read more >
Using Saga To Accumulate And Deduplicate Redux Actions
One of the components of admin-on-rest is called <ReferenceField> , and it's perfect to fetch references based on a foreign key.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found