{
    "componentChunkName": "component---src-templates-post-js",
    "path": "/5-layers-react-state",
    "result": {"data":{"site":{"siteMetadata":{"title":"your friend Joel's digital garden","description":"Articles and notes from a collaborator at egghead.io. Musings on software, business, and life from a skilled virtual assistant.","author":{"name":"Joel Hooks"},"keywords":["Video Blogger"]}},"mdx":{"excerpt":"One of the challenges with state management in React is coming to terms and deciding as a team how you will categorize the layers of state in your application. It's variable and often nuanced to describe the layers but framing them in a…","fields":{"github":"https://github.com/joelhooks/joelhooks-com/tree/master/content/blog/2020-05-12--5-layers-react-state~~uM_l7fLmT/index.mdx"},"body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"id\": \"uM_l7fLmT\",\n  \"slug\": \"5-layers-react-state\",\n  \"date\": \"2020-05-12T00:00:00.000Z\",\n  \"title\": \"5 Layers of State Management in React Applications\",\n  \"published\": false\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"One of the challenges with state management in React is coming to terms and deciding as a team how you will categorize the layers of state in your application. It's variable and often nuanced to describe the layers but framing them in a simple hierarchy is an excellent tool for communicating with your team.\"), mdx(\"p\", null, mdx(\"span\", {\n    parentName: \"p\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1035px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/34b4f9e3fc689f8ee7b5e5f2bb0ea543/8aace/5-layers-of-state.png\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"74.90347490347492%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABRNAAAUTQGUyo0vAAAC5klEQVQ4y4WUy28TVxTG8x+k60pVu0Zi3X+AVaXuqy6QKkWq2BTUTVe0KippAygLBOLZCEpUVBPyEE0aQpxYBJzgGIc4TjJ+je3xjJ8zc8cznmCnwA/NWCY2QWJxdDSac7/7nXu+8w04pkk3bMN4l7vRFALXEriiE3uWYE8I3rRbtJtNGrr+rtY7O9D70QvUvaRaKpHPFcgViuQVjWxOIaeozMzMsb4aYd/tgHbPD/SyawoTtyFoWia2qWNWq6iVKvlqnWB4lUQ2R9myUeoGn352lOEz52H/f0S1jqjVDzPUSxVKsoqW1iglK6iJKvlkGSVfI7mdJ5tU0RSdbErjyuhtdsJZKrsmP538leiax9btApo4wkBayxCdkticzRCeiPMkEGN9cpu1iTiRyQTR6V3Wp3b8nAyqyI+r3Pz9Hz4Z/AJpa5uW43QAHcPEFjrSU5mNSZnEbIHlO1Fmbiwz/3eEhbtR7o8tk1hQkIM1MosVYtMZUgtlLp2+w29nRnj98qX/ln0Mi1KRdCRHNpqnmCgjzcfZvRIkeS2EMvaUkRMjXLo4zvWLd4kF4+Q3VF6sbGHV67iWdTAU2+yw9Iax5wgso0ZUesF0IMDS2auEzt0kNjrOjydOcezbbzhy9EsqqkLLbbDnWH2SO2jZY+qP30baWGR24g8W5y6zErxG6NFVnq38yXRglMHBz/lrbBzabX+yDb1fdgN92vOyaaFKYZ4t32ByfJjQ3GX+C1wgFr7FvVvDfHfuF5ZCIV65rt/q+xru06EXDcOgZVqsl1J8PTTE+cBtfjj9M/dXl7j37wNCUoytzThtxzm0YX7LvavnRcPQaYsGz8tpjh0/zszDeVZWw1i1ui90Qyv7dUalQk3T+rakD/CAoc6+aBApSnz1/RDy5g62oZNLp5FTKXKZjJ8VWUYrFPpa/iBD74dnAsVSkcTuNk2Pta4jajX/zTyz8Oo6pmF9vOVe0JZtHzKL3iG+bywe4Fu4AShXSbmM0wAAAABJRU5ErkJggg==')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"a stack of blocks labeled components, application, remote, router, and meta\",\n    \"title\": \"a stack of blocks labeled components, application, remote, router, and meta\",\n    \"src\": \"/static/34b4f9e3fc689f8ee7b5e5f2bb0ea543/e3189/5-layers-of-state.png\",\n    \"srcSet\": [\"/static/34b4f9e3fc689f8ee7b5e5f2bb0ea543/a2ead/5-layers-of-state.png 259w\", \"/static/34b4f9e3fc689f8ee7b5e5f2bb0ea543/6b9fd/5-layers-of-state.png 518w\", \"/static/34b4f9e3fc689f8ee7b5e5f2bb0ea543/e3189/5-layers-of-state.png 1035w\", \"/static/34b4f9e3fc689f8ee7b5e5f2bb0ea543/44d59/5-layers-of-state.png 1553w\", \"/static/34b4f9e3fc689f8ee7b5e5f2bb0ea543/a6d66/5-layers-of-state.png 2070w\", \"/static/34b4f9e3fc689f8ee7b5e5f2bb0ea543/8aace/5-layers-of-state.png 2732w\"],\n    \"sizes\": \"(max-width: 1035px) 100vw, 1035px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\",\n    \"decoding\": \"async\"\n  }), \"\\n  \"), \"\\n    \")), mdx(\"p\", null, \"One way to frame these layers of states is using the 5 Layers of State that Jed Watson proposed in his excellent talk \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.youtube.com/watch?v=tBz3UmZG_bk\"\n  }, \"A Treatise on State\"), \".\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, \"Local\"), \": component state using a combination of custom and native React Hooks often in conjunction with \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://egghead.io/courses/introduction-to-state-machines-using-xstate\"\n  }, \"xState as shown in Kyle Shevlin's excellent free egghead course\"), \".\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, \"Shared\"), \": this is a graph or network of related components that need to share state up to an including the entire application state up at the top of \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://joelhooks.com/react-potato-plant\"\n  }, \"the potato plant\"), \". There is caching involved at this layer of state and often performance concerns. \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://joelhooks.com/react-context\"\n  }, \"React Context, custom React Hooks\"), \" are an excellent combination. xState is also an excellent tool for managing shared application state.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, \"Remote\"), \": This is state that the UI doesn't own. It is in The Cloud for all intents and purposes, even if have control over what that means in practical terms. It's async. There is a lot of flexibility at this layer of state and a lot of solutions. GraphQL is a very popular option that will affect the lower levels of state management as well. There are also \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://github.com/tannerlinsley/react-query\"\n  }, \"excellent React libraries like react-query\"), \" \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://twitter.com/tannerlinsley\"\n  }, \"Tanner Linsley\"), \" is somebody to follow if you're interested in these problems) that handle some of the hardest aspects of managing this layer of state such as cache invalidation and future proofing against React Suspense concurrent mode. It's complicated and absolutely where you need to spend the most time researching and communicating to come to a practical solution that suits the needs of your team.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, \"Meta\"), \": Is out of your control. You request changes and it might happen. \\\"Might\\\" is always tricky. It's pure and deserves our respect. It's not remote state, but it's intertwined with it very deeply and deserves the same consideration. Coordination, shared understanding, documentation, and communication are essential. \\\"The Business\\\"\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, \"Router\"), \": This is meta state and is likewise coupled to remote state as well. The Browser. React Router kindly deals with this for us. It's a hard problem and not for the feint of heart.\")), mdx(\"p\", null, \"State management is about coordination and communication and each layer of state relies on mutual agreement at both the code and often more importantly human to human level. Most applications start with local component state and layer on the rest as needed. Research, documentation, and experience will help guide decisions as complexity increases with the needs of the application.\"), mdx(\"p\", null, \"There are \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://en.wikipedia.org/wiki/No_Silver_Bullet\"\n  }, \"no silver bullets\"), \".\"));\n}\n;\nMDXContent.isMDXComponent = true;","frontmatter":{"title":"5 Layers of State Management in React Applications","date":"May 12, 2020","banner":null,"slug":"5-layers-react-state","keywords":null}}},"pageContext":{"id":"ae70c648-e65c-5716-88df-a2ce2020c140","prev":{"id":"a4f4f718-015f-5d17-ad00-e084adce153e","parent":{"name":"index","sourceInstanceName":"blog"},"excerpt":"PDFs on the iPad Pro using PDF Expert are extremely versatile to annotate and use for studying non-fiction texts such as books and academic papers. The  PDF Spec  has been open for years and you aren't forced to use Acrobat if you want to harness the…","fields":{"title":"Using PDF Expert to Highlight and Summarize Non-Fiction Books on the iPad Pro and Mac","slug":"pdf-expert","date":"2020-07-11T00:00:00.000Z"}},"next":{"id":"37e7ec27-1c51-5ec9-a64e-a74939e4e25b","parent":{"name":"index","sourceInstanceName":"blog"},"excerpt":"In a complicated web application there are going to be several pieces of truly global state that you'll need across your application. This is state that components need, but it's tedious and error prone to use prop drilling to pass state data around…","fields":{"title":"Using React Context and Custom React Hooks for State Management in React Apps","slug":"react-context","date":"2020-05-12T00:00:00.000Z"}}}},
    "staticQueryHashes": ["1045846374"]}