{"id":369174,"date":"2021-11-19T01:00:00","date_gmt":"2021-11-18T22:00:00","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-get-started-with-redux-for-javascript-state-management-cloudsavvy-it\/"},"modified":"2021-11-19T01:00:00","modified_gmt":"2021-11-18T22:00:00","slug":"how-to-get-started-with-redux-for-javascript-state-management-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-get-started-with-redux-for-javascript-state-management-cloudsavvy-it\/","title":{"rendered":"#How to Get Started with Redux for JavaScript State Management \u2013 CloudSavvy IT"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a3071be3b6d4\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a3071be3b6d4\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-get-started-with-redux-for-javascript-state-management-cloudsavvy-it\/#What_Does_Redux_Do\" >What Does Redux Do?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-get-started-with-redux-for-javascript-state-management-cloudsavvy-it\/#Structuring_Your_Project\" >Structuring Your Project<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-get-started-with-redux-for-javascript-state-management-cloudsavvy-it\/#Installing_and_Configuring_Redux\" >Installing and Configuring Redux<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-get-started-with-redux-for-javascript-state-management-cloudsavvy-it\/#Using_Redux_In_React\" >Using Redux In React<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#How to Get Started with Redux for Java<a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">Script<\/a> State Management \u2013 CloudSavvy IT&#8221;<\/strong><\/p>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage imgchk9 alignnone wp-image-4160 size-full\" srcset=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2020\/03\/9c80fe24.png?width=398&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 400w, https:\/\/www.cloudsavvyit.com\/p\/uploads\/2020\/03\/9c80fe24.png?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 1200w\" sizes=\"auto, 400w, 1200w\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2020\/03\/9c80fe24.png?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Redux logo\" width=\"700\" height=\"300\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Redux is a state management tool, built specifically for client-side JavaScript applications that depend heavily on complex data and external APIs, and provides great developer tools that make it easy to work with your data.<\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"What_Does_Redux_Do\"><\/span>What Does Redux Do?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Simply put, Redux is a centralized data store. All of your application data is stored in one large object. The <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/zalmoxisus\/redux-devtools-extension\">Redux Devtools<\/a>\u00a0make this easy to visualize:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"imgchk9 alignnone wp-image-4158 size-full\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2020\/03\/f38d625b.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"A visualized Redux data store\" width=\"700\" height=\"327\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>This state is immutable, which is a strange concept at first, but makes sense for a few reasons. If you want to modify the state, you have to send out an\u00a0<em>action<\/em>, which basically takes a few arguments, forms a payload, and sends it over to Redux. Redux passes the current state to a\u00a0<em>reducer<\/em> function, which modifies the existing state and returns a new state that replaces the current one and triggers a reload of the affected components. For example, you might have a reducer to add a new item to a list, or remove or edit one that already exists.<\/p>\n<p>Doing it this way means you\u2019ll never get any undefined behavior with your app-modifying state at will. Also, because there\u2019s a record of each action, and what it changed, it enables time-<a href=\"https:\/\/buradabiliyorum.com\/en\/category\/trip-and-travel\/\" data-internallinksmanager029f6b8e52c=\"10\" title=\"Trip &amp; Travel\" target=\"_blank\" rel=\"noopener\">travel<\/a> debugging, where you can scroll your application state back to debug what happens with each action (much like a git history).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"imgchk9 alignnone wp-image-4159 size-full\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2020\/03\/12fcbfb8.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"A record of each action\" width=\"700\" height=\"333\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Redux can be used with any frontend framework, but it\u2019s commonly used with React, and that\u2019s what we\u2019ll focus on here. Under the hood, Redux uses React\u2019s <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/reactjs.org\/docs\/context.html\">Context API<\/a>, which works similarly to Redux and is good for simple apps if you want to forego Redux altogether. However, Redux\u2019s Devtools are fantastic when working with complex data, and it\u2019s actually more optimized to prevent unnecessary rerenders.<\/p>\n<p>If you\u2019re using TypeScript, things are a lot more complicated to get Redux strictly typed. You\u2019ll want to follow <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/piotrwitek\/react-redux-typescript-guide\">this guide instead<\/a>, which uses <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/piotrwitek\/typesafe-actions\"><code>typesafe-actions<\/code><\/a>\u00a0to handle the actions and reducers in a type-friendly manner.<\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Structuring_Your_Project\"><\/span>Structuring Your Project<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>First, you\u2019ll want to lay out your folder structure. This is up to you and your team\u2019s styling preferences, but there are basically two main patterns most Redux projects use. The first is simply splitting each type of file (action, reducer, middleware, side-effect) into its own folder, like so:<\/p>\n<pre>store\/&#13;\n  actions\/&#13;\n  reducers\/&#13;\n  sagas\/&#13;\n  middleware\/&#13;\n  index.js<\/pre>\n<p>This isn\u2019t the best though, as you\u2019ll often need both an action and reducer file for each feature you add. It\u2019s better to merge the actions and reducers folders, and split them up by feature. This way, each action and corresponding reducer are in the same file. You<\/p>\n<pre>store\/&#13;\n  features\/&#13;\n    todo\/&#13;\n    etc\/&#13;\n  sagas\/&#13;\n  middleware\/&#13;\n  root-reducer.js&#13;\n  root-action.js&#13;\n  index.js<\/pre>\n<p>This cleans up the imports, as now you can import both the actions and reducers in the same statement using:<\/p>\n<pre>import { todosActions, todosReducer } from\u00a0'store\/features\/todos'<\/pre>\n<p>It\u2019s up to you whether you want to keep Redux code in its own folder (<code>\/store<\/code>\u00a0in the above examples), or integrate it into your app\u2019s root src folder. If you\u2019re already separating code per component, and are writing a lot of custom actions and reducers for each component, you might want to merge the <code>\/features\/<\/code>\u00a0and <code>\/components\/<\/code>\u00a0folders, and store JSX components alongside reducer code.<\/p>\n<p>If you\u2019re using Redux with TypeScript, you can add an additional file in each feature folder to define your types.<\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Installing_and_Configuring_Redux\"><\/span>Installing and Configuring Redux<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Install Redux and React-Redux from NPM:<\/p>\n<pre>npm install redux react-redux<\/pre>\n<p>You\u2019ll also probably want <code>redux-devtools<\/code>:<\/p>\n<pre>npm install --save-dev redux-devtools<\/pre>\n<p>The first thing you\u2019ll want to create is your store. Save this as <code>\/store\/index.js<\/code><\/p>\n<pre>import { createStore } from 'redux'&#13;\nimport rootReducer from '.\/root-reducer'&#13;\n&#13;\nconst store = createStore(rootReducer)&#13;\n&#13;\nexport default store;<\/pre>\n<p>Of course, your store will get more complicated than this as you add things like side-effect addons, middleware, and other utilities like <code><a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/supasate\/connected-react-router\">connected-react-router<\/a><\/code>, but this is all that\u2019s required for now. This file takes the root reducer, and calls <code>createStore()<\/code>\u00a0using it, which is exported for the app to use.<\/p>\n<p>Next up, we\u2019ll create a simple to-do list feature. You\u2019ll probably want to start by defining the actions this feature requires, and the arguments that are passed to them. Create a <code>\/features\/todos\/<\/code>\u00a0folder, and save the following as <code>types.js<\/code>:<\/p>\n<pre>export const ADD = 'ADD_TODO'&#13;\nexport const DELETE = 'DELETE_TODO'&#13;\nexport const EDIT = 'EDIT_TODO'<\/pre>\n<p>This defines a few string constants for the action names. Regardless of the data you\u2019re passing around, each action will have a <code>type<\/code>\u00a0property, which is a unique string that identifies the action.<\/p>\n<p>You aren\u2019t required to have a type file like this, as you can just type out the string name of the action, but it\u2019s better for interoperability to do it this way. For example, you could have <code>todos.ADD<\/code>\u00a0and <code>reminders.ADD<\/code>\u00a0in the same app, which saves you the hassle of typing <code>_TODO<\/code>\u00a0or <code>_REMINDER<\/code> every time you reference an action for that feature.<\/p>\n<p>Next, save the following as <code>\/store\/features\/todos\/actions.js<\/code>:<\/p>\n<pre>import * as types from '.\/types.js'&#13;\n&#13;\nexport const addTodo = text =&gt; ({ type: types.ADD, text })&#13;\nexport const deleteTodo = id =&gt; ({ type: types.DELETE, id })&#13;\nexport const editTodo = (id, text) =&gt; ({ type: types.EDIT, id, text })<\/pre>\n<p>This defines a few actions using the types from the string constants, laying out the arguments and payload creation for each one. These don\u2019t have to be entirely static, as they are functions\u2014one example that you might use is setting a runtime <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/ericelliott\/cuid\">CUID<\/a>\u00a0for certain actions.<\/p>\n<p>The most complicated bit of code, and where you\u2019ll implement most of your business logic, is in the reducers. These can take many forms, but the most commonly used setup is with a switch statement that handles each case based on the action type. Save this as <code>reducer.js<\/code>:<\/p>\n<pre>import * as types from '.\/types.js'&#13;\n&#13;\nconst initialState = [&#13;\n  {&#13;\n    text: 'Hello World',&#13;\n    id: 0&#13;\n  }&#13;\n]&#13;\n&#13;\nexport default function todos(state = initialState, action) {&#13;\n  switch (action.type) {&#13;\n    case types.ADD:&#13;\n      return [&#13;\n        ...state,&#13;\n        {&#13;\n          id: state.reduce((maxId, todo) =&gt; Math.max(todo.id, maxId), -1) + 1,&#13;\n          text: action.text&#13;\n        }&#13;\n      ]    &#13;\n&#13;\n    case types.DELETE:&#13;\n      return state.filter(todo =&gt;&#13;\n        todo.id !== action.id&#13;\n      )&#13;\n&#13;\n    case types.EDIT:&#13;\n      return state.map(todo =&gt;&#13;\n        todo.id === action.id ? { ...todo, text: action.text } : todo&#13;\n      )&#13;\n&#13;\n    default:&#13;\n      return state&#13;\n  }&#13;\n}<\/pre>\n<p>The state is passed as an argument, and each case returns a modified version of the state. In this example, <code>ADD_TODO<\/code>\u00a0appends a new item to the state (with a new ID each time), <code>DELETE_TODO<\/code>\u00a0removes all items with the given ID, and <code>EDIT_TODO<\/code>\u00a0maps and replaces the text for the item with the given ID.<\/p>\n<p>The initial state should also be defined and passed to the reducer function as the default value for the state variable. Of course, this doesn\u2019t define your entire Redux state structure, only the <code>state.todos<\/code>\u00a0section.<\/p>\n<p>These three files are usually separated in more complex apps, but if you want, you can also define them all in one file, just make sure you\u2019re importing and exporting properly.<\/p>\n<p>With that feature complete, let\u2019s hook it up to Redux (and to our app). In <code>\/store\/root-reducer.js<\/code>, import the todosReducer (and any other feature reducer from the <code>\/features\/<\/code>\u00a0folder), then pass it to <code>combineReducers()<\/code>, forming one top-level root reducer that is passed to the store. This is where you\u2019ll set up the root state, making sure to keep each feature on its own branch.<\/p>\n<pre>import { combineReducers } from 'redux';&#13;\n&#13;\nimport todosReducer from '.\/features\/todos\/reducer';&#13;\n&#13;\nconst rootReducer = combineReducers({&#13;\n  todos: todosReducer&#13;\n})&#13;\n&#13;\nexport default rootReducer<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Using_Redux_In_React\"><\/span>Using Redux In React<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Of course, none of this is useful if it\u2019s not connected to React. To do so, you\u2019ll have to wrap your entire app in a <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/react-redux.js.org\/api\/provider\">Provider<\/a> component. This makes sure that the necessary state and hooks are passed down to every component in your app.<\/p>\n<p>In <code>App.js<\/code>\u00a0or <code>index.js<\/code>, wherever you have your root render function, wrap your app in a <code>&lt;Provider&gt;<\/code>, and pass it the store (imported from <code>\/store\/index.js<\/code>) as a prop:<\/p>\n<div>\n<pre>import\u00a0React\u00a0from\u00a0'react';&#13;\nimport\u00a0ReactDOM\u00a0from\u00a0'react-dom';&#13;\n&#13;\n\/\/\u00a0Redux\u00a0Setup&#13;\nimport\u00a0{\u00a0Provider\u00a0}\u00a0from\u00a0'react-redux';&#13;\nimport\u00a0store,\u00a0{\u00a0history\u00a0}\u00a0from\u00a0'.\/store';&#13;\n&#13;\nReactDOM.render(&#13;\n\u00a0\u00a0\u00a0\u00a0&lt;Provider\u00a0store={store}&gt;&#13;\n       &lt;App\/&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0&lt;\/Provider&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0,\u00a0document.getElementById('root'));<\/pre>\n<\/div>\n<p>You are now free to use Redux in your components. The easiest method is with function components and hooks. For example, to dispatch an action, you will use the <code>useDispatch()<\/code>\u00a0hook, which allows you to call actions directly, e.g.\u00a0<code>dispatch(todosActions.addTodo(text))<\/code>.<\/p>\n<p>The following container has an input connected to local React state, which is used to add a new todo to the state whenever a button is clicked:<\/p>\n<div>\n<pre>import\u00a0React,\u00a0{\u00a0useState\u00a0}\u00a0from\u00a0'react';&#13;\n&#13;\nimport\u00a0'.\/Home.css';&#13;\n&#13;\nimport\u00a0{\u00a0TodoList\u00a0}\u00a0from\u00a0'components'&#13;\nimport\u00a0{\u00a0todosActions\u00a0}\u00a0from\u00a0'store\/features\/todos'&#13;\nimport\u00a0{\u00a0useDispatch\u00a0}\u00a0from\u00a0'react-redux'&#13;\n&#13;\nfunction\u00a0Home()\u00a0{&#13;\n\u00a0\u00a0const\u00a0dispatch\u00a0=\u00a0useDispatch();&#13;\n\u00a0\u00a0const\u00a0[text,\u00a0setText]\u00a0=\u00a0useState(\"\");&#13;\n&#13;\n\u00a0\u00a0function\u00a0handleClick()\u00a0{&#13;\n\u00a0\u00a0\u00a0\u00a0dispatch(todosActions.addTodo(text));&#13;\n\u00a0\u00a0\u00a0\u00a0setText(\"\");&#13;\n\u00a0\u00a0}&#13;\n&#13;\n\u00a0\u00a0function\u00a0handleChange(e:\u00a0React.ChangeEvent&lt;HTMLInputElement&gt;)\u00a0{&#13;\n\u00a0\u00a0\u00a0\u00a0setText(e.target.value);&#13;\n\u00a0\u00a0}&#13;\n&#13;\n\u00a0\u00a0return\u00a0(&#13;\n\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0className=\"App\"&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;header\u00a0className=\"App-header\"&gt;&#13;\n&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input\u00a0type=\"text\"\u00a0value={text}\u00a0onChange={handleChange}\u00a0\/&gt;&#13;\n&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button\u00a0onClick={handleClick}&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Add\u00a0New\u00a0Todo&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/button&gt;&#13;\n&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;TodoList\u00a0\/&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/header&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;&#13;\n\u00a0\u00a0);&#13;\n}&#13;\n&#13;\nexport\u00a0default\u00a0Home;<\/pre>\n<p>Then, when you want to make use of the data stored in state, use the <code>useSelector<\/code>\u00a0hook. This takes a function that selects part of the state for use in the app. In this case, it sets the <code>post<\/code>\u00a0variable to the current list of todos. This is then used to render a new todo item for each entry in <code>state.todos<\/code>.\n<\/div>\n<div>\n<div>\n<pre>import\u00a0React\u00a0from\u00a0'react';&#13;\nimport\u00a0{\u00a0useSelector\u00a0}\u00a0from\u00a0'store'&#13;\n&#13;\nimport\u00a0{\u00a0Container,\u00a0List,\u00a0ListItem,\u00a0Title\u00a0}\u00a0from\u00a0'.\/styles'&#13;\n&#13;\nfunction\u00a0TodoList()\u00a0{&#13;\n\u00a0\u00a0const\u00a0posts\u00a0=\u00a0useSelector(state\u00a0=&gt;\u00a0state.todos)&#13;\n&#13;\n\u00a0\u00a0return\u00a0(&#13;\n\u00a0\u00a0\u00a0\u00a0&lt;Container&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;List&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{posts.map(({\u00a0id,\u00a0title\u00a0})\u00a0=&gt;\u00a0(&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;ListItem\u00a0key={title}&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Title&gt;{title}\u00a0:\u00a0{id}&lt;\/Title&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/ListItem&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0))}&#13;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/List&gt;&#13;\n\u00a0\u00a0\u00a0\u00a0&lt;\/Container&gt;&#13;\n\u00a0\u00a0);&#13;\n}&#13;\n&#13;\nexport\u00a0default\u00a0TodoList;<\/pre>\n<p>You can actually create <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/redux.js.org\/recipes\/computing-derived-data\/\">custom selector functions<\/a>\u00a0to handle this for you, saved in the <code>\/features\/<\/code>\u00a0folder much like actions and reducers.<\/p>\n<p>Once you have everything set up and figured out, you might want to look into setting up <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/zalmoxisus\/redux-devtools-extension\">Redux Devtools<\/a>, setting up middleware like <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/LogRocket\/redux-logger\">Redux Logger<\/a>\u00a0or <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/supasate\/connected-react-router\"><code>connected-react-router<\/code><\/a>, or installing a side effect model such as <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/redux-saga.js.org\/\">Redux Sagas<\/a>.\n<\/div>\n<\/div>\n<\/div>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.cloudsavvyit.com\/4156\/how-to-get-started-with-redux-for-javascript-state-management\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#How to Get Started with Redux for JavaScript State Management \u2013 CloudSavvy IT&#8221; Redux is a state management tool, built specifically for client-side JavaScript applications that depend heavily on complex data and external APIs, and provides great developer tools that make it easy to work with your data. What Does Redux Do? Simply put, Redux&#8230;<\/p>\n","protected":false},"author":1,"featured_media":369175,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2020\/03\/9c80fe24.png","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-369174","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/369174","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=369174"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/369174\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/369175"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=369174"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=369174"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=369174"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}