Redux-Sagas is based on generator functions. Whenever you call one of these, it gets executed until it reaches a yield
. This, besides allowing you to perform async actions by waiting for promises, has a bunch of advantages when it comes to testing for example.
Esentially, mocking is what is trying to be avoided here when you are testing. In order to do so, a declarative approach is followed. The point is that you don't dispatch (nor really do anything), the middleware does. You only provide this middleware with objects called Effects. So, what the put will do is to create an Effect object that the middleware will "read". Then, it will dispatch the action and use next(result)
(with result
being the result of whatever the Effect told the middleware to do) to go to the next yield and get the next Effect. You can read more about it here.
Remember that the main advantages of redux-sagas when compared to redux-thunk appear when testing comes in. Being able to just declare which Effect will be returned by each put, call... and then just iterating from yield to yield instead of having to mock API calls or dispatches is a major selling point for redux-sagas. You probably need to read and practise a little bit more before you get the concept completely but I hope my explanation solves your doubt.