{"componentChunkName":"component---src-components-blog-template-js","path":"/blog/redux-saga/","result":{"data":{"markdownRemark":{"frontmatter":{"title":"Redux Saga","date":"2019-07-16"},"html":"<p>Redux Saga is a middleware library that is used to handle side-effects from asynchronous actions in Redux. It is way more complex compared to <code class=\"language-text\">Redux-Thunk</code>\nThere are trade-offs for both Thunk or Saga, so we can not say that Saga is better than Thunk, it depends on each use case.</p>\n<h4>Intro to Saga</h4>\n<p>A saga is actually a story created to handle all logic related to side-effects in asynchronous actions. It has special abilities to start, pause or stop the functions. These abilities are based on the new ES6 feature called <code class=\"language-text\">generator</code>\nA generator looks just like a normal function, except it has the word <code class=\"language-text\">yield</code> inside it. With this yield, we can pause, restart or resume the function as many times as we like.\nYou can read more about generator functions in my other blog post <a href=\"/blog/generator\">here</a></p>\n<h4>Differences between Thunk and Saga</h4>\n<p>With <code class=\"language-text\">Thunk</code> we can create an action that returns a function, but in <code class=\"language-text\">Saga</code> we return an object.\nIn general, Thunk is often used in a simple or small scale app, whereas Saga is used in a more complex and bigger app. This is because as the app is getting larger or more complex, the actions inside Thunk can get nested and messy.</p>\n<p>The code below is an example usage of Redux-Saga:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> takeLatest <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'redux-saga'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> call<span class=\"token punctuation\">,</span> put <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'redux-saga/effects'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">import</span> validateLogin <span class=\"token keyword\">from</span> <span class=\"token string\">'./actions'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span><span class=\"token operator\">*</span> <span class=\"token function\">loginFormSubmit</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">payload</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> result <span class=\"token operator\">=</span> <span class=\"token keyword\">yield</span> <span class=\"token function\">call</span><span class=\"token punctuation\">(</span>validateLogin<span class=\"token punctuation\">,</span> payload<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">yield</span> <span class=\"token function\">put</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">type</span><span class=\"token operator\">:</span> <span class=\"token string\">'LOGIN_SUCCESS'</span><span class=\"token punctuation\">,</span> payload <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">yield</span> <span class=\"token function\">put</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">type</span><span class=\"token operator\">:</span> <span class=\"token string\">'LOGIN_FAIL'</span><span class=\"token punctuation\">,</span> payload <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span><span class=\"token operator\">*</span> <span class=\"token function\">watchSaga</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">yield</span><span class=\"token operator\">*</span> <span class=\"token function\">takeLatest</span><span class=\"token punctuation\">(</span><span class=\"token string\">'ON_FORM_SUBMIT'</span><span class=\"token punctuation\">,</span> loginFormSubmit<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> watchSaga<span class=\"token punctuation\">;</span></code></pre></div>\n<p>From the code above, we run watchSaga as a watcher saga, we yield takeLatest inside it.</p>\n<p><code class=\"language-text\">takeLatest</code> is a helper function that has a task to listen or watch for <strong>ON<em>FORM</em>SUBMIT</strong> action dispatched and then it will run loginFormSubmit.\n<code class=\"language-text\">put</code> and <code class=\"language-text\">call</code> in the code above is called Redux-Saga <code class=\"language-text\">effects</code>, both are plain JavaScript objects that carry instructions to be executed by the middleware.\n_call* is like its name, call a <em>validateLogin</em> with payload as the given argument, whereas <em>put</em>, will dispatch an action to the <code class=\"language-text\">Store</code>\nIn the code above, if login validation is success, it will dispatch <strong>LOGIN_SUCCESS</strong> otherwise it will dispatch <strong>LOGIN_FAIL</strong> to the Store.</p>\n<p>Then all we need to do for the code above to run is to put it inside the middleware:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> createStore<span class=\"token punctuation\">,</span> applyMiddleware <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'redux'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> createSagaMiddleware <span class=\"token keyword\">from</span> <span class=\"token string\">'redux-saga'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> rootSaga <span class=\"token keyword\">from</span> <span class=\"token string\">'./sagas'</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">//...</span>\n<span class=\"token keyword\">const</span> sagaMiddleware <span class=\"token operator\">=</span> <span class=\"token function\">createSagaMiddleware</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> store <span class=\"token operator\">=</span> <span class=\"token function\">createStore</span><span class=\"token punctuation\">(</span>reducers<span class=\"token punctuation\">,</span> <span class=\"token function\">applyMiddleware</span><span class=\"token punctuation\">(</span>sagaMiddleware<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">//...</span>\nsagaMiddleware<span class=\"token punctuation\">.</span><span class=\"token function\">run</span><span class=\"token punctuation\">(</span>rootSaga<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>That's it! The next step is to create a reducer to handle all the actions dispatched, which is not covered in here.</p>\n<p>The way a saga with generator function works is that once the promise is run and yielded, it will not continue until the promise is resolved. Everytime an effect or a yield statement is found, it will pause or suspend and resume again after the promise is resolved.</p>"}},"pageContext":{"slug":"/redux-saga/"}},"staticQueryHashes":[]}