{"id":1351,"date":"2025-02-27T00:00:00","date_gmt":"2025-02-26T23:00:00","guid":{"rendered":"https:\/\/demo.sidekick.be\/itenium\/reduxjs-toolkit-createselector\/"},"modified":"2025-11-28T13:31:41","modified_gmt":"2025-11-28T12:31:41","slug":"reduxjs-toolkit-createselector","status":"publish","type":"post","link":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/","title":{"rendered":"ReduxJS\/Toolkit: createSelector"},"content":{"rendered":"<h1 id=\"examples\">Examples<\/h1>\n<p>By convention, selectors are named <a href=\"https:\/\/redux.js.org\/style-guide\/#name-selector-functions-as-selectthing\"><code>selectThing<\/code><\/a>:<\/p>\n<ul>\n<li><code>inputSelectors<\/code>: The first argument, the dependencies, is an array of root state selectors<\/li>\n<li><code>combiner<\/code>: The second argument, the result function, calculates the derived state<\/li>\n<li><code>createSelectorOptions<\/code>: The third (optional) options argument configures how the selector behaves<\/li>\n<\/ul>\n<pre><code class=\"language-ts\">import { createSelector } from \"@reduxjs\/toolkit\";\n\nconst selectMyTodosCompletedCount = createSelector(\n  [\n    (state: RootState) =&gt; state.todos,\n    (state: RootState) =&gt; state.user.id,\n  ],\n  (todos, userId) =&gt; {\n    return todos.filter(todo =&gt; todo.userId === userId &amp;&amp; todo.done).length;\n  }\n)\n\n\n\/\/ Usage in a component\nimport { useSelector } from \"react-redux\";\n\nconst TodosDoneCount = () =&gt; {\n  const doneCount = useSelector(selectMyTodosCompletedCount);\n  return &lt;&gt;\u2714\ufe0f {doneCount}&lt;\/&gt;;\n}\n<\/code><\/pre>\n<p>Every time the root state changes, it will execute the inputSelectors; in this case <code>state.todos<\/code> and <code>state.user.id<\/code>. If the returned references have not changed, the memoized count is returned, otherwise the combiner is executed.<\/p>\n<p>This is also why you want to select the todos and the userId separately, if you select them as <code>({todos: state.todos, userId: state.user.id})<\/code>, you\u2019d get a new reference every time, effectively rendering the selector useless!<\/p>\n<p>The Reselect development-only <a href=\"https:\/\/reselect.js.org\/api\/development-only-stability-checks#inputstabilitycheck\"><code>inputStabilityCheck<\/code><\/a> executes the selector twice and logs a warning to the console if one of the inputSelectors returns a different reference.<\/p>\n<h2 id=\"with-parameters\">With Parameters<\/h2>\n<p>Filter the todo list with a needle parameter.<\/p>\n<pre><code class=\"language-ts\">const selectTodos = createSelector(\n  [\n    (state: RootState) =&gt; state.todos,\n    (_, needle: string) =&gt; needle,\n  ],\n  (todos, needle) =&gt; todos.filter(todo =&gt; todo.text.includes(needle))\n)\n\n\/\/ Usage in a component\nconst TodoList = ({searchNeedle}) =&gt; {\n  const todos = useSelector(state =&gt; selectTodos(state, searchNeedle));\n  return todos.map(todo =&gt; (\n    &lt;Todo key={todo.id} todo={todo} \/&gt;\n  );\n}\n<\/code><\/pre>\n<p>If you don\u2019t like this syntax, see the <a href=\"https:\/\/reselect.js.org\/FAQ#how-can-i-make-a-curried-selector\">Reselect FAQ<\/a> on how to create a curried selector instead.<\/p>\n<pre><code class=\"language-ts\">\/\/ This would allow you to do this instead:\nconst todos = useSelector(selectTodos(searchNeedle));\n\n\/\/ The FAQ also contains a recipe to turn this into:\nconst todos = useSelectTodos(searchNeedle);\n<\/code><\/pre>\n<h3 id=\"multiple-parameters\">Multiple Parameters<\/h3>\n<pre><code class=\"language-ts\">const selectTodos = createSelector(\n  [\n    (state: RootState) =&gt; state.todos,\n    (_, needle: string) =&gt; needle,\n    (_, __, caseSensitive: boolean) =&gt; caseSensitive\n  ],\n  (todos, needle, caseSensitive) =&gt; { \/* magic here *\/ }\n)\n<\/code><\/pre>\n<h2 id=\"createselectoroptions\">createSelectorOptions<\/h2>\n<p>Reselect will only execute the combiner fn when the inputs have changed, which is typically your entire root state (with potentially additional parameters) AND the result of those input selectors has changed.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/itenium-be.github.io\/blog-posts-new\/assets\/blog-images\/reduxjs-toolkit-reselect-how-it-works.png\" alt=\"How reselect works\" title=\"How reselect works\" class=\"img-responsive\" \/><\/p>\n<p>Configure this behavior with <code>argsMemoize(Options)<\/code> and <code>memoize(Options)<\/code>.<\/p>\n<p>If you want to change the default behavior of many\/all selectors, use <a href=\"https:\/\/reselect.js.org\/api\/createSelectorCreator\">createSelectorCreator<\/a>.<\/p>\n<h3 id=\"lrumemoize\">lruMemoize<\/h3>\n<p><a href=\"https:\/\/reselect.js.org\/api\/lruMemoize\"><code>lruMemoize<\/code><\/a> (Least Recently Used) was the default before v5 of Reselect. It had a default cache size of 1, meaning a recomputation every time one of the inputSelectors changed.<\/p>\n<p>The \u201cproblem\u201d with lruMemoize was that a cache of size 1 might not be that useful! This was typically solved with <code>useMemo<\/code> or by passing <code>memoizeOptions: { maxSize: 5 }<\/code>.<\/p>\n<pre><code class=\"language-ts\">import { lruMemoize } from \"reselect\";\nimport { shallowEqual } from \"react-redux\";\n\nexport const selectMyTodosCompletedCount = createSelector(\n  [(state: RootState) =&gt; ({todos: state.todos, userId: state.more.users.ids[0]})],\n  ({todos, userId}) =&gt;  todos.filter(todo =&gt; todo.userId === userId &amp;&amp; todo.done).length,\n  {\n    memoize: lruMemoize,\n    memoizeOptions: {\n      equalityCheck: (a, b) =&gt; a.todos === b.todos &amp;&amp; a.userId === b.userId,\n      \/\/ resultEqualityCheck: shallowEqual,\n      \/\/ maxSize: 10\n    },\n    \/\/ argsMemoize: lruMemoize,\n    \/\/ argsMemoizeOptions: {\n    \/\/   equalityCheck: shallowEqual,\n    \/\/   resultEqualityCheck: shallowEqual,\n    \/\/   maxSize: 10\n    \/\/ }\n  }\n)\n<\/code><\/pre>\n<h3 id=\"weakmapmemoize-default\">weakMapMemoize (default)<\/h3>\n<p><a href=\"https:\/\/reselect.js.org\/api\/weakMapMemoize\"><code>weakMapMemoize<\/code><\/a> is the new default since v5 and provides a dynamic cache size out of the box.<\/p>\n<h3 id=\"unstable_autotrackmemoize-experimental\">unstable_autotrackMemoize (experimental)<\/h3>\n<p>There is also the experimental <a href=\"https:\/\/reselect.js.org\/api\/unstable_autotrackMemoize\"><code>unstable_autotrackMemoize<\/code><\/a>, which, like <code>proxy-memoize<\/code> below, can be more efficient.<\/p>\n<pre><code class=\"language-ts\">import { unstable_autotrackMemoize } from \"reselect\";\n\n\/\/ The combiner (todos.filter) will NOT execute when we\n\/\/ toggle a Todo between done\/not done as that field is\n\/\/ not accessed.\nconst selectTodos = createSelector(\n  [\n    (state: RootState) =&gt; state.todos,\n    (_, needle: string) =&gt; needle,\n  ],\n  (todos, needle) =&gt; todos.filter(todo =&gt; todo.text.includes(needle)),\n  {\n    memoize: unstable_autotrackMemoize,\n  }\n)\n<\/code><\/pre>\n<h1 id=\"createslice\">createSlice<\/h1>\n<p>Common selectors can already be defined in the <code>createSlice<\/code> setup.<\/p>\n<pre><code class=\"language-ts\">const todoSlice = createSlice({\n  initialState: [],\n\n  \/\/ Predefined selectors, which receive the slice's state as their first parameter.\n  selectors: {\n    selectTodo: (state, id: number): Todo | undefined =&gt; {\n      return state.find(todo =&gt; todo.id === id);\n    },\n  },\n});\n\nexport const { selectTodo } = todoSlice.selectors;\n\n\/\/ Usage in a component\nconst todo = useSelector(state =&gt; selectTodo(state, todoId));\n<\/code><\/pre>\n<h1 id=\"typescript\">TypeScript<\/h1>\n<p>See <a href=\"\/blog\/javascript\/reduxjs-toolkit-typescript\/\">ReduxJS\/Toolkit: TypeScript<\/a> if you\u2019re unsure how to create the <code>RootState<\/code>.<\/p>\n<pre><code class=\"language-ts\">import { createSelector } from \"@reduxjs\/toolkit\";\nconst createAppSelector = createSelector.withTypes&lt;RootState&gt;();\n<\/code><\/pre>\n<h1 id=\"debugging\">Debugging<\/h1>\n<p><a href=\"https:\/\/github.com\/skortchmark9\/reselect-tools\" class=\"github\"><img decoding=\"async\" src=\"https:\/\/img.shields.io\/github\/stars\/skortchmark9\/reselect-tools.svg?style=social&amp;label=Star\" \/><\/a><a href=\"https:\/\/github.com\/skortchmark9\/reselect-tools\">skortchmark9\/reselect-tools<\/a>: Debugging Tools for Reselect<\/p>\n<p>Once you get many selectors depending on other selectors, you can use this tool to visualize re-computations.<\/p>\n<p>If your debugging needs are basic, you can check the <a href=\"https:\/\/reselect.js.org\/api\/createSelector#output-selector-fields\">Output Selector Fields<\/a>:<\/p>\n<pre><code class=\"language-ts\">const meta = {\n  lastResult: selectMyTodosCompletedCount.lastResult(),\n  recomputations: selectMyTodosCompletedCount.recomputations(),\n  dependencyRecomputations: selectMyTodosCompletedCount.dependencyRecomputations(),\n}\n<\/code><\/pre>\n<h1 id=\"alternatives\">Alternatives<\/h1>\n<h2 id=\"proxy-memoize\">proxy-memoize<\/h2>\n<p><a href=\"https:\/\/github.com\/dai-shi\/proxy-memoize\" class=\"github\"><img decoding=\"async\" src=\"https:\/\/img.shields.io\/github\/stars\/dai-shi\/proxy-memoize.svg?style=social&amp;label=Star\" \/><\/a><a href=\"https:\/\/github.com\/dai-shi\/proxy-memoize\">dai-shi\/proxy-memoize<\/a>: Intuitive magical memoization library with Proxy and WeakMap<\/p>\n<p>This will re-execute when the <code>done<\/code> property toggles even though it has no impact on the actual result.<\/p>\n<pre><code class=\"language-ts\">import { createSelector } from \"reselect\";\n\nconst selectTodoDescriptionsReselect = createSelector(\n  [state =&gt; state.todos],\n  todos =&gt; todos.map(todo =&gt; todo.text)\n)\n<\/code><\/pre>\n<p>With <code>proxy-memoize<\/code>, this would not be the case as due to the proxy, it figures only text is actually relevant for selector.<\/p>\n<pre><code class=\"language-ts\">import { memoize } from \"proxy-memoize\";\n\nconst selectTodoDescriptionsProxy = memoize(state =&gt;\n  state.todos.map(todo =&gt; todo.text)\n)\n<\/code><\/pre>\n<p>For this reason <strong>the ReduxJS\/Toolkit officially encourages you to consider using proxy-memoize as a viable alternative to Reselect.<\/strong><\/p>\n<h2 id=\"re-reselect\">re-reselect<\/h2>\n<p><a href=\"https:\/\/github.com\/toomuchdesign\/re-reselect\" class=\"github\"><img decoding=\"async\" src=\"https:\/\/img.shields.io\/github\/stars\/toomuchdesign\/re-reselect.svg?style=social&amp;label=Star\" \/><\/a><a href=\"https:\/\/github.com\/toomuchdesign\/re-reselect\">toomuchdesign\/re-reselect<\/a>: Enhance Reselect selectors with deeper memoization and cache management.<\/p>\n<p>As of Reselect v5, what you\u2019d need this library for can now achieved with Reselect <code>createSelectorOptions<\/code> natively.<\/p>\n<h1>Also in this series<\/h1>\n<ul>\n<li>Part 1: <a href=\"\/javascript\/reduxjs-toolkit\/\">ReduxJS\/Toolkit<\/a><\/li>\n<li>Part 2: <a href=\"\/javascript\/reduxjs-toolkit-immer\/\">ReduxJS\/Toolkit: Immer<\/a><\/li>\n<li>Part 3: <a href=\"\/javascript\/reduxjs-toolkit-createslice\/\">ReduxJS\/Toolkit: createSlice and configureStore<\/a><\/li>\n<li>Part 4: <a href=\"\/javascript\/reduxjs-toolkit-createasyncthunk\/\">ReduxJS\/Toolkit: createAsyncThunk<\/a><\/li>\n<li>Part 5: <a href=\"\/javascript\/reduxjs-toolkit-typescript\/\">ReduxJS\/Toolkit: TypeScript<\/a><\/li>\n<li>This Part: ReduxJS\/Toolkit: createSelector<\/li>\n<\/ul>\n<h1>Extras<\/h1>\n<p><b>Stuff that came into being during the making of this post<\/b><\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/itenium-be\/reduxjs-toolkit\">Check todoSelectors.ts to see the examples in action<\/a><\/li>\n<\/ul>\n<p><b>Other interesting reads<\/b><\/p>\n<ul>\n<li><a href=\"https:\/\/itenium.be\/blog\/javascript\/react-component-profiling\/\">React Component Profiling also goes into some detail with Reselect for performance optimalizations<\/a><\/li>\n<\/ul>\n<h1> Package Versions <i class=\"fa fa-info-circle\" style=\"float: right; color: cornflowerblue; font-size: 28px\" title=\"Package versions used for this post and in the accompanying code on Github\"><\/i><\/h1>\n<div><a href=\"https:\/\/github.com\/reduxjs\/reselect\" class=\"github\"><img decoding=\"async\" src=\"https:\/\/img.shields.io\/github\/stars\/reduxjs\/reselect.svg?style=social&#038;label=Star\" \/><\/a><a href=\"https:\/\/github.com\/reduxjs\/reselect\">reduxjs\/reselect<\/a>: v5.1.1 <\/div>\n","protected":false},"excerpt":{"rendered":"<p><a href=\"https:\/\/github.com\/reduxjs\/reselect\" class=\"github\"><img decoding=\"async\" src=\"https:\/\/img.shields.io\/github\/stars\/reduxjs\/reselect.svg?style=social&amp;label=Star\" \/><\/a><a href=\"https:\/\/github.com\/reduxjs\/reselect\">reduxjs\/reselect<\/a>: Create memoized \u2018selector\u2019 functions<\/p>\n<p>One of the Redux Style Guide \u201cStrongly Recommended\u201d rules is <a href=\"https:\/\/redux.js.org\/style-guide\/#keep-state-minimal-and-derive-additional-values\">Keep State Minimal and Derive Additional Values<\/a>:<\/p>\n<p class=\"notice--info\">Keep the actual data in the Redux store as minimal as possible, and derive additional values from that state as needed.<\/p>\n<p>Another strongly recommended rule is <a href=\"https:\/\/redux.js.org\/style-guide\/#normalize-complex-nestedrelational-state\">Normalize Complex Nested\/Relational State<\/a><\/p>\n<p class=\"notice--info\">Many applications need to cache complex data in the store. That data is often received in a nested form from an API, or has relations between different entities in the data (such as a blog that contains Users, Posts, and Comments).<\/p>\n<p>Of course your components are interested in those derived values and in the nested data. Keeping those calculations and recombining the data efficient is where <code>createSelector<\/code> comes into play.<\/p>\n","protected":false},"author":1,"featured_media":1961,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[3],"tags":[22,6],"class_list":["post-1351","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript","tag-react","tag-tutorial"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>ReduxJS\/Toolkit: createSelector - Itenium<\/title>\n<meta name=\"robots\" content=\"noindex, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ReduxJS\/Toolkit: createSelector - Itenium\" \/>\n<meta property=\"og:description\" content=\"reduxjs\/reselect: Create memoized \u2018selector\u2019 functionsOne of the Redux Style Guide \u201cStrongly Recommended\u201d rules is Keep State Minimal and Derive Additional Values:Keep the actual data in the Redux store as minimal as possible, and derive additional values from that state as needed.Another strongly recommended rule is Normalize Complex Nested\/Relational StateMany applications need to cache complex data in the store. That data is often received in a nested form from an API, or has relations between different entities in the data (such as a blog that contains Users, Posts, and Comments).Of course your components are interested in those derived values and in the nested data. Keeping those calculations and recombining the data efficient is where createSelector comes into play.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/\" \/>\n<meta property=\"og:site_name\" content=\"Itenium\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-26T23:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-28T12:31:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/reduxjs-toolkit-reselect.png\" \/>\n\t<meta property=\"og:image:width\" content=\"360\" \/>\n\t<meta property=\"og:image:height\" content=\"300\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Usdevelop\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Usdevelop\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/\",\"url\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/\",\"name\":\"ReduxJS\/Toolkit: createSelector - Itenium\",\"isPartOf\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/reduxjs-toolkit-reselect.png\",\"datePublished\":\"2025-02-26T23:00:00+00:00\",\"dateModified\":\"2025-11-28T12:31:41+00:00\",\"author\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022\"},\"breadcrumb\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/#primaryimage\",\"url\":\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/reduxjs-toolkit-reselect.png\",\"contentUrl\":\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/reduxjs-toolkit-reselect.png\",\"width\":360,\"height\":300,\"caption\":\"A futuristic energy core at the center of a massive digital network, precisely extracting and refining structured data from chaotic streams of information. Glowing, transparent data streams flow into the core, where a high-tech filtration system refines and optimizes them before channeling the clean output into structured pathways. The scene has a cyberpunk aesthetic, with neon-lit circuits and a sleek, high-tech control center.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/demo.sidekick.be\/itenium\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ReduxJS\/Toolkit: createSelector\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#website\",\"url\":\"https:\/\/demo.sidekick.be\/itenium\/\",\"name\":\"Itenium\",\"description\":\"We build software. We build careers.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/demo.sidekick.be\/itenium\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022\",\"name\":\"Usdevelop\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g\",\"caption\":\"Usdevelop\"},\"sameAs\":[\"https:\/\/demo.sidekick.be\/itenium\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"ReduxJS\/Toolkit: createSelector - Itenium","robots":{"index":"noindex","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"og_locale":"en_US","og_type":"article","og_title":"ReduxJS\/Toolkit: createSelector - Itenium","og_description":"reduxjs\/reselect: Create memoized \u2018selector\u2019 functionsOne of the Redux Style Guide \u201cStrongly Recommended\u201d rules is Keep State Minimal and Derive Additional Values:Keep the actual data in the Redux store as minimal as possible, and derive additional values from that state as needed.Another strongly recommended rule is Normalize Complex Nested\/Relational StateMany applications need to cache complex data in the store. That data is often received in a nested form from an API, or has relations between different entities in the data (such as a blog that contains Users, Posts, and Comments).Of course your components are interested in those derived values and in the nested data. Keeping those calculations and recombining the data efficient is where createSelector comes into play.","og_url":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/","og_site_name":"Itenium","article_published_time":"2025-02-26T23:00:00+00:00","article_modified_time":"2025-11-28T12:31:41+00:00","og_image":[{"width":360,"height":300,"url":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/reduxjs-toolkit-reselect.png","type":"image\/png"}],"author":"Usdevelop","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Usdevelop","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/","url":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/","name":"ReduxJS\/Toolkit: createSelector - Itenium","isPartOf":{"@id":"https:\/\/demo.sidekick.be\/itenium\/#website"},"primaryImageOfPage":{"@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/#primaryimage"},"image":{"@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/#primaryimage"},"thumbnailUrl":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/reduxjs-toolkit-reselect.png","datePublished":"2025-02-26T23:00:00+00:00","dateModified":"2025-11-28T12:31:41+00:00","author":{"@id":"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022"},"breadcrumb":{"@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/#primaryimage","url":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/reduxjs-toolkit-reselect.png","contentUrl":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/reduxjs-toolkit-reselect.png","width":360,"height":300,"caption":"A futuristic energy core at the center of a massive digital network, precisely extracting and refining structured data from chaotic streams of information. Glowing, transparent data streams flow into the core, where a high-tech filtration system refines and optimizes them before channeling the clean output into structured pathways. The scene has a cyberpunk aesthetic, with neon-lit circuits and a sleek, high-tech control center."},{"@type":"BreadcrumbList","@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/reduxjs-toolkit-createselector\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/demo.sidekick.be\/itenium\/"},{"@type":"ListItem","position":2,"name":"ReduxJS\/Toolkit: createSelector"}]},{"@type":"WebSite","@id":"https:\/\/demo.sidekick.be\/itenium\/#website","url":"https:\/\/demo.sidekick.be\/itenium\/","name":"Itenium","description":"We build software. We build careers.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/demo.sidekick.be\/itenium\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022","name":"Usdevelop","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g","caption":"Usdevelop"},"sameAs":["https:\/\/demo.sidekick.be\/itenium"]}]}},"_links":{"self":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts\/1351","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/comments?post=1351"}],"version-history":[{"count":2,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts\/1351\/revisions"}],"predecessor-version":[{"id":2145,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts\/1351\/revisions\/2145"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/media\/1961"}],"wp:attachment":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/media?parent=1351"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/categories?post=1351"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/tags?post=1351"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}