{
    "componentChunkName": "component---src-templates-blog-post-js",
    "path": "/react-tutorial-working-with-redux-toolkit-with-saga/",
    "result": {"data":{"site":{"siteMetadata":{"title":"CrewCode Solutions"}},"markdownRemark":{"id":"cf94ca75-725d-52ee-b2ab-71f7aa5fd158","excerpt":"In this article i will explain you step by step to use redux toolkit with saga in react typescript application Step 1: Create react typescript application with…","html":"<p>In this article i will explain you step by step to use redux toolkit with saga in react typescript application</p>\n<h4>Step 1: Create react typescript application with following command</h4>\n<pre><code class=\"language-js\">npx create-react-app my-app --template typescript\n</code></pre>\n<h4>Step 2: Install redux, redux toolkit, redux saga, react-redux, redux-actions</h4>\n<p>In your newly created application install redux toolkit, redux saga and react-redux with following command</p>\n<pre><code class=\"language-js\">npm install --save react-redux redux-saga redux-actions @reduxjs/toolkit @types/react-redux @types/redux-saga @types/redux-actions\n</code></pre>\n<p>Install redux logger this helps in to log all triggered actions in the developer console</p>\n<pre><code class=\"language-js\">npm install --save-dev redux-logger @types/redux-logger\n</code></pre>\n<p>Install axios this helps in sending http request</p>\n<pre><code class=\"language-js\">npm install --save axios @types/axios\n</code></pre>\n<h4>Step 3: Create Store</h4>\n<p>Store act as central repository for all your state management</p>\n<p>Go to your project folder and create <strong><em>/src/store/index.ts</em></strong> this is the main file for your store creation where we will be initializing and creating store</p>\n<pre><code class=\"language-js\">import { configureStore } from \"@reduxjs/toolkit\";\nimport { createStore, applyMiddleware } from \"redux\";\nimport createSagaMiddleware from \"redux-saga\";\nimport logger from \"redux-logger\";\nimport rootReducer from \"./rootReducer\";\nimport { rootSaga } from \"./rootSaga\";\n\nexport default function configureMainStore() {\n  const sagaMiddleware = createSagaMiddleware();\n  const store = configureStore({\n    reducer: rootReducer,\n    middleware: [sagaMiddleware, logger]\n    devTools: process.env.NODE_ENV !== \"production\",\n  });\n  sagaMiddleware.run(rootSaga);\n  return { store };\n}\n</code></pre>\n<h4>Step 4: Create Root Reducer</h4>\n<p>Reducers are the pure functions that take the current state and action and return the new state and tell the store how to do</p>\n<p>Create a main reducer file as <strong><em>/src/store/rootReducer.ts</em></strong> where we will combine all the sub reducers and export it from here. Copy paste following content inside your rootReducer</p>\n<pre><code class=\"language-js\">import { combineReducers } from \"@reduxjs/toolkit\";\nimport { userslice } from \"./user\";\nimport { appslice } from \"./app\";\n\nconst reducers = combineReducers({\n  user: userslice.reducer,\n  app: appslice.reducer,\n});\n</code></pre>\n<h4>Step 5: Create Auth Reducer</h4>\n<p>We will be creating auth reducer as sub reducer i'm creating an example of login and signup to show you all how we can work for authentication in redux saga</p>\n<p>Create a file <strong><em>/src/store/userslice.ts</em></strong> and copy paste the following code</p>\n<pre><code class=\"language-js\">import { createSlice, PayloadAction } from \"@reduxjs/toolkit\";\nimport { UserType } from \"../types/user\";\n\nconst initialState: UserType = {\n  userDetails: null,\n  token: null,\n};\n\nexport const userslice = createSlice({\n  name: \"user\",\n  initialState,\n  reducers: {\n    setAuthenticationToken: (\n      state = initialState,\n      { payload }: PayloadAction&#x3C;any>\n    ) => {\n      return {\n        ...state,\n        token: payload,\n      };\n    },\n    loginAction: (state = initialState, { payload }: PayloadAction&#x3C;any>) => {\n      return {\n        ...state,\n        userDetails: payload,\n      };\n    },\n  },\n  extraReducers: {},\n});\n</code></pre>\n<h4>Step 7: Add types for Auth</h4>\n<p>Create a file <strong><em>/src/auth/store/types/user.ts</em></strong> and copy paste following code</p>\n<pre><code class=\"language-js\">export type UserType = {\n  userDetails: any,\n  token: any,\n};\n</code></pre>\n<h4>Step 7: Create Auth Action types</h4>\n<p>Actions are plain JavaScript object that must have a type attribute to indicate the type of action performed. It tells us what had happened. Types should be defined as string constants in your application as given below</p>\n<p>Create a file <strong><em>/src/store/actions/user.actions.types.ts</em></strong> and copy paste following code inside that file</p>\n<pre><code class=\"language-js\">import { createAction } from \"redux-actions\";\n\nexport const LOGIN = \"LOGIN\";\nexport const login = createAction(LOGIN);\n\nexport const REGISTER = \"REGISTER\";\nexport const register = createAction(REGISTER);\n</code></pre>\n<h4>Step 8: Create Saga middleware for Auth</h4>\n<p>Redux Saga is a middleware library used to allow a Redux store to interact with resources outside of itself asynchronously</p>\n<p>Create file <strong><em>/src/stores/sagas/user.ts</em></strong> copy paste the following code</p>\n<pre><code class=\"language-js\">import { all, put, takeLatest } from \"redux-saga/effects\";\nimport { errorMessage, successMessage } from \"../../utilities/notification\";\nimport { userslice } from \"../slices/user\";\n\nimport { LOGIN, REGISTER } from \"../actions/user.actions.types\";\nimport axios from \"axios\";\nimport * as Effects from \"redux-saga/effects\";\nconst call: any = Effects.call;\n\nconst login = async (payload: { email: string, password: string }) => {\n  const { data } = await axios.post(\n    \"https://reqres.in/api/login\",\n    { email: payload.email, password: payload.password },\n    {\n      headers: {\n        \"Content-Type\": \"application/json\",\n        Accept: \"application/json\",\n      },\n    }\n  );\n  return data;\n};\n\nconst signup = async (payload: { email: string, password: string }) => {\n  const { data } = await axios.post(\n    \"https://reqres.in/api/register\",\n    { ...payload },\n    {\n      headers: {\n        \"Content-Type\": \"application/json\",\n        Accept: \"application/json\",\n      },\n    }\n  );\n\n  return data;\n};\n\nfunction* registerHandler({ payload: { data, callback } }: any) {\n  try {\n    const response: { token: string } = yield call(signup, {\n      ...payload,\n    });\n    if (callback) {\n      callback({ success: true, data: response.token });\n    }\n  } catch (error) {\n    if (callback) {\n      callback({ success: false, data: null });\n    }\n  }\n}\n\nfunction* loginSaga({ payload: { data, callback } }: any) {\n  try {\n    const response: { token: string } = yield call(signup, {\n      ...payload,\n    });\n    yield put(userslice.actions.setAuthenticationToken(response.token));\n    if (callback) {\n      callback({ success: true, data: response.token });\n    }\n  } catch (error) {\n    if (callback) {\n      callback({ success: false, data: null });\n    }\n  }\n}\n\nfunction* authSaga() {\n  yield all([takeLatest(LOGIN, loginSaga)]);\n  yield all([takeLatest(REGISTER, registerHandler)]);\n}\n\nexport default authSaga;\n</code></pre>\n<h4>Step 9: Create Root saga which combine all the saga and export</h4>\n<p>Create a file <strong><em>/src/store/sagas/index.ts</em></strong> and copy paste the following code</p>\n<pre><code class=\"language-js\">import { all } from \"redux-saga/effects\";\nimport user from \"./user\";\n\nconst sagas = function* sagas() {\n  yield all([user()]);\n};\n\nexport default sagas;\n</code></pre>\n<h4>Step 10:Add Store provider to your index.ts file</h4>\n<p>Inside your <strong><em>src/index.tsx</em></strong> file copy paste the following code</p>\n<pre><code class=\"language-js\">import React from \"react\";\nimport ReactDOM from \"react-dom/client\";\nimport \"./index.css\";\nimport App from \"./App\";\nimport reportWebVitals from \"./reportWebVitals\";\nimport { Provider } from \"react-redux\";\nimport configureStore from \"./stores\";\n\nconst { store } = configureStore();\n\nconst root = ReactDOM.createRoot(\n  document.getElementById(\"root\") as HTMLElement\n);\nroot.render(\n  &#x3C;React.StrictMode>\n    &#x3C;Provider store={store}>\n        &#x3C;App />\n    &#x3C;/Provider>\n  &#x3C;/React.StrictMode>\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n</code></pre>\n<h4>Step 11:Inside your login page use redux saga</h4>\n<pre><code class=\"language-js\">import React, { useRef } from \"react\";\nimport { login } from \"../store/actions/user.actions.types.ts\";\nimport { connect } from \"react-redux\";\n\nconst Login: React.FC&#x3C;{}> = (props: any) => {\n  const emailRef = useRef();\n  const passwordRef = useRef();\n\n  const callback = (data: any) => {\n    console.log(\"Inside callback after login\");\n  };\n\n  const login = () => {\n    let data: any = {\n      values: {\n        email: emailRef.current.value,\n        password: passwordRef.current.value,\n      },\n      callback,\n    };\n    props.login(data);\n  };\n  return (\n    &#x3C;div>\n      &#x3C;div className=\"form-floating\">\n        &#x3C;input\n          type=\"email\"\n          className=\"form-control\"\n          name=\"email\"\n          id=\"floatingInput\"\n          placeholder=\"name@example.com\"\n          ref={emailRef}\n        />\n        &#x3C;label htmlFor=\"floatingInput\">Email address&#x3C;/label>\n      &#x3C;/div>\n\n      &#x3C;div className=\"form-floating mt-3\">\n        &#x3C;input\n          type=\"password\"\n          className=\"form-control\"\n          name=\"password\"\n          id=\"floatingPassword\"\n          placeholder=\"Password\"\n          ref={passwordRef}\n        />\n        &#x3C;label htmlFor=\"floatingPassword\">Password&#x3C;/label>\n      &#x3C;/div>\n\n      &#x3C;div className=\"checkbox mb-3 mt-3\">\n        &#x3C;label>\n          &#x3C;input name=\"remember\" type=\"checkbox\" defaultValue=\"remember-me\" />{\" \"}\n          Remember me\n        &#x3C;/label>\n      &#x3C;/div>\n      &#x3C;button\n        onClick={() => {\n          login();\n        }}\n        className=\"w-100 btn btn-lg btn-warning\"\n      >\n        Sign in\n      &#x3C;/button>\n    &#x3C;/div>\n  );\n};\n\nconst mapDispatchToProps = (dispatch: any) => ({\n  login: (params: any) => dispatch(login(params)),\n});\n\nexport default connect(null, mapDispatchToProps)(Login);\n</code></pre>","fields":{"slug":"/react-tutorial-working-with-redux-toolkit-with-saga/"},"frontmatter":{"title":"React tutorial working with redux toolkit with saga in typescript","date":"April 26, 2023","description":"In this article i will explain you step by step to setup redux toolkit with saga in typescript","bannerimage":"https://crew-code-images.s3.us-east-1.amazonaws.com/blog_images/redux-toolkit.jpeg"}},"previous":{"fields":{"slug":"/react-tutorial-using-redux-saga-typescript/"},"frontmatter":{"title":"React tutorial using redux saga in react typescript application","date":"April 16, 2023","bannerimage":"https://crew-code-images.s3.us-east-1.amazonaws.com/blog_images/React.jpg"}},"next":{"fields":{"slug":"/restapi-using-deno-oak-mongodb/"},"frontmatter":{"title":"Developing REST Api using Deno, Oak and MongoDB","date":"April 30, 2023","bannerimage":"https://crew-code-images.s3.us-east-1.amazonaws.com/blog_images/RestAPI.jpg"}}},"pageContext":{"id":"cf94ca75-725d-52ee-b2ab-71f7aa5fd158","previousPostId":"a48018e9-44ac-53f0-a03b-da9bde9fb047","nextPostId":"6d904096-d929-5403-a8d8-150a4d45b491"}},
    "staticQueryHashes": ["3860684146"]}