Hacker News new | comments | show | ask | jobs | submit login
Understanding redux-saga: From action creators to sagas (logrocket.com)
16 points by efunction 37 days ago | hide | past | web | 11 comments | favorite



This fails to demonstrate any benefit. The end result, ease of implementation, action flow and performance are the same, with a couple extra abstractions in the middle. What does it achieve?


Redux-saga is overkill for simpler use cases (like basic API requests), but it's a life saver for taming heavily asynchronous workflows. I used it for dealing with crypto operations in EnvKey[1], and I really couldn't have gotten by without it. It makes chains of asynchronously interdependent actions almost as easy to reason about as normal synchronous code. There's a learning curve, but it does pay off in projects of sufficient complexity. At this point, I'd say it's my favorite library in the whole Redux ecosystem.

1 - https://www.envkey.com


One key advantage of redux-saga is testability-- since sagas are essentially functions with their arguments passed in by the saga middleware, it is easy to inject mocked dependencies in a test environment.


It isn't hard to create easily testable redux actions using redux-thunk. When you configure the redux store you can use `thunk.withExtraArgument` to provide a service object to your actions, so you can write something like this:

  const getDog = dogId => (dispatch, getState, { DogApi }) => {
    dispatch(fetchingDog(dogId))
    DogApi.getDogById(dogId, (err, dog) => {
      dispatch(err ? dogFetchError(err) : fetchedDog(dog))
    })
  }

  ...

  dispatch(getDog(123))


Strongly agree having worked on projects that use redux-saga. More difficult to debug, more magic, no real benefits. I would love to be proven wrong however.


How large were the projects? Was there a high level of concurrency? redux-saga is definitely an example of over-engineering unless you fully understand its benefits (which are many, depending on context).


The main project I worked on that had redux saga was a very simple concept that I think would have had no problem without it. There was no complex behavior. I think your insight about over-engineering would definitely apply here. It was apart of the basic boilerplate of the front-end from the beginning in this project despite not having a reason to use it. This seems to be a common theme based on the react developers I have been in contact with.


Agreed, not sure what this gives over redux-promise-middleware, which lets you write things like:

    function myAction () {
      return {
        type: 'MY_ACTION',
        payload: someApiCall(),
      }
    }
And that will dispatch `MY_ACTION_PENDING`, then `MY_ACTION_FULFILLED` or `MY_ACTION_REJECTED`. Soon you'll be able to write your payload as an `async function`:

    function myAction () {
      return {
        type: 'MY_ACTION',
        async payload (dispatch) {
          const apiResult = await someApiCall()

          dispatch(anotherActionCauseWhyNot(apiResult))

          return apiResult
        }
      }
    }
I'm sure there's more to redux-saga, but this article doesn't do a great job of presenting that.


The library helps manage complex, concurrent in-flight workflows. Games are a great example of this, or something like a flight booking app that communicates with many different processes and servers and you need to ensure that fine-grained control is maintained at all times.


Another benefit of redux-saga not mentioned here is the ability to build stateful sagas. For example, something like a game loop can be encoded in a saga like this:

export default function* playGame({ getState, selectors }) { yield take(GAME_READY);

  const refreshDelay = 1000 / FPS;

  while (true) { 
    yield take(START_GAME_PLAY);

    while (true) { 
      const {
        gameState: {
          speed,
          isPlaying,
          gameTime,
        },
      } = getState();

      if (!isPlaying) {
        // game play has stopped
        break;
      }

      const timeDelta = refreshDelay * speed;
      yield put(setGameTime(gameTime + timeDelta));

      // sleep
      yield call(delay, refreshDelay);
    }
  }
}


redux-sagas are awesome. If you have a complicated web app (and most apps aren't) then it's a godsend. It really simplifies a lot of the business logic. You do have to be careful about performance though.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: