{"id":24415,"date":"2023-09-29T05:00:00","date_gmt":"2023-09-29T03:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=24415"},"modified":"2024-07-22T14:31:41","modified_gmt":"2024-07-22T12:31:41","slug":"introduction-to-redux-saga","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/en\/introduction-to-redux-saga\/","title":{"rendered":"Introduction to Redux-Saga"},"content":{"rendered":"\n<p>Redux-Saga is a middleware library for managing asynchronous operations in Redux applications. It was created to address some of the limitations of Redux-Thunk, which was the most popular middleware for handling asynchronous operations in Redux applications at the time.<\/p>\n\n\n\n<p>Redux-Saga is based on the concept of &#8220;sagas&#8221;, which are <strong>long-lived processes running in the background of the application<\/strong> and managing the flow of asynchronous data. Sagas can be thought of as separate threads in the application, handling complex side effects such as network calls, timers, and other asynchronous operations.<\/p>\n\n\n\n<p>In this article, I will give you an introduction to the history of this library, and describe its installation and configuration. In addition, you will also find information about dispatch actions and functions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>History of Redux-Saga<\/strong><\/h2>\n\n\n\n<p>Redux-Saga was created by Yelldigital \u2013 a web and mobile development agency based in Germany, in 2016. The developers at Yelldigital were unhappy with the limitations of Redux-Thunk and believed that there was a better way to handle asynchronous operations in Redux applications.<\/p>\n\n\n\n<p>The idea for Redux-Saga came from <strong>a similar library called Elm Effects<\/strong>, which was popular in the Elm programming community. The creators of Redux-Saga took inspiration from Elm Effects and aimed to create a similar solution for Redux applications.<\/p>\n\n\n\n<p>The initial release of Redux-Saga was met with enthusiasm from the Redux community, with <strong>many developers praising its simplicity, testability, and maintainability<\/strong>. Since then, Redux-Saga has become one of the most popular middleware libraries for Redux applications, with a large and active developer community contributing to its development and maintenance.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Installation and configuration<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Install Redux-Saga<\/strong><\/h3>\n\n\n\n<p>To use Redux-Saga in your React project, you need to install it first. You can use either npm or yarn to install it. If you&#8217;re using npm, run the following command:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nnpm install redux-saga\n<\/pre><\/div>\n\n\n<p>If you&#8217;re using yarn, run the following command:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nyarn add redux-saga\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><strong>Create Sagas<\/strong><\/h3>\n\n\n\n<p>Next, you need to create your sagas. Sagas are generator functions that handle the side effects (such as API calls) and dispatch Redux actions. Here&#8217;s an example saga that makes an API call to get some data:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { call, put, takeEvery } from &#039;redux-saga\/effects&#039;;\nimport { fetchSuccess, fetchFailure } from &#039;.\/actions&#039;;\nimport { api } from &#039;.\/api&#039;;\n\nfunction* fetchDataSaga(action) {\n  try {\n    const data = yield call(api.fetchData, action.payload);\n    yield put(fetchSuccess(data));\n  } catch (error) {\n    yield put(fetchFailure(error.message));\n  }\n}\n\nfunction* rootSaga() {\n  yield takeEvery(&#039;FETCH_DATA_REQUEST&#039;, fetchDataSaga);\n}\n\nexport default rootSaga;\n<\/pre><\/div>\n\n\n<p>In this example, we first import the necessary Redux-Saga functions, Redux actions, and an API service. We then create a generator function called `fetchDataSaga` that uses the `call` effect to call the API service and `put` effect to dispatch a success or failure action depending on the result.<\/p>\n\n\n\n<p>We then create another generator function called `rootSaga` that uses the `takeEvery` effect to watch for a specific Redux action (`FETCH_DATA_REQUEST`) and run the `fetchDataSaga` generator function when the action is dispatched.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Integrate Sagas with Redux Store<\/strong><\/h3>\n\n\n\n<p>After creating your sagas, you need to integrate them with your Redux store using the `createSagaMiddleware` function from the Redux-Saga library. Here&#8217;s an example of how to configure your store to use Redux-Saga:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { applyMiddleware, combineReducers, createStore } from &#039;redux&#039;;\nimport createSagaMiddleware from &#039;redux-saga&#039;;\nimport dataReducer from &#039;.\/reducers&#039;;\nimport rootSaga from &#039;.\/sagas&#039;;\n\nconst rootReducer = combineReducers({\n  data: dataReducer,\n});\n\nconst sagaMiddleware = createSagaMiddleware();\n\nconst store = createStore(\n  rootReducer,\n  applyMiddleware(sagaMiddleware),\n);\n\nsagaMiddleware.run(rootSaga);\n\nexport default store;\n<\/pre><\/div>\n\n\n<p>In this example, we first import the necessary Redux and Redux-Saga functions, reducers, and sagas. We then create our root reducer using the `combineReducers` function, create a saga middleware instance using the `createSagaMiddleware` function, and apply it to the store using the `applyMiddleware` function.<\/p>\n\n\n\n<p>Finally, we run the root saga using the `sagaMiddleware.run` function and export the store for use in our application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Dispatch Actions<\/strong><\/h2>\n\n\n\n<p>To trigger the saga, you need to dispatch the Redux action it&#8217;s listening for. Here&#8217;s an example of how to dispatch the `FETCH_DATA_REQUEST` action:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { useDispatch } from &#039;react-redux&#039;;\nimport { fetchDataRequest } from &#039;.\/actions&#039;;\n\nexport function App() {\n  const dispatch = useDispatch();\n\n  useEffect(() =&gt; {\n    dispatch(fetchDataRequest(&#039;url\/to\/data&#039;));\n  }, &#x5B;dispatch]);\n\n  return (\n    \/\/ your component&#039;s JSX\n  );\n}\n<\/pre><\/div>\n\n\n<p>We first import the `useDispatch` hook and the `fetchDataRequest` action from our Redux actions. We then create a functional component called `App` and call the `useDispatch` hook to get a reference to the dispatch function.<\/p>\n\n\n\n<p>In the `useEffect` hook, we dispatch the `fetchDataRequest` action with a URL to fetch our data. This will trigger the `FETCH_DATA_REQUEST` action in our saga, which will in turn call our API service and dispatch either a success or failure action depending on the result.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Redux-Saga functions<\/strong><\/h2>\n\n\n\n<p>Here are some of the most commonly used Redux-Saga functions and their explanations.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>`takeEvery`<\/strong><\/h3>\n\n\n\n<p>This function creates a non-blocking saga that listens for a specific Redux action and runs a generator function every time the action is dispatched.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { takeEvery } from &#039;redux-saga\/effects&#039;;\n\nfunction* mySaga() {\n  yield takeEvery(&#039;MY_ACTION&#039;, myGeneratorFunction);\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><strong><strong>`takeLatest`<\/strong><\/strong><\/h3>\n\n\n\n<p>This function is similar to `takeEvery`, but it only runs the latest instance of a generator function if multiple instances are triggered before the first has completed.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { takeLatest } from &#039;redux-saga\/effects&#039;;\n\nfunction* mySaga() {\n  yield takeLatest(&#039;MY_ACTION&#039;, myGeneratorFunction);\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>`call` <\/strong><\/h2>\n\n\n\n<p>This function is used to call a function that returns a promise, such as an API call. The generator function waits for the promise to resolve before continuing to the next line of code.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { call } from &#039;redux-saga\/effects&#039;;\n\nfunction* mySaga() {\n  const result = yield call(myFunction, arg1, arg2);\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><strong>`put` <\/strong><\/h3>\n\n\n\n<p>This function is used to dispatch a new action to the Redux store.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { put } from &#039;redux-saga\/effects&#039;;\n\nfunction* mySaga() {\n  yield put({ type: &#039;MY_NEW_ACTION&#039;, payload: data });\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><strong>`all` <\/strong><\/h3>\n\n\n\n<p>This function is used to run multiple sagas at once in parallel. It waits for all the sagas to complete before continuing to the next line of code.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { all } from &#039;redux-saga\/effects&#039;;\n\nfunction* mySaga() {\n  yield all(&#x5B;myFirstSaga(), mySecondSaga()]);\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><strong>`race` <\/strong><\/h3>\n\n\n\n<p>This function is used to run multiple sagas at once and resolve with the first saga that completes.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { race } from &#039;redux-saga\/effects&#039;;\n\nfunction* mySaga() {\n  yield race(&#x5B;myFirstSaga(), mySecondSaga()]);\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><strong>`select` <\/strong><\/h3>\n\n\n\n<p>This function is used to access the current state of the Redux store in your saga.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { select } from &#039;redux-saga\/effects&#039;;\n\nfunction* mySaga() {\n  const state = yield select();\n}\n<\/pre><\/div>\n\n\n<p>These are just a few of the many functions available in Redux-Saga. These functions allow you to create complex asynchronous processes in your Redux store and manage them in a more organised and maintainable way.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Summary<\/strong><\/h2>\n\n\n\n<p>In summary, Redux-Saga is a powerful middleware library for Redux that allows you to manage complex asynchronous processes in a more organised and maintainable way. By using generator functions and a set of pre-built functions, it provides a clear, structured approach to managing side effects like API calls, handling callbacks, and more. Additionally, its declarative style makes the code more predictable, easier to read, and easier to test than traditional async code.<\/p>\n\n\n\n<p>It&#8217;s essential for developers to <strong>understand Redux-Saga because managing asynchronous processes is critical<\/strong> to building modern web applications. Redux-Saga provides a more structured and organised approach to managing these processes, reducing the complexity and making it easier to maintain a large, complex codebase.<\/p>\n\n\n\n<p>It&#8217;s also worth noting that Redux-Saga is just one of many approaches to managing asynchronous processes in Redux. Other libraries like Redux-Thunk and Redux-Observable offer different trade-offs and may be better suited for certain use cases.<\/p>\n\n\n\n<p>Overall, understanding Redux-Saga (and other Redux middleware libraries) is a valuable skill for any React developer, and can make a significant difference in the maintainability and scalability of your application.<\/p>\n\n\n\n<p>***<\/p>\n\n\n\n<p>If you&#8217;re interested in other tools and programs, also <a href=\"https:\/\/sii.pl\/blog\/wyszukiwarka\/narz%C4%99dzia\/\" target=\"_blank\" aria-label=\"check out our other expert articles (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">check out our other expert articles<\/a>.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;24415&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;1&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( vote: 1)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Introduction to Redux-Saga&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( vote: 1)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Redux-Saga is a middleware library for managing asynchronous operations in Redux applications. It was created to address some of the &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/en\/introduction-to-redux-saga\/\">Continued<\/a><\/p>\n","protected":false},"author":564,"featured_media":24424,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1320],"tags":[2622,1800,1799,1590],"class_list":["post-24415","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hard-development","tag-digital-en","tag-redux-saga","tag-redux","tag-tools"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/Introduction-to-Redux-Saga.jpg","category_names":["Hard development"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/24415"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/users\/564"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/comments?post=24415"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/24415\/revisions"}],"predecessor-version":[{"id":24426,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/24415\/revisions\/24426"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media\/24424"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media?parent=24415"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/categories?post=24415"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/tags?post=24415"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}