{"id":2160,"date":"2018-04-26T17:35:17","date_gmt":"2018-04-26T16:35:17","guid":{"rendered":"https:\/\/sandbox.weareadaptive.com\/?p=2160\/"},"modified":"2018-09-28T15:44:37","modified_gmt":"2018-09-28T14:44:37","slug":"working-normalized-state-redux-applications","status":"publish","type":"post","link":"https:\/\/sandbox.weareadaptive.com\/fr\/2018\/04\/26\/working-normalized-state-redux-applications\/","title":{"rendered":"Working with normalized state in Redux applications"},"content":{"rendered":"<p style=\"text-align: center;\">Original source: <a href=\"https:\/\/barvi.co.uk\/blog\/2018\/04\/07\/redux-normalized-state.html\" rel=\"noopener\">Barvi.co.uk<\/a><\/p>\n<p style=\"text-align: center;\">Author:\u00a0<a href=\"https:\/\/www.linkedin.com\/in\/syzov\/\" rel=\"noopener\">Vlad Syzov<\/a>, Senior Front-end developer at Adaptive, London<\/p>\n<p>&nbsp;<\/p>\n<p>In pre-Redux, pre-immutable front-end world there was mostly no need to have a normalized application state. Building your application state structure was simple &#8211; you would just use multiple models which refer each other. Then one model instance can be easily referred by multiple other models and each model can be updated individually without affecting the rest of the application state.<\/p>\n<p>In Redux world, sooner or later you will end up with a need to normalize your state (<small><em>note: this post will not explain why you would normalize the Redux state in a large app &#8211; this deserves a separate post<\/em><\/small>). Accessing entities in a normalized state might be a complicated task because data related to one entity is scattered across multiple state slices. So naturally, you will start exploring ways to simplify the reasoning about application state. This article proposes a way to solve this problem.<\/p>\n<p>How does the normalized state look? Let\u2019s say, your application manages records of drivers and their cars. In pre-Redux world, you would \u2018nest\u2019 objects by references, so there would be an \u2018intuitive\u2019 and \u2018straightforward\u2019 way to get cars of a driver (<code class=\"highlighter-rouge\">someDriver.cars<\/code>). Here is how normalized state for this app might look like:<\/p>\n<div class=\"language-ts highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"default\" data-enlighter-title=\"\">{\r\n    drivers: {\r\n        &#039;1&#039;: {\r\n            id: &#039;1&#039;,\r\n            name: &#039;Kevin Potter&#039;\r\n        },\r\n        &#039;2&#039;: {\r\n            id: &#039;2&#039;,\r\n            name: &#039;Keith Johnson&#039;\r\n        }\r\n    },\r\n    cars: {\r\n        &#039;3&#039;: {\r\n            id: &#039;3&#039;,\r\n            name: &#039;Daewoo Lanos&#039;,\r\n            driverId: &#039;1&#039;\r\n        },\r\n        &#039;4&#039;: {\r\n            id: &#039;4&#039;,\r\n            name: &#039;McLaren&#039;,\r\n            driverId: &#039;2&#039;\r\n        },\r\n        &#039;5&#039;: {\r\n            id: &#039;5&#039;,\r\n            name: &#039;Ferrari&#039;,\r\n            driverId: &#039;2&#039;\r\n        }\r\n    }\r\n}<\/pre>\n<\/div>\n<\/div>\n<p><small><em>&#8211; please note that I deliberately chose to have\u00a0<code class=\"highlighter-rouge\">Car<\/code>\u00a0record referring its\u00a0<code class=\"highlighter-rouge\">Driver<\/code>\u00a0and not to have\u00a0<code class=\"highlighter-rouge\">Driver<\/code>\u00a0referring his list of car IDs. More on this choice later as this is not the main goal of this post<\/em><\/small><\/p>\n<p>As you see from example above, normalized state is very different &#8211; you can\u2019t access cars of a certain driver by just drilling down the properties of the object, so you can\u2019t do something like\u00a0<code class=\"highlighter-rouge\">driver.cars<\/code>. Instead, you will need to get cars who\u2019s\u00a0<code class=\"highlighter-rouge\">driverId<\/code>\u00a0matches id of your driver. Here\u2019s how this would look like:<\/p>\n<div class=\"language-ts highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"default\" data-enlighter-title=\"\">const driverId = &#039;2&#039;;\r\nconst carsOfDriver = Object.keys(state.cars)\r\n  .map((carId: string) =&gt; state.cars[carId])\r\n  .filter((car: Car) =&gt; car.driverId === driverId);<\/pre>\n<\/div>\n<\/div>\n<p><small><em>&#8211; please note that all examples are written in TypeScript because I hardly see writing a large-scale application in pure JS<\/em><\/small><\/p>\n<p>As you see that\u2019s a lot of code to just get cars of the driver, compare this with\u00a0<code class=\"highlighter-rouge\">someDriver.cars<\/code>\u00a0in non-normalized state.<\/p>\n<p>Now imagine that you will need this functionality in a lot of places &#8211; anywhere where you need to access cars of a driver. It is, of course, reasonable to extract this code into a separate function (redux selector for example), let\u2019s say you put it in\u00a0<code class=\"highlighter-rouge\">DriverSelector<\/code>\u00a0selector. But as the application grows and amount of normalized state slices grows, you will find that you start forgetting which selector to use in which case. Compare this selectors approach with non-Redux application model management &#8211; there you would not even need to remember how to get cars of the driver, intellisense is always there to help you to write\u00a0<code class=\"highlighter-rouge\">someDriver.cars<\/code>.<\/p>\n<p>But in our normalized Redux state there\u2019s nothing that tells you what selector to use in which case, as there\u2019s no link between your state shape and selectors that you need to use. And the biggest problem of the normalized state is that it does not represent a human-readable world which we are used to. Our brains are not trained to think in normalized forms.<\/p>\n<h2 id=\"introducing-projection\">Introducing \u2018Projection\u2019<\/h2>\n<p>In Redux application, you wish to just think about\u00a0<code class=\"highlighter-rouge\">Driver<\/code>\u00a0entity and not think how it is stored in the state, that parts of entity are stored in different state slice (<code class=\"highlighter-rouge\">Cars<\/code>). Let\u2019s think which API will be suitable to achieve this simplification. Ideally, we are trying to get back to\u00a0<code class=\"highlighter-rouge\">someDriver.cars<\/code>\u00a0simplicity from non-normalized state world. Here\u2019s what we would be happy with:<\/p>\n<div class=\"language-ts highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"default\" data-enlighter-title=\"\">const carsOfDriver = driverApi.cars;<\/pre>\n<\/div>\n<\/div>\n<p>If we get\u00a0<code class=\"highlighter-rouge\">driverApi<\/code>\u00a0to indeed represent\u00a0<code class=\"highlighter-rouge\">Driver<\/code>\u00a0entity and hide the normalization of the state for us, we should be happy.<\/p>\n<p>Here\u2019s where the pattern\u00a0<code class=\"highlighter-rouge\">Projection<\/code>\u00a0comes in. It takes the idea from the\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Object-relational_mapping\" rel=\"noopener\">ORM<\/a>\u00a0principles (normalize Redux state is very similar to a relational database). The idea is to create a\u00a0<code class=\"highlighter-rouge\">View<\/code>\u00a0(or\u00a0<code class=\"highlighter-rouge\">Projection<\/code>) for your entity and let this view \u2018gather\u2019 data from multiple state slices. Then, when you need to access your state, you no longer access it via\u00a0<code class=\"highlighter-rouge\">state.someProperty<\/code>, you don\u2019t access the state directly at all. Instead, you always use\u00a0<code class=\"highlighter-rouge\">Projection<\/code>\u00a0which transforms normalized, non-readable state into a shape which human brain can easily work with. Here\u2019s how the use of such projection API will look like:<\/p>\n<div class=\"language-ts highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"default\" data-enlighter-title=\"\">const driver = new DriverProjection(state, &#039;2&#039;);\r\nconst carsOfDriver = driver.cars;<\/pre>\n<\/div>\n<\/div>\n<p>And here\u2019s an implementation of this\u00a0<code class=\"highlighter-rouge\">Projection<\/code>\u00a0pattern:<\/p>\n<div class=\"language-ts highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"default\" data-enlighter-title=\"\">\/\/ private function inside your Projection module\r\nfunction getCarsForDriver(state: AppState, driverId: string): Array&lt;Car&gt; {\r\n  return Object.keys(state.cars)\r\n    .map((id: string) =&gt; state.cars[id])\r\n    .filter((car: Car) =&gt; car.driverId === driverId);\r\n}\r\n\r\nclass DriverProjection {\r\n  constructor(private state: AppState, private driverId: string) {\r\n  }\r\n\r\n  get cars(): Array&lt;Car&gt; {\r\n    return getCarsForDriver(this.state, driverId);\r\n  }\r\n}<\/pre>\n<\/div>\n<\/div>\n<p>As you see, the structure of the state is encapsulated behind the getter, so developer who uses projection does not need to know the shape of the complex normalized state to access the data. It is important to understand\u00a0<code class=\"highlighter-rouge\">Projection<\/code>\u2019s main benefit compared with selector (because one might say that selector hides the state structure as well). The difference is that you can hide multiple getters and selectors under one projection and let users of your projection API only think about high-level application entity &#8211;\u00a0<code class=\"highlighter-rouge\">Driver<\/code>\u00a0and intellisense will guide the user through possible properties of the entity. So we are going back to a non-normalized, \u2018straightforward\u2019 and natural reasoning about application state. This is hardly achievable when having multiple selectors scattered all over your app.\u00a0<code class=\"highlighter-rouge\">Projection<\/code>groups selectors for you and hides them under the facade that is easily understood, you can say that\u00a0<code class=\"highlighter-rouge\">Projection<\/code>\u00a0\u2018de-normalizes\u2019 the state for you.<\/p>\n<h2 id=\"memoization\">Memoization<\/h2>\n<p>There is one optimization that we can make to Projection. As you see, each invocation of\u00a0<code class=\"highlighter-rouge\">cars<\/code>\u00a0getter will create a new array. We can prevent this with memoization. If\u00a0<code class=\"highlighter-rouge\">state<\/code>\u00a0and\u00a0<code class=\"highlighter-rouge\">driverId<\/code>\u00a0don\u2019t change, we should not recalculate the array. You are welcome to use any memoization library, here we will stop on\u00a0<code class=\"highlighter-rouge\">reselect<\/code>\u00a0as this is what a lot of people in React-Redux community are used to:<\/p>\n<div class=\"language-ts highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"default\" data-enlighter-title=\"\">import { createSelector } from &#039;reselect&#039;;\r\n\r\n\/\/ private function inside your Projection module\r\nconst getCarsForDriver = (cars: Cars, driverId: string): Array&lt;Car&gt; =&gt;\r\n  Object.keys(cars)\r\n    .map((id: string) =&gt; cars[id])\r\n    .filter((car: Car) =&gt; car.driverId === driverId);\r\n\r\nclass DriverProjection {\r\n  \/\/ private instance of memoized selector\r\n  private carsForDriverSelector = createSelector(\r\n    state =&gt; state.cars,\r\n    (state, driverId) =&gt; driverId,\r\n    getCarsForDriver\r\n  );\r\n\r\n  constructor(private state: AppState, private driverId: string) {\r\n  }\r\n\r\n  get cars(): Array&lt;Car&gt; {\r\n    return this.carsForDriverSelector(this.state, this.driverId);\r\n  }\r\n}<\/pre>\n<\/div>\n<\/div>\n<p>Now every\u00a0<code class=\"highlighter-rouge\">.cars<\/code>\u00a0getter invocation will return the same instance of array.<\/p>\n<h2 id=\"using-in-react\">Using in React<\/h2>\n<p>The great thing about \u2018Projection\u2019 approach is that you can also use it in connected React-Redux components. Here\u2019s your\u00a0<code class=\"highlighter-rouge\">mapStateToProps<\/code>\u00a0of the connected component which displays cars of a given driver:<\/p>\n<div class=\"language-ts highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"default\" data-enlighter-title=\"\">const mapStateToProps = (state: AppState, props: DriverContainerProps): DriverProps =&gt; {\r\n  const driver = new DriverProjection(state, props.driverId);\r\n  return {\r\n    cars: driver.cars\r\n  };\r\n};<\/pre>\n<\/div>\n<\/div>\n<p>As you see, we again don\u2019t need to use selectors at all &#8211; we only use\u00a0<code class=\"highlighter-rouge\">Driver<\/code>\u00a0projection.<\/p>\n<p>There\u2019s a final optimization that we can do here &#8211; making sure that our projection instance is not recreated on every store update ( our memoized selector would not actually work if new projection instance is created every time). For this optimization let\u2019s add a method\u00a0<code class=\"highlighter-rouge\">update<\/code>\u00a0to the projection which allows us to update the state value and not recreate selectors every time:<\/p>\n<div class=\"language-ts highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"default\" data-enlighter-title=\"\">class DriverProjection {\r\n\r\n  \/\/...\r\n\r\n  update(state: AppState, driverId: string) {\r\n    this.state = this.state;\r\n    this.driverId = this.driverId;\r\n  }\r\n\r\n  \/\/...\r\n}<\/pre>\n<\/div>\n<\/div>\n<p>And here\u2019s a complete example of how to use it in React-Redux:<\/p>\n<div class=\"language-ts highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"default\" data-enlighter-title=\"\">const makeMapStateToProps = (state: AppState, props: DriverContainerProps) =&gt; {\r\n  \/\/ projection is created once when component is mounted\r\n  const driverProjection = new DriverProjection(state, props.driverId);\r\n\r\n  return (state: AppState, props: DriverContainerProps): GroupProps =&gt; {\r\n    \/\/ here we update the projection with latest &#039;state&#039; and &#039;driverId&#039;\r\n    driverProjection.update(state, props.driverId);\r\n\r\n    return {\r\n      \/\/ this &#039;cars&#039; getter will return same array instance every time\r\n      \/\/ if arguments for calculating cars didn&#039;t change\r\n      cars: driverProjection.cars\r\n    };\r\n  };\r\n};<\/pre>\n<\/div>\n<\/div>\n<h2 id=\"summary\">Summary<\/h2>\n<p>One might say that such\u00a0<code class=\"highlighter-rouge\">Projection<\/code>\u00a0approach over-complicates the application. It is indeed true for most Redux applications, specifically for those which do not use normalized state.<\/p>\n<p>But as soon as you try to write a large, scalable React-Redux application, you will face with a problem of reasoning about the normalized state. Unfortunately, sometimes you might realize the scale of the problem when it\u2019s too late to go back and fix things. So please consider this or similar approach if you are writing a large React-Redux application.<\/p>\n<h4 id=\"some-useful-links\">Some useful links:<\/h4>\n<ul>\n<li><a href=\"https:\/\/redux.js.org\/recipes\/structuring-reducers\/normalizing-state-shape\" rel=\"noopener\">Intro<\/a>\u00a0to \u2018normalized state\u2019 from Redux website<\/li>\n<li><a href=\"https:\/\/github.com\/reactjs\/reselect#createstructuredselectorinputselectors-selectorcreator--createselector\" rel=\"noopener\">Structured selectors<\/a>\u00a0from \u2018reselect\u2019 library &#8211; something that can be used for the same purpose as projections but has its own limitations in my view<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<div class=\"row center-col main-content\">\n<div class=\"col s12 m12 l12 xl12 main-content\">\n<div class=\"post-content center\">\n<p class=\"center hide-on-med-and-down\">Let&rsquo;s discuss a project<\/p>\n<p><a class=\"waves-effect waves-light btn-flat cta-talk\" href=\"https:\/\/sandbox.weareadaptive.com\/contact\/\">Let&rsquo;s talk<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Original source: Barvi.co.uk Author:\u00a0Vlad Syzov, Senior Front-end developer at Adaptive, London &nbsp; In pre-Redux, pre-immutable front-end world there was mostly &#8230;<\/p>\n","protected":false},"author":24,"featured_media":2161,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,144,135],"tags":[125,62,124,126],"class_list":["post-2160","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","category-front-end-ui-ux","category-reactive-web-development","tag-normalized-state","tag-react","tag-redux","tag-redux-applications"],"_links":{"self":[{"href":"https:\/\/sandbox.weareadaptive.com\/fr\/wp-json\/wp\/v2\/posts\/2160"}],"collection":[{"href":"https:\/\/sandbox.weareadaptive.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sandbox.weareadaptive.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sandbox.weareadaptive.com\/fr\/wp-json\/wp\/v2\/users\/24"}],"replies":[{"embeddable":true,"href":"https:\/\/sandbox.weareadaptive.com\/fr\/wp-json\/wp\/v2\/comments?post=2160"}],"version-history":[{"count":0,"href":"https:\/\/sandbox.weareadaptive.com\/fr\/wp-json\/wp\/v2\/posts\/2160\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sandbox.weareadaptive.com\/fr\/wp-json\/wp\/v2\/media\/2161"}],"wp:attachment":[{"href":"https:\/\/sandbox.weareadaptive.com\/fr\/wp-json\/wp\/v2\/media?parent=2160"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sandbox.weareadaptive.com\/fr\/wp-json\/wp\/v2\/categories?post=2160"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sandbox.weareadaptive.com\/fr\/wp-json\/wp\/v2\/tags?post=2160"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}