Redux-saga: too many watches

Created on 3 Aug 2017  路  3Comments  路  Source: redux-saga/redux-saga

Hi

I'm new to redux-saga and to open source. Where is the right place to discuss what I've written below?

I noticed when you write sagas, you write a lot of

function* watchSetUser() {
  yield takeEvery(ActionTypes.SET_USER, setUser);
}

This seems like unnecessary boilerplate and I've simplified it as follows:

const watches = [
  [takeEvery, ActionTypes.ADD_LESSON, addLesson],
  [takeLatest, ActionTypes.SET_CURRENT_LESSON, setCurrentLesson],
  [takeEvery, ActionTypes.SET_USER, setUser],
];

export default function* rootSaga() {
  const genericWatcher = function*(f, pattern, saga) {
    yield f(pattern, saga);
  };

  const allWatches = [
    ...watches,
    ...imagesWatches,
    ...loggerWatches,
  ].map(arg => {
    const [f, pattern, saga] = arg;
    return genericWatcher(f, pattern, saga);
  });
  allWatches.push(initialise());

  yield all(allWatches);
}

This has two advantages:

  1. you put all the watches for a file in a single, simple array; and
  2. you can easily combine sagas from multiple files.

What do the experts think of this? Is it a good solution? Can it be improved?

Most helpful comment

If it works for you - its a good pattern for you.

Personally I dont see quite any gain from this particular abstraction. I think most people dont realise what effects really are - they are just objects, so really this can be simplified to:

const watches = [
  takeEvery(ActionTypes.ADD_LESSON, addLesson),
  takeLatest(ActionTypes.SET_CURRENT_LESSON, setCurrentLesson),
  takeEvery(ActionTypes.SET_USER, setUser),
];

export default function* rootSaga() {
  const allWatches = [
    ...watches,
    ...imagesWatches,
    ...loggerWatches,
    initialise(),
  ]

  yield all(allWatches);
}

All 3 comments

If it works for you - its a good pattern for you.

Personally I dont see quite any gain from this particular abstraction. I think most people dont realise what effects really are - they are just objects, so really this can be simplified to:

const watches = [
  takeEvery(ActionTypes.ADD_LESSON, addLesson),
  takeLatest(ActionTypes.SET_CURRENT_LESSON, setCurrentLesson),
  takeEvery(ActionTypes.SET_USER, setUser),
];

export default function* rootSaga() {
  const allWatches = [
    ...watches,
    ...imagesWatches,
    ...loggerWatches,
    initialise(),
  ]

  yield all(allWatches);
}

Hi - thank you for your answer, it's exactly what I'm thinking of!

I think your solution is much cleaner that my solution and in comparison to the default strips out a huge amount of unnecessary code ("function* watchSetUser() {yield" for every watcher)

Glad I could help :)

Was this page helpful?
0 / 5 - 0 ratings