<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Angus Bower-Brown</title>
    <description>The latest articles on DEV Community by Angus Bower-Brown (@angus_bowerbrown_96449f1).</description>
    <link>https://dev.to/angus_bowerbrown_96449f1</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F863311%2F64f202c8-6295-4351-bea6-10223f34babe.png</url>
      <title>DEV Community: Angus Bower-Brown</title>
      <link>https://dev.to/angus_bowerbrown_96449f1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/angus_bowerbrown_96449f1"/>
    <language>en</language>
    <item>
      <title>Stacking Contexts and why you should go deep on what frustrates you (a personal journey)</title>
      <dc:creator>Angus Bower-Brown</dc:creator>
      <pubDate>Fri, 07 Jul 2023 17:40:40 +0000</pubDate>
      <link>https://dev.to/angus_bowerbrown_96449f1/stacking-contexts-and-why-you-should-go-deep-on-css-a-personal-journey-ccf</link>
      <guid>https://dev.to/angus_bowerbrown_96449f1/stacking-contexts-and-why-you-should-go-deep-on-css-a-personal-journey-ccf</guid>
      <description>&lt;p&gt;&lt;em&gt;I'm reaching the end of a software training and am reflecting on my progress. This blog is a little more focused on the abstracts of learning css and my own personal learning journey. For a more technical view of stacking contexts, this &lt;a href="https://www.joshwcomeau.com/css/stacking-contexts/" rel="noopener noreferrer"&gt;blog is great&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Josh Comeuax, the &lt;a href="https://www.joshwcomeau.com/tutorials/css/" rel="noopener noreferrer"&gt;CSS wizard&lt;/a&gt;, often starts his talks with a question:&lt;/p&gt;

&lt;h3&gt;
  
  
  Is CSS a hard language?
&lt;/h3&gt;

&lt;p&gt;It's intentionally provocative, because, in many ways CSS is relatively easy to understand. Non-programmers could look at a declaration like &lt;code&gt;bottom-border: 1px;&lt;/code&gt; or &lt;code&gt;float: right;&lt;/code&gt; and have a rough idea of what it's going to do. &lt;/p&gt;

&lt;p&gt;I'm willing to bet though, that a large number of web devs would answer 'yes' (or at least, 'it can be') to this question. So, why is that?&lt;/p&gt;

&lt;p&gt;In my experience, CSS is rarely taught by itself in web-development courses. By the time we hit a deeper language or framework, there's so much to learn when it comes to building web apps, that CSS is kind of left behind. We often end up relying on cobbled together methods we picked up in our &lt;em&gt;very first web projects&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I felt this really keenly with a messaging project I worked on this spring. It felt like what was holding me back as a developer was: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The way I was dealing with/thinking about asynchronous data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;My styling&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the former, I picked up a great tool that I'll blog about another time. &lt;/p&gt;

&lt;p&gt;For the latter, I thought I'd write a bit about my history with css; how learning more about it gave me the tools to solve problems that had bugged me for &lt;em&gt;a long time&lt;/em&gt;. Hopefully it can give you a clue where to look if you're dealing with a similar problem!&lt;/p&gt;




&lt;h3&gt;
  
  
  Why can CSS be hard to deal with?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1) No error messages
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CSS won't throw an error if it thinks your style is ugly (thankfully)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It simply applies the styles you've given it and we behold the results.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The only 'error' you can really trigger in CSS is a bad declaration (a spelling/syntax error, a non-sensical declaration one like &lt;code&gt;position: darkblue;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even then, in those situations, css simply doesn't apply that style (and maybe the following one) and moves on to the next valid one it can find which is not particularly useful in a debugging situation!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2) New keyword, new rules
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All we have to do is put down a declaration like &lt;code&gt;display: grid;&lt;/code&gt; or &lt;code&gt;position: fixed;&lt;/code&gt;, and we're suddenly in a completely new CSS world, with a new layout algorithms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This means we have a whole new set of keywords to handle our elements AND a whole other set of keywords can become totally useless. e.g using &lt;code&gt;float: right;&lt;/code&gt; on an element that's absolutely positioned.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If something's not working, it can be incredibly hard to figure out why. CSS's underlying rules can be pretty opaque, but taking the time to figure out what's going on under the hood can often give us a clue as to what the problem is. &lt;/p&gt;

&lt;p&gt;Let me give a personal example...&lt;/p&gt;

&lt;h2&gt;
  
  
  An annoying bug
&lt;/h2&gt;

&lt;p&gt;The first website I ever designed was for a project given to me by my software engineering course, about a year ago. I had to put together a personal website using HTML, CSS and very basic JavaScript.&lt;/p&gt;

&lt;p&gt;It looked like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F878qvop8nf2ro3kn0ymf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F878qvop8nf2ro3kn0ymf.png" alt="My first personal website" width="793" height="977"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking back, I'm quite happy with how it came out. To be  honest, it's a lot cleaner than a lot of websites that were to follow 😅&lt;/p&gt;




&lt;p&gt;There was one problem that really bugged me though... &lt;/p&gt;

&lt;p&gt;I'd followed some tutorials and made some nice hover effects for some links:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1tnd5azxflstyurymom.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1tnd5azxflstyurymom.gif" alt="Link animations triggering when hovered by mouse" width="366" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But some wouldn't trigger when hovered.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjslxla0e403j9r3zrb8w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjslxla0e403j9r3zrb8w.gif" alt="Link hover animations not triggering when hovered over by mouse" width="306" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's worse, they weren't even clickable.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;My styling wasn't just affecting my site's appearance, it was affecting its functionality&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;It's easy to think of styling and functionality as separate, but it's important to remember that styling is an essential part of how users interact with our sites, &lt;em&gt;both aesthetically and functionally.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This was an annoying problem and I put everything into trying to solve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;I managed to figure out &lt;em&gt;why&lt;/em&gt; the links weren't triggering, by looking at the browsers tools:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b7zvxgb4su7rympepa2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b7zvxgb4su7rympepa2.png" alt="Browser's tools showing the subordinate element's margin covering the non-hovering links" width="719" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The carousel below the biography section of my site (where the links weren't working) had a top margin that was covering the biography&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a user clicked or hovered over my links, &lt;em&gt;they weren't interacting with the links at all&lt;/em&gt;, but with the containing div of that carousel&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The solution?
&lt;/h2&gt;

&lt;p&gt;Folks, I'm willing to bet that all of you reading this will have experienced at least one debugging session that stretched into the ridiculous. This was my very first one.&lt;/p&gt;

&lt;p&gt;Despite knowing what the problem was, I had no idea how to solve it.&lt;/p&gt;

&lt;p&gt;Me and my instructor tried a variety of things:z-indexes, different display modes, different positioning modes- we couldn't get the links to animate or function. &lt;/p&gt;

&lt;p&gt;Gradually, new requirements and projects arose and I (reluctantly) moved on with my life, but the amount of time I spent on this issue and the fact that I wasn't able to solve it really gnawed at me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F232ahlsnqe6mcj6o99bk.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F232ahlsnqe6mcj6o99bk.jpeg" alt="Meme of someone estranged at a lively party, caption: " width="500" height="501"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;What bugged me distinctly was how my z-indexes just didn't work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I cranked them up to ridiculously high and low numbers respectively&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I knew that z-indexes are aspects of the positioned layout mode, so I made sure my elements were all positioned in some way&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;None of this seemed to matter or make any change to my rendering problem&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It wasn't until I decided to take a deeper dive into CSS, with some courses and personal research, before I understood what was happening. It was pretty satisfying (if petty) to go back and solve the problem a year later 😂&lt;/p&gt;

&lt;p&gt;So what was going on? What aspect of CSS was I missing?&lt;/p&gt;
&lt;h2&gt;
  
  
  A Puzzle
&lt;/h2&gt;

&lt;p&gt;Below's a representation of the code of the two elements involved here.&lt;/p&gt;

&lt;p&gt;Ask yourself, would the div with a class of "red", or the div with a class of "blue" render on top in the DOM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.blue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.red&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you guessed blue would appear on top, you guessed right! But why? It's z-index is lower than red? What's going on here?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjdfxlzd6kjhz9n50r3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjdfxlzd6kjhz9n50r3s.png" alt="A DOM where the blue square is on top of the red" width="452" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stacking Contexts
&lt;/h2&gt;

&lt;p&gt;The big piece of information that I think most beginners are missing when it comes to understanding z index is this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;z-index values aren't global&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Our browser doesn't look through the style sheet and render all the elements with a z-index of 1 at one layer of the DOM and all the elements with a z-index of 2 at another.&lt;/p&gt;

&lt;p&gt;Instead, they render elements based on their z-index AND the &lt;strong&gt;stacking context&lt;/strong&gt; that contains them.&lt;/p&gt;

&lt;p&gt;A 'stacking context' is a little similar to the idea of a functional scope.&lt;/p&gt;

&lt;p&gt;Just as when we create a new function, we create a new scope, when we make give an element a positioned layout and a z-index, we create a new stacking context.&lt;/p&gt;

&lt;p&gt;Is that the only way to create a stacking context? &lt;strong&gt;Absolutely not.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating a stacking context
&lt;/h4&gt;

&lt;p&gt;There are a &lt;a href="_https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context_"&gt;variety of ways&lt;/a&gt; we can create a stacking context. &lt;/p&gt;

&lt;p&gt;They include changing an element's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;opacity&lt;/li&gt;
&lt;li&gt;mix-blend-mode&lt;/li&gt;
&lt;li&gt;z-index (not just in positioned layout, but in the flex and grid display modes too)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's entirely possible to create a stacking context by accident! But what exactly happens when we do?&lt;/p&gt;

&lt;h4&gt;
  
  
  Using stacking contexts
&lt;/h4&gt;

&lt;p&gt;When we create a stacking context (most commonly when we combine a z-index with a positioned layout), we create an insular world of z-indexes. &lt;/p&gt;

&lt;p&gt;Z-indexes defined within that stacking context will &lt;strong&gt;only&lt;/strong&gt; be compared to z-indexes also within that stacking context.&lt;/p&gt;

&lt;p&gt;So, in our example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.blue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.red&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The red element's z-index of 2 is only compared with the container element's z-index of 3. The blue element is &lt;em&gt;isolated&lt;/em&gt; within the stacking context created by the container element.&lt;/p&gt;

&lt;p&gt;As it's z-index is larger, the container element (and therefore the blue element) will be rendered on top of the the red:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjdfxlzd6kjhz9n50r3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjdfxlzd6kjhz9n50r3s.png" alt="A DOM where the blue square is on top of the red" width="452" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The blue div's z-index is &lt;em&gt;totally irrelevant&lt;/em&gt; when it comes to discussing the order of the red and container elements-  will only get compared to elements within the same stacking context.&lt;/p&gt;

&lt;p&gt;Say we wanted it to render behind the red box, we could try and give it a crazy negative z-index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.blue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-9999&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.red&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It would render in exactly the same way:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdswtqpsr96hz8tfychf0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdswtqpsr96hz8tfychf0.png" alt="The same render order of blue on top of red" width="452" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(I don't know about you, but that crazy high z-index number looks painfully familiar!)&lt;/p&gt;

&lt;p&gt;The only thing our red div's z-index is being compared to is &lt;em&gt;other z-index's of elements in that stacking context&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The only way we can get the blue to render on top of the red is by changing the z-index in that top-level stacking context, ie. of the container div:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.blue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.red&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the situations have reversed. Despite the lower z-index, our red div is now on top:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwqdn6efbtfklbap0njl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwqdn6efbtfklbap0njl.png" alt="red element on top of blue" width="452" height="285"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;So, that's a brief summary of stacking contexts. Is there a takeaway here? &lt;/p&gt;

&lt;p&gt;For me, it's this:&lt;/p&gt;

&lt;h3&gt;
  
  
  Be honest about what frustrates you and explore it
&lt;/h3&gt;

&lt;p&gt;The point of this blog wasn't really to explore stacking contexts in any great depth but to emphasise that if we're regularly frustrated by the same problem in our projects, it can be really rewarding to prioritise those things in our learning journey.&lt;/p&gt;

&lt;p&gt;Being frustrated about how clumsy my styling felt in my personal projects led me to explore the mechanics of CSS a bit further. That lead me to a mental model that let me comment a single line of code:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4z8n3pd0esi7t7f9xzy3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4z8n3pd0esi7t7f9xzy3.png" alt="An uncommented position: absolute declaration" width="178" height="51"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And solve a problem that had been bugging me for a year!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5c6qqx737xs9s96hqqg6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5c6qqx737xs9s96hqqg6.gif" alt="the link animations animating on hover" width="270" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe being petty is a good learning process? 🤔&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Single Responsibility for Beginners (2/2)</title>
      <dc:creator>Angus Bower-Brown</dc:creator>
      <pubDate>Mon, 23 Jan 2023 16:24:52 +0000</pubDate>
      <link>https://dev.to/angus_bowerbrown_96449f1/single-responsibility-for-beginners-22-3836</link>
      <guid>https://dev.to/angus_bowerbrown_96449f1/single-responsibility-for-beginners-22-3836</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/angus_bowerbrown_96449f1/single-responsibility-principle-for-beginners-12-1e1f"&gt;our last blog&lt;/a&gt;, we explored some beginner 'hows' of the Single Responsibility Principle (how to build classes that follow it, how to check that they are following it at any time). This blog is focused on &lt;em&gt;why&lt;/em&gt; we follow the SRP and what it brings to the table for us as developers.&lt;/p&gt;

&lt;p&gt;Blindly following principles of design can be helpful when we're starting out, but they stand to benefit us (or at least me!) most when we understand exactly what kind of headaches they're trying to avoid!&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the point of SRP?
&lt;/h2&gt;

&lt;p&gt;Sandi Metz said that designing classes with a Single Responsibility encourages us to &lt;em&gt;"code for the future"&lt;/em&gt; 🔮 ✨ 🤔 We'll exploring what she might mean by that throughout this blog but, in general, classes with a single responsibility are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More reusable&lt;/li&gt;
&lt;li&gt;More responsive to change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's pretty much it! That may not seem like much but, unless we can visualise every aspect of our program from very start of our process, these qualities reveal themselves to be incredibly useful over time 😍&lt;/p&gt;

&lt;p&gt;Let's show this in action with some examples from last time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Back to the Bookshop
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/angus_bowerbrown_96449f1/single-responsibility-principle-for-beginners-12-1e1f"&gt;To refresh&lt;/a&gt;, as a Bookshop owner, we wanted a program that could keep track of all the books on a particular shelf.&lt;/p&gt;

&lt;p&gt;So, we needed a program that could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Represent individual books as data objects&lt;/li&gt;
&lt;li&gt;Represent a bookshelf in some way that can store and remove those objects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We crafted both a program that achieved those goals with separate classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bookshelf&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:books&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;remove_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and a counter-example of a big &lt;code&gt;Book&lt;/code&gt; class that handled everything 🤹‍♀️:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;

  &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;
    &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both of these examples demonstrate the behaviour we need, but what happens when we need to add a new feature? &lt;/p&gt;

&lt;h2&gt;
  
  
  A New Feature: A Catalogue
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;As the bookshop owner, we've now decided to digitise our entire stock of books. As well as keeping track of our bookshelf, we want to represent every book in store as data in some way and have it accessible.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This new idea of a "catalogue" could be useful for a whole bunch of reasons (searching and sorting our stock, keeping track of what new books need to be ordered etc) and our program will now need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Represent individual books as data objects&lt;/li&gt;
&lt;li&gt;Represent a bookshelf in some way that can store and remove those objects&lt;/li&gt;
&lt;li&gt;Represent a catalogue of all books in a way that can also store and remove those objects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both of our earlier examples take care of two of these concerns, so we'll just have to adapt them to address the third one.&lt;/p&gt;

&lt;p&gt;Let's start by looking at the second extract- the &lt;code&gt;Book&lt;/code&gt; class that handles everything 🤹‍♀️- and see how it accommodates this new idea.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Class Divided
&lt;/h3&gt;

&lt;p&gt;Our new &lt;code&gt;Catalogue&lt;/code&gt; class will need to store data objects that represent books. At the moment, our &lt;code&gt;Book&lt;/code&gt; class is responsible for generating those objects.&lt;/p&gt;

&lt;p&gt;We'll need to make them work together!&lt;/p&gt;

&lt;p&gt;If we look at our &lt;code&gt;Book&lt;/code&gt; class's &lt;code&gt;#initialize&lt;/code&gt; method though, there's a snag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;
    &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the moment, whenever a new book object is created, it's automatically pushed to the &lt;code&gt;@@bookshop&lt;/code&gt; class variable.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;Book&lt;/code&gt; class's responsibility of representing books as data objects is currently &lt;em&gt;entangled&lt;/em&gt; with its responsibility of adding to the bookshelf 🪢&lt;/p&gt;

&lt;p&gt;This won't do. Our coming &lt;code&gt;Catalogue&lt;/code&gt; will have every book in the store; there need be some books in our &lt;code&gt;Catalogue&lt;/code&gt; that aren't on our &lt;code&gt;@@bookshelf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With that in mind, let's "detangle" these methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright! We can now create new book objects without having to add them to our &lt;code&gt;@@bookshelf&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;That being said, with our &lt;code&gt;@@bookshelf&lt;/code&gt; and our coming "catalogue", we now have two places where we can "add" books.&lt;/p&gt;

&lt;p&gt;It might be better to clarify exactly what data object our &lt;code&gt;Book&lt;/code&gt; class's &lt;code&gt;.add_book&lt;/code&gt; and &lt;code&gt;.remove_book&lt;/code&gt; methods are acting on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;

  &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_book_to_bookshelf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove_book_from_bookshelf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this in place our final program might look something like this 🫣:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;

  &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_book_to_bookshelf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove_book_from_bookshelf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Catalogue&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:books&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;remove_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok! That's one way of doing things!&lt;/p&gt;

&lt;h3&gt;
  
  
  Another Way
&lt;/h3&gt;

&lt;p&gt;Let's see how we would go about achieving the same thing with our first example, where the classes had separated responsibilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bookshelf&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:books&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;remove_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Catalogue&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:books&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;remove_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice about the above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We haven't had to change our &lt;code&gt;Book&lt;/code&gt; class at all for it to be adapted to our new needs&lt;/li&gt;
&lt;li&gt;We actually haven't had to modify any of our code, (only add new stuff) to create our &lt;code&gt;Catalogue&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Programmers often call classes that follow the SRP "&lt;a href="https://en.wikipedia.org/wiki/Cohesion_(computer_science)#High_cohesion" rel="noopener noreferrer"&gt;cohesive&lt;/a&gt;" or say that they have "high cohesion". What they mean by this is that classes that are focused on just one thing work better with other classes.&lt;/p&gt;

&lt;p&gt;We didn't design our &lt;code&gt;Book&lt;/code&gt; class with the &lt;code&gt;Catalogue&lt;/code&gt; class in mind. However, because it's only responsible for one behaviour (representing books as data) and because that behaviour is useful in many situations, it's more than happy to do it in a new context&lt;/p&gt;

&lt;p&gt;This partly what we mean by saying coding classes in line with the SRP is 'coding for the future'. The more "cohesive" our classes are, the easier they are to use in ways we didn't even expect! &lt;/p&gt;

&lt;p&gt;Cohesive classes can act acting as building blocks for our new ideas, instead of obstacles!&lt;/p&gt;

&lt;h2&gt;
  
  
  OOD Mindset
&lt;/h2&gt;

&lt;p&gt;Look again at our two finished examples and consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In which is it clearer what each part of the program does?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If we were to add a new feature to this program (a way of making sure each object goes to the right place, maybe a sorting method to alphabetise a collection of books), in which do you feel more sure of where you might start?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In many ways, what we're doing right now- considering how refactoring our code can help our own development process- is what's ultimately important about the SRP.&lt;/p&gt;

&lt;p&gt;The SRP isn't essential for code to work (our counter examples were perfectly functional); we don't get any prizes for having 100% SRP purity in our code 😢 We also don't &lt;em&gt;always&lt;/em&gt; have to follow the SRP; we shouldn't feel pressure to completely redesign our app if we have just one dodgy method with no clear home!&lt;/p&gt;

&lt;p&gt;What it &lt;em&gt;does&lt;/em&gt; offer us is a guiding principle to help us with our moment-to-moment decision making process as developers. It helps us write code that's readable and changeable, for ourselves and our collaborators.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SRP makes our classes more reusable and responsive to change&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Classes with a single responsibility are often referred to as being "cohesive" or having "high cohesion"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Classes with high cohesion work better with other classes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This makes classes that follow the SRP useful to us down the development pipeline in ways that we can't even anticipate&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  More OOD Posts?
&lt;/h4&gt;

&lt;p&gt;Thanks for reading this little 2 parter! &lt;/p&gt;

&lt;p&gt;By now, as beginners, we hopefully have an idea of &lt;a href="https://dev.to/angus_bowerbrown_96449f1/single-responsibility-principle-for-beginners-12-1e1f"&gt;how to enact the SRP in our programs&lt;/a&gt; and what doing so offers us as developers 🎉&lt;/p&gt;

&lt;p&gt;These have been really informative and fun to put together; I might explore the other SOLID principles in future posts. Let me know if that's something you would like!&lt;/p&gt;

</description>
      <category>langchain</category>
      <category>learning</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Single Responsibility Principle for beginners (1/2)</title>
      <dc:creator>Angus Bower-Brown</dc:creator>
      <pubDate>Mon, 09 Jan 2023 13:59:37 +0000</pubDate>
      <link>https://dev.to/angus_bowerbrown_96449f1/single-responsibility-principle-for-beginners-12-1e1f</link>
      <guid>https://dev.to/angus_bowerbrown_96449f1/single-responsibility-principle-for-beginners-12-1e1f</guid>
      <description>&lt;p&gt;When learning Ruby it's almost impossible not to come into contact with the concepts of object-oriented programming (hereafter OOP!).&lt;/p&gt;

&lt;p&gt;The maxim that 'everything in Ruby is an object' 🤔 shows just how integral object-oriented design is to the language. For me, it's been a great experience to learn about one as I learn about the other.&lt;/p&gt;

&lt;p&gt;I thought a some blogs exploring key tenets of OOP, would help improve me as a Ruby programmer and I hope it's of use to beginners out there or for people looking refresh themselves on the fundamentals of OOP theory 🤓&lt;/p&gt;

&lt;p&gt;This blog will explore SRP, how to check if our classes are following it and to think about create classes that are more likely to do so from the get-go!&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the Single Responsibility Principle (SRP)?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The SRP is one of the &lt;a href="https://en.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID principles&lt;/a&gt; of Object-Oriented Design &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's a guiding convention that a class should only have one responsibility or job&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is often extrapolated to 'a class should have only one reason to change'&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What does this mean in practice? Let's explore the idea with an example...&lt;/p&gt;

&lt;h3&gt;
  
  
  Example- A new bookshelf&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;We're the owner of a bookshop and would like to put up a new shelf. We want to design an app that will keep track of the books that go on that shelf.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To make an app that follows the SRP, we'll start by thinking carefully about what classes to create in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing which Classes to Create
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A great way to start thinking about what classes need creating is to look at the nouns in our brief&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When considering each noun, ask if it could represent &lt;em&gt;data&lt;/em&gt; or &lt;em&gt;behaviour&lt;/em&gt; that would help you in your app's goal&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For instance, we might think that a &lt;code&gt;Bookshop&lt;/code&gt; class would be a good thing to make, but it's unclear how making one would help us in our goal of keeping track of books that go on a particular shelf (if there were many shelves to keep track of, we could return to this idea)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In our example, if we think about the &lt;em&gt;data&lt;/em&gt; and &lt;em&gt;behaviour&lt;/em&gt; we need, we'll probably need a &lt;code&gt;Book&lt;/code&gt; and &lt;code&gt;Bookshelf&lt;/code&gt; class&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can use a &lt;code&gt;Book&lt;/code&gt; class to represent the books we add to the shelf as objects. It will need to be able to create objects that represent our books, that bundle &lt;em&gt;data&lt;/em&gt; specific to each book&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can use a &lt;code&gt;Bookshelf&lt;/code&gt; class to keep track of the books currently on that shelf. It will need to have the &lt;em&gt;behaviour&lt;/em&gt; of saving our book objects to a variable within itself and adding or removing books from that variable&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We've decided what nouns we want to represent as classes and what behaviour and data each class is responsible for. &lt;/p&gt;

&lt;p&gt;Our code could end up looking something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bookshelf&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:books&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;remove_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far, so good. This code looks sensible enough, but does it follow the Single Responsibility Principle?&lt;/p&gt;

&lt;p&gt;How can we be sure either way?&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking if a Class has a Single Responsibility
&lt;/h2&gt;

&lt;p&gt;Not all examples are as simple as the one we're dealing with. It can be necessary for a class to have multiple methods to manage its responsibility and, as a project's complexity grows, it's important to have a way of deciding whether a object's method falls within it's "responsibility". &lt;/p&gt;

&lt;p&gt;For me, the best way that I found to check this, I got from &lt;a href="https://www.amazon.co.uk/Practical-Object-Oriented-Design-Ruby-Addison-Wesley/dp/0321721330" rel="noopener noreferrer"&gt;Sandi Metz's 'Practical Object Oriented Design'&lt;/a&gt; (a book I can't recommend enough, if you find this topic interesting!).&lt;/p&gt;

&lt;p&gt;The technique goes like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Personify the class in your mind&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rephrase the method as a question&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ask yourself if it makes sense to ask &lt;em&gt;this&lt;/em&gt; class &lt;em&gt;this&lt;/em&gt; question&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our example, our &lt;code&gt;Book&lt;/code&gt; class is initialised with an 'author' method and a 'title' method.&lt;/p&gt;

&lt;p&gt;We could rephrase these methods as &lt;em&gt;"Hi Book, what's your title?"&lt;/em&gt; or &lt;em&gt;"Hi Book, who's your author?"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3c6avycu6hfzlqgax584.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3c6avycu6hfzlqgax584.jpeg" alt="A cartoon book, smiling with a thumbs up" width="225" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, we can put the &lt;code&gt;Bookshelf&lt;/code&gt; class's methods as something like &lt;em&gt;"Hey Bookshelf, what books are on you right now? Can I add this one? Can I take this one?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmjte4ump2epq0farvdqz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmjte4ump2epq0farvdqz.png" alt="A cartoon bookshelf" width="159" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All of these questions seem perfectly valid to ask our personified classes. We can feel safe then, that each of these methods fall within its class's 'responsibility'.&lt;/p&gt;

&lt;h4&gt;
  
  
  A Counter-example
&lt;/h4&gt;

&lt;p&gt;That being said, &lt;a href="https://www.newscientist.com/article/mg25333770-400-make-mistakes-on-purpose-it-can-dramatically-boost-your-performance/" rel="noopener noreferrer"&gt;a good way to learn to do something right is to do something wrong on purpose.&lt;/a&gt; With that in mind, let's create a &lt;code&gt;Book&lt;/code&gt; class that's responsible for everything and see if it passes our test!&lt;/p&gt;

&lt;p&gt;Such a class might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;

  &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;
    &lt;span class="vc"&gt;@@bookshelf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we were to rephrase the &lt;code&gt;.bookshelf&lt;/code&gt; method as a question, it might sound like "&lt;em&gt;Book, what instances of you have been added to the shelf so far?&lt;/em&gt;". The &lt;code&gt;.remove_book&lt;/code&gt; method might be put something like &lt;em&gt;"Book, can you remove an instance of yourself from the shelf?".&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzf9afl21zmlhg5rfhgt.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzf9afl21zmlhg5rfhgt.jpeg" alt="A cartoon book, looking confused" width="320" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are pretty strange, abstract questions to be asking a book (personified or otherwise)... We can intuitively feel that this isn't something that a 'book' should be doing and that's a hint to us that this class has too many responsibilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summing up
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Choosing initial classes that are likely to follow the SRP
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When deciding on which classes to start with, think about the "objects" (often nouns) in an application's main goal or brief&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ask yourself, which of these objects can represent &lt;em&gt;data&lt;/em&gt; or &lt;em&gt;behaviour&lt;/em&gt; that will help achieve your app's goal?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The objects that occur to you are a good candidates for becoming classes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Checking if a class's method falls under its responsibility
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Personify the class and rephrase the method as a question&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the question seems fair to ask this particular class, it likely falls under its responsibility&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;As a beginner, it may seem strange to read phrases like 'occur to you', 'seems' and 'likely' when reading about something as seemingly technical as programming. There's nothing particularly concrete about whether a question 'feels right' to ask a class. &lt;/p&gt;

&lt;p&gt;However, as I've been reflecting lately, a huge part of developing as a programmer though, is developing your decision making process. &lt;a href="https://twitter.com/potetotes/status/1348044775887233024" rel="noopener noreferrer"&gt;The old joke goes&lt;/a&gt;: the key to being a senior developer are the words "it depends".&lt;/p&gt;

&lt;h3&gt;
  
  
  Next Time
&lt;/h3&gt;

&lt;p&gt;This blog has focused on the practicals of SRP: how to design classes that are likely to follow it from the ground up and how to check whether a class is doing too much.&lt;/p&gt;

&lt;p&gt;But why is Single Responsibility Principle important to our coding decisions? What does it offer our code, or make available to us down the development pipeline? Do our classes &lt;em&gt;always&lt;/em&gt; need to have one and only one responsibility? &lt;/p&gt;

&lt;p&gt;These are the questions will be explored in my next blog, I hope you enjoyed this one and keep your eyes peeled til then!&lt;/p&gt;

</description>
      <category>learning</category>
    </item>
    <item>
      <title>A Matter of Flexibility- Passing Data Between React Components</title>
      <dc:creator>Angus Bower-Brown</dc:creator>
      <pubDate>Wed, 12 Oct 2022 15:39:10 +0000</pubDate>
      <link>https://dev.to/angus_bowerbrown_96449f1/a-matter-of-flexibility-passing-data-between-react-components-2e38</link>
      <guid>https://dev.to/angus_bowerbrown_96449f1/a-matter-of-flexibility-passing-data-between-react-components-2e38</guid>
      <description>&lt;p&gt;&lt;em&gt;I like starting these posts with a bit of introspection about my current learning processes. The technical content of the blog starts here&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In previous blogs, I’ve talked about what a great tool blogging is to learn about a process or aspect of programming that I’m struggling to to get a hold of. I’ve found the act of breaking things down and writing them out step by step to be a great to approach a learning problem I’m experiencing at the time.&lt;/p&gt;

&lt;p&gt;For this blog though, I’ve decided not to look at something I’m struggling with, but to look at alternatives to a pretty basic aspect of React programming that I do every time I program in it: transferring data between components.&lt;/p&gt;

&lt;p&gt;When programming, I often reach out for the easiest and first way I can think of to solve a problem.  There’s nothing wrong with that in itself- when you’re just starting  out, the most important thing is writing code that &lt;em&gt;works&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In my experience though, there are often multiple ways of solving something. A great use I can see for these blogs is, not just breaking down something I’m struggling with, but exploring alternatives to something that I think I know well, otherwise, it’s hard to ever know I’m using the right tool for the job or just falling back on habits to achieve the task as best they can!&lt;/p&gt;

&lt;p&gt;As I said, in this blog, I’ll be looking at a few different ways to pass data to deeply nested components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Props &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Props are such a fundamental part of React programming, it might seem redundant to cover them in any detail. However, when we're later looking at different ways of passing data to nested components, I think it will have been  useful to remember the benefits of using props and why they're such a powerful feature of React.&lt;/p&gt;

&lt;p&gt;If we look at this basic example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MainComponent(){
    return(
        &amp;lt;FirstNestedComponent/&amp;gt;
    )
}

function FirstNestedComponent(){
    return(
        &amp;lt;SecondNestedComponent/&amp;gt;
    )
}

function SecondNestedComponent(){
    let greeting = "Hello World"
    return (
        &amp;lt;h1&amp;gt;{greeting}&amp;lt;/h1&amp;gt;
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example's component hierarchy could be represented something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1m97u4o3ymk8exudjsj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1m97u4o3ymk8exudjsj.jpeg" alt="Graphical depiction of a main component and two nested ones"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it would render something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajq0ombql082dlmpr0rd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajq0ombql082dlmpr0rd.png" alt="A webpage with an h1 header with the text "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is an example of using components without props. By defining the &lt;code&gt;greeting&lt;/code&gt; variable within the &lt;code&gt;SecondNestedComponent&lt;/code&gt;, the component has lost all flexibility. The &lt;code&gt;SecondNestedComponent&lt;/code&gt; can say "Hello World" and nothing else.&lt;/p&gt;

&lt;p&gt;Using that component again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function FirstNestedComponent() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;SecondNestedComponent/&amp;gt;
      &amp;lt;SecondNestedComponent/&amp;gt;
    &amp;lt;/&amp;gt;
  )
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Would just render the same content twice:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1sfpt1o83m74384rl5n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1sfpt1o83m74384rl5n.png" alt="Two h1 elements with a "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we instead pass the value for greeting to the SecondNested Components via props:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function FirstNestedComponent() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;SecondNestedComponent greeting = "Hello World"/&amp;gt;
      &amp;lt;SecondNestedComponent greeting = "Howdy!"/&amp;gt;
    &amp;lt;/&amp;gt;
  )
};

function SecondNestedComponent(props){
    return (
        &amp;lt;h1&amp;gt;{props.greeting}&amp;lt;/h1&amp;gt;
    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The component can now flexibly render different content, depending on the value that it's been passed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrwk0tpu6f50grhyyeos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrwk0tpu6f50grhyyeos.png" alt="A webpage with two h1 elements with text content of "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This basic example illustrates some of the power of component-based programming.&lt;/p&gt;

&lt;p&gt;As put in the React Documents: &lt;a href="https://reactjs.org/docs/components-and-props.html" rel="noopener noreferrer"&gt;Components let you split the UI into independent, reusable pieces, and think about each piece in isolation.&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Passing components data via props, rather than having them hold their own data, increases these qualities of &lt;em&gt;independence&lt;/em&gt; and &lt;em&gt;reusability&lt;/em&gt; making the components more flexible and 'composable' to the programmer. &lt;/p&gt;

&lt;p&gt;That being said, as React projects become more complex, passing information to components via props can become increasingly cumbersome and intricate. &lt;/p&gt;

&lt;h2&gt;
  
  
  The difficulties of props with deeply nested components
&lt;/h2&gt;

&lt;p&gt;If our React App was working with state and had a few more nested components, it might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MainComponent(){

    const [greeting, setGreeting] = useState("Hello world")

    return(
        &amp;lt;FirstNestedComponent greeting = {greeting}/&amp;gt;
    )
}

function FirstNestedComponent(props){
    return(
        &amp;lt;SecondNestedComponent greeting= {props.greeting}/&amp;gt;
    )
}
function SecondNestedComponent(props){
    return (
        &amp;lt;ThirdNestedComponent greeting = {props.greeting}/&amp;gt;
    )
}

function ThirdNestedComponent(props){
    return (
        &amp;lt;FourthNestedComponent greeting = {props.greeting}/&amp;gt;
    )
}

function FourthNestedComponent(props){
    return (
        &amp;lt;h1&amp;gt;{props.greeting}&amp;lt;/h1&amp;gt;
    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr513qb55y7unshs9xues.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr513qb55y7unshs9xues.jpeg" alt="Graphical depiction of the hierarchy of a main component and four nested ones"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As state is often defined in the top level component (to give it its fullest possible range across an app), to get the required value of &lt;code&gt;greeting&lt;/code&gt; to our &lt;code&gt;FourthNestedComponent&lt;/code&gt;, we need to pass it as props &lt;em&gt;four times&lt;/em&gt; through our component hierarchy, just so &lt;em&gt;one&lt;/em&gt; component can use it.&lt;/p&gt;

&lt;p&gt;With code as basic as our example, this may not seem like a big problem-  but the inefficiency of needing multiple lines of code in multiple components, just for a "Hello World" in our last one, will only get worse and worse as our apps grow in size and complexity.&lt;/p&gt;

&lt;p&gt;The act of passing props through multiple components that do not use the values being passed is what's referred to as 'prop-drilling' in the React community and it's the main problem that comes out of using props to pass information.&lt;/p&gt;

&lt;p&gt;Up till now, props are the main method of passing data that I've been using- prop drilling is just something I've put up with to get my code to work (I'm sure I'm not alone among beginners!).&lt;/p&gt;

&lt;p&gt;As said before though, just because something works doesn't mean it's the best way to do something, so let's look at well-known alternatives and consider their costs and benefits.&lt;/p&gt;

&lt;p&gt;One would be to use the useContext hook.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;The useContext hook allows us to store the data we need in a separate Context object. Then, after wrapping our components in a special "Provider component", we can access that data in our components when we need to, without having to pass it to them as props (and so avoiding the need of 'prop drilling').&lt;/p&gt;

&lt;p&gt;Let's see how this works in practice.&lt;/p&gt;

&lt;p&gt;In a new, 'context' file we can create our context object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/context/greeting.js

import React from 'react';

const GreetingContext = React.createContext();


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll make our provider component. Note that this component receives a 'value' prop which can take the data we want to be passed to our nested component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/context/greeting.js

import React from 'react';

// our context object
const GreetingContext = React.createContext();

// our provider component

function GreetingProvider({ children }) {

  const greeting = "Hello world"

  return &amp;lt;GreetingContext.Provider value={greeting}&amp;gt;{children}&amp;lt;/GreetingContext.Provider&amp;gt;
}

export {GreetingContext, GreetingProvider}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now wrap our components with our provider component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {GreetingProvider} from 'src/context/greeting'

function MainComponent(){

    return(
        &amp;lt;GreetingProvider&amp;gt;
            &amp;lt;FirstNestedComponent/&amp;gt;
        &amp;lt;/GreetingProvider&amp;gt;
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the components wrapped in &lt;code&gt;GreetingProvider&lt;/code&gt; now have access to the &lt;code&gt;GreetingContext&lt;/code&gt; object. They can access this object by calling on the &lt;code&gt;useContext&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;Let's demonstrate this in our most nested component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { GreetingProvider, GreetingContext } from "src/context/greeting";

function MainComponent(){

    return(
        &amp;lt;GreetingProvider&amp;gt;
            &amp;lt;FirstNestedComponent/&amp;gt;
        &amp;lt;/GreetingProvider&amp;gt;
    )
}

function FirstNestedComponent(){
    return(
        &amp;lt;SecondNestedComponent /&amp;gt;
    )
}

function SecondNestedComponent(){
    return (
        &amp;lt;ThirdNestedComponent/&amp;gt;
    )
}

function ThirdNestedComponent(){
    return (
        &amp;lt;FourthNestedComponent/&amp;gt;
    )
}

function FourthNestedComponent(){

    const greeting = useContext(GreetingContext);
    return (
        &amp;lt;h1&amp;gt;{greeting}&amp;lt;/h1&amp;gt;
    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we look at webpage that's rendered, we can see that our &lt;code&gt;FourthNestedComponent&lt;/code&gt; is getting our desired value for the its &lt;code&gt;greeting&lt;/code&gt; variable:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxipy4dtilsxrd9pznab0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxipy4dtilsxrd9pznab0.png" alt="A correctly rendered h1 element with "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our deeply nested component has gotten the value we want and we haven't had to drill our props. &lt;/p&gt;

&lt;p&gt;This seems to have solved our problem, but are there any issues with passing information to our components this way?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Issues of Using Context
&lt;/h2&gt;

&lt;p&gt;Michael Jackson, the creator of React Router said that the problem of using context to pass data to nested component is that it acts essentially as 'an implicit prop'.&lt;/p&gt;

&lt;p&gt;As he puts it: &lt;a href="https://www.youtube.com/watch?v=3XaXKiXtNjw&amp;amp;t=550s" rel="noopener noreferrer"&gt;'It is implied, when we render [a component using context] that we are in this state and if we are not, then we have to handle it somehow'.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most obvious problem of the 'implicit state' context gives to components is trying to use them outside of the provider component.&lt;/p&gt;

&lt;p&gt;If were to do so in our example app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MainComponent(){

    return(
        &amp;lt;&amp;gt;
            &amp;lt;GreetingProvider&amp;gt;
                &amp;lt;FirstNestedComponent/&amp;gt;
            &amp;lt;/GreetingProvider&amp;gt;
            &amp;lt;FourthNestedComponent/&amp;gt;
        &amp;lt;/&amp;gt;
    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We get an error:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1dqmokugnmz1f4n4cv2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1dqmokugnmz1f4n4cv2o.png" alt="Error message describing a failure to destructure an absent context object"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another issue of components having these 'implied props' is, as put by the React docs, &lt;a href="https://reactjs.org/docs/context.html#before-you-use-context" rel="noopener noreferrer"&gt;"it makes component reuse more difficult".&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I were to render two of our component that draws it's values from our context object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function ThirdNestedComponent(){
    return (
        &amp;lt;&amp;gt;
            &amp;lt;FourthNestedComponent/&amp;gt;
            &amp;lt;FourthNestedComponent/&amp;gt;
        &amp;lt;/&amp;gt;
    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It would render the same content twice:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo84fbwc5grg5ourb27vi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo84fbwc5grg5ourb27vi.png" alt="Two components with the content of "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I wanted a different string to be rendered as my &lt;code&gt;greeting&lt;/code&gt; variable, I could change the context object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/context/greeting.js

import React from 'react';

// our context object
const GreetingContext = React.createContext();

// our provider component

function GreetingProvider({ children }) {

  const greeting = "Howdy"

  return &amp;lt;GreetingContext.Provider value={greeting}&amp;gt;{children}&amp;lt;/GreetingContext.Provider&amp;gt;
}

export {GreetingContext, GreetingProvider}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, as both the &lt;code&gt;FourthNestedComponents&lt;/code&gt; draw their value from this object, obviously, both of them will render the change:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxh94uqcmktf2n3kkome.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxh94uqcmktf2n3kkome.png" alt="Two h1 elements saying "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our components have lost their flexibility.&lt;/strong&gt; Using context, I can't have one &lt;code&gt;FourthNestedComponent&lt;/code&gt; take one &lt;code&gt;greeting&lt;/code&gt; variable and the other take another, which was such a powerful feature of using props in our most basic example. &lt;/p&gt;

&lt;p&gt;I could use things like default values or conditional rendering to address these issues but we turned to this method originally to clean up our code and reduce its complexity.&lt;/p&gt;

&lt;p&gt;By using context instead of props, we've spared ourselves from prop-drilling, but we've affected our components independence, reusability and we exchanged one kind of complexity for another.&lt;/p&gt;

&lt;p&gt;Luckily, there's also a third way of passing information to our nested components, which achieved by using a prop of React that Michael Jackson calls &lt;a href="https://www.youtube.com/watch?v=3XaXKiXtNjw&amp;amp;t=652s" rel="noopener noreferrer"&gt;'highly highly underappreciated and underused'&lt;/a&gt;: the children prop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Composition
&lt;/h2&gt;

&lt;p&gt;Composition allows us pass the content of our components directly to them as props, mainly by using the 'children' prop. We can see how this works with our earlier, more simple example with just two nested components.&lt;/p&gt;

&lt;p&gt;Component composition allows us to "compose" the content of our components when we first write them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MainComponent(){
    return(
        &amp;lt;FirstNestedComponent&amp;gt;
            &amp;lt;SecondNestedComponent greeting = {"Hello World"}/&amp;gt;
        &amp;lt;/FirstNestedComponent&amp;gt;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then pass that content to the nested components via the &lt;code&gt;children&lt;/code&gt; prop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
function FirstNestedComponent({children}){
    return(
        &amp;lt;&amp;gt;
            {children}
        &amp;lt;/&amp;gt;
    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the whole of our code in place:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MainComponent(){
    return(
        &amp;lt;FirstNestedComponent&amp;gt;
            &amp;lt;SecondNestedComponent greeting = {"Hello World"}/&amp;gt;
        &amp;lt;/FirstNestedComponent&amp;gt;
}

function FirstNestedComponent({children}){
    return(
        &amp;lt;&amp;gt;
            {children}
        &amp;lt;/&amp;gt;
    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that our code renders as desired:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjd60yqfdk7hdt4p32z77.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjd60yqfdk7hdt4p32z77.png" alt="One h1 element saying "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Applying these principles with our more complex example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
function MainComponent(){

    return(

            &amp;lt;FirstNestedComponent&amp;gt;
                &amp;lt;SecondNestedComponent&amp;gt;
                    &amp;lt;ThirdNestedComponent&amp;gt;
                        &amp;lt;FourthNestedComponent greeting = {"Hello World"}/&amp;gt;
                    &amp;lt;/ThirdNestedComponent&amp;gt;
                &amp;lt;/SecondNestedComponent&amp;gt;
            &amp;lt;/FirstNestedComponent&amp;gt;

    )
}

function FirstNestedComponent({children}){
    return(
        &amp;lt;&amp;gt;
            {children}
        &amp;lt;/&amp;gt;
    )
}

function SecondNestedComponent({children}){
    return (
        &amp;lt;&amp;gt;
        {children}
        &amp;lt;/&amp;gt;
    )
}

function ThirdNestedComponent({children}){
    return (
        &amp;lt;&amp;gt;
            {children}
        &amp;lt;/&amp;gt;
    )
}

function FourthNestedComponent({greeting}){
    return (
        &amp;lt;h1&amp;gt;{greeting}&amp;lt;/h1&amp;gt;
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shows just how powerful composition can be. Instead of passing our values as props between multiple component layers, we can pass them directly to the required component.&lt;/p&gt;

&lt;p&gt;In the case of the &lt;code&gt;useContext&lt;/code&gt; hook, this came at the price of our components' flexibility. In this case, none of that is lost, we can easily pass different values to components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
function MainComponent(){

    return(

            &amp;lt;FirstNestedComponent&amp;gt;
                &amp;lt;SecondNestedComponent&amp;gt;
                    &amp;lt;ThirdNestedComponent&amp;gt;
                        &amp;lt;FourthNestedComponent greeting = {"Hello World"}/&amp;gt;
                        &amp;lt;FourthNestedComponent greeting = {"Howdy"}/&amp;gt;
                    &amp;lt;/ThirdNestedComponent&amp;gt;
                &amp;lt;/SecondNestedComponent&amp;gt;
            &amp;lt;/FirstNestedComponent&amp;gt;

    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And have them render different content based on their props:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nog8s9e9a9c81a6sjyr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nog8s9e9a9c81a6sjyr.png" alt="One h1 element saying "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Composition doesn't just clean up our code without adding complexity, it also &lt;em&gt;adds&lt;/em&gt; something by giving us better insight into our components' content.&lt;/p&gt;

&lt;p&gt;In our first example, looking at the &lt;code&gt;MainComponent&lt;/code&gt; on its own:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MainComponent(){
    return(
        &amp;lt;FirstNestedComponent/&amp;gt;
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;would give us no clue as to what components or JSX elements our &lt;code&gt;FirstNestedComponent&lt;/code&gt; contains.&lt;/p&gt;

&lt;p&gt;Composition allows us to see exactly what's inside our components as we write them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MainComponent(){
    return(
        &amp;lt;FirstNestedComponent&amp;gt;
            &amp;lt;SecondNestedComponent greeting = {"Hello World"}/&amp;gt;
        &amp;lt;/FirstNestedComponent&amp;gt;
}

function FirstNestedComponent({children}){
    return(
        &amp;lt;&amp;gt;
            {children}
        &amp;lt;/&amp;gt;
    )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of reducing our components' flexibility, as in the case of using context, Composition gives us a better sense of what our components contain and a better feeling of how our app is constructed, without the programmer having to travel between files to confirm what's inside their components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Reviewing what we've covered then: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Props and the ability to pass dynamic data to components are an essential part of what makes React a great framework&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The difficulty of using props across complex applications arises when having to pass values through multiple levels of component hierarchy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The cumbersome process of passing props through these component levels is called 'prop drilling'&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;useContext&lt;/code&gt; hook is one possible method of passing data directly to the required component and bypassing the need to drill through props&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The problem with context is that it makes components that derive their data from context objects less flexible and reusable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Context is a better tool for broadcasting global variables across apps than it is for specialised, small, reusable components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another method of avoiding prop drilling is direct Composition of components and passing them their content through the 'children' prop&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This not only allows us to pass the correct props directly to our nested components but it also lets us see the passed content of our components as we write them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Composition can offer the right mix of flexibility, simplicity and visibility to our components and is definitely worth turning to if we need to  pass our props through multiple levels of component hierarchy&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From my perspective, this has been a really useful working through of the different options available to me when I pass props in React.&lt;/p&gt;

&lt;p&gt;Having the time to consider each option in practice and look at the wider community's response to them has been a great exercise and is something I'll definitely return to if I suspect the way that I'm doing something regularly has better alternatives out there! Improvement, after all, is a constant process, not a final destination.&lt;/p&gt;

&lt;p&gt;Until next time and thanks for reading!&lt;/p&gt;

</description>
      <category>react</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The Subtly Different Results of Query Selectors</title>
      <dc:creator>Angus Bower-Brown</dc:creator>
      <pubDate>Tue, 12 Jul 2022 16:43:00 +0000</pubDate>
      <link>https://dev.to/angus_bowerbrown_96449f1/the-subtly-different-results-of-query-selectors-472b</link>
      <guid>https://dev.to/angus_bowerbrown_96449f1/the-subtly-different-results-of-query-selectors-472b</guid>
      <description>&lt;h3&gt;
  
  
  A Distinctly non-technical introduction
&lt;/h3&gt;

&lt;p&gt;(Skip To Content)&lt;/p&gt;

&lt;p&gt;Recently, I was talking with my instructor about what exactly to blog about. My past experience with blogging was pretty limited and every topic that  crossed my mind seemed either too large or small a problem to address in a single post.&lt;/p&gt;

&lt;p&gt;I was grateful then, when Demetrio (my instructor) gave me some solid advice on what to explore: a technical problem you’re struggling to overcome or an idea you don’t understand. &lt;/p&gt;

&lt;p&gt;It’s &lt;a href="https://fs.blog/feynman-technique/"&gt;no secret&lt;/a&gt; that writing out concepts in your own words is a great way to make them clear and find out exactly where the holes in your understanding are. By being honest about what problems you’re actually struggling with, you also get a documentation of your learning process which could be invaluable when returning to your posts at later point.&lt;/p&gt;

&lt;p&gt;With that in mind, what I’m writing about in this post is a relatively small part of JavaScript that I’ve personally struggled to grasp: the different results of  different query selectors. Those differences are subtle but go into the heart of what a webpage exactly is and how it relates to the code that defines it, so I think blogging about them will be a fantastic exercise for my learning journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query Selectors &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;When interacting with the DOM with our JavaScript, we often start by “grabbing” the element we want to affect with a query selector. &lt;/p&gt;

&lt;p&gt;So, for the following stretch of code in an HTML document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;ul id = list&amp;gt;
      &amp;lt;li class="list-entry"&amp;gt;Thing 1&amp;lt;/li&amp;gt;
      &amp;lt;li class="list-entry"&amp;gt;Thing 2&amp;lt;/li&amp;gt;
      &amp;lt;li class="list-entry"&amp;gt;Thing 3&amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I could grab the &lt;code&gt;li&lt;/code&gt; elements in a number of different ways.&lt;/p&gt;

&lt;p&gt;Three possible examples are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;using the &lt;code&gt;getElementsByClassName()&lt;/code&gt; method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;using the &lt;code&gt;querySelectorAll()&lt;/code&gt; method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;grab the containing &lt;code&gt;ul&lt;/code&gt; element and access its &lt;code&gt;childNodes&lt;/code&gt; property&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these techniques would allow me to select what I need to on the DOM, but they would also return them to me in subtly different ways.&lt;/p&gt;

&lt;p&gt;Using the first method &lt;code&gt;document.getElementsByClassName('list-entry')&lt;/code&gt; returns an &lt;strong&gt;HTML Collection&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tveN_Zo8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/swa6jkajmcu3mcjx8jyr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tveN_Zo8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/swa6jkajmcu3mcjx8jyr.png" alt="returned HTML Collection" width="800" height="36"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the second &lt;code&gt;document.querySelectorAll(".list-entry")&lt;/code&gt; returns a &lt;strong&gt;static Node List&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oFQebp2K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8pl3bx1di98aahopilzk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oFQebp2K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8pl3bx1di98aahopilzk.png" alt="returned NodeList" width="800" height="40"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the third &lt;code&gt;document.getElementById('list').childNodes&lt;/code&gt; returns a &lt;strong&gt;live Node List&lt;/strong&gt; with a different number of things within:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fi2pn2pU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvc9l37zzudg6hbkqw2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fi2pn2pU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvc9l37zzudg6hbkqw2t.png" alt="returned live node list" width="800" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is about the differences between these three results, whether those differences are important and whether or not they might affect the way I use each selector.&lt;/p&gt;

&lt;p&gt;To begin that process, we'll outline the difference between an Element and a Node.&lt;/p&gt;

&lt;h3&gt;
  
  
  Elements and Nodes
&lt;/h3&gt;

&lt;p&gt;Put simply, nodes are the objects that make up the Document Object Model. There are &lt;a href="https://www.w3schools.com/jsref/prop_node_nodetype.asp"&gt;many different kinds of node&lt;/a&gt; and  elements are simply one of those kinds that have access to methods that other kinds don't. Not all nodes are elements but all elements are nodes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MxlIaDyJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/40skkfob61rx3851desg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MxlIaDyJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/40skkfob61rx3851desg.png" alt="Venn diagram" width="460" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having loosely outlined the distinction between these two objects, I want to go into why that distinction is important for understanding the different results of query selectors.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML Collections and Node Lists
&lt;/h3&gt;

&lt;p&gt;The main difference between these two collections is what they can contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;HTML Collections contain only elements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node Lists can contain any kind of node&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This accounts for the different number of objects returned by the &lt;code&gt;childNodes&lt;/code&gt; property of my &lt;code&gt;ul&lt;/code&gt; element:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fi2pn2pU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvc9l37zzudg6hbkqw2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fi2pn2pU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvc9l37zzudg6hbkqw2t.png" alt="returned live node list" width="800" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and the &lt;code&gt;document.querySelectorAll()&lt;/code&gt; method:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oFQebp2K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8pl3bx1di98aahopilzk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oFQebp2K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8pl3bx1di98aahopilzk.png" alt="returned NodeList" width="800" height="40"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While the &lt;code&gt;document.querySelectorAll()&lt;/code&gt; method searched for all nodes with the class name of 'list-item' and returned only the elements I was after, the &lt;code&gt;childNodes&lt;/code&gt; property returned &lt;em&gt;all&lt;/em&gt; of the nodes in contained within my &lt;code&gt;ul&lt;/code&gt; element which included the non-element nodes such as 'text'.&lt;/p&gt;

&lt;p&gt;I can demonstrate that this further by adding a comment to my list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;ul id = list&amp;gt;
      &amp;lt;li class="list-entry"&amp;gt;Thing 1&amp;lt;/li&amp;gt;
      &amp;lt;li class="list-entry"&amp;gt;Thing 2&amp;lt;/li&amp;gt;
      &amp;lt;li class="list-entry"&amp;gt;Thing 3&amp;lt;/li&amp;gt;
      &amp;lt;!-- Our Comment --&amp;gt;
    &amp;lt;/ul&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Accessing the &lt;code&gt;childNodes&lt;/code&gt; property of our &lt;code&gt;ul&lt;/code&gt; again, I get:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aCH8iput--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6y5w1x0nxv40bsbq8iu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aCH8iput--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6y5w1x0nxv40bsbq8iu.png" alt="Image description" width="800" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The number of nodes has changed, whilst the number of elements are exactly the same.&lt;/p&gt;

&lt;p&gt;So, when creating a nodeList, for the vast majority of cases I'll only want to handle the elements on my DOM and so the &lt;code&gt;document.querySelectorAll()&lt;/code&gt; method  on a class is a more precise way to grab the nodes I want.&lt;/p&gt;

&lt;p&gt;If I ever want to grab some non-element nodes, I can do so with the &lt;code&gt;childNodes&lt;/code&gt; property of the containing node.&lt;/p&gt;

&lt;h3&gt;
  
  
  -
&lt;/h3&gt;

&lt;p&gt;So, that answers how best to construct a Node List to suit my goals, but what about HTML Collections? Is there a difference between using one of those as opposed to a Node List?&lt;/p&gt;

&lt;p&gt;Well, while the nodes contained in both are exactly the same- there is still a difference in the HTML Collection returned by &lt;code&gt;document.getElementsByClassName()&lt;/code&gt; and the Node List returned by &lt;code&gt;document.querySelectorAll()&lt;/code&gt;: the HTML Collection is live and the Node List is static.&lt;/p&gt;

&lt;h3&gt;
  
  
  Live and Static Collections
&lt;/h3&gt;

&lt;p&gt;The difference between live and static collections is simple enough to state plainly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Live collections update their values whenever the DOM is changed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Static collections often don't unless the method is performed again.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But despite being simple enough to articulate, I personally found it a tricky concept to grasp so, to explore it properly in practice, I'll start a basic DOM manipulation by defining both an HTML Collection and a Node List:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jTxzzUH7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqnwwt1kf3h2r9bia2fc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jTxzzUH7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqnwwt1kf3h2r9bia2fc.png" alt="Defining the two Collections" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So far, things are as expected; the two collections have the same number of objects within. &lt;/p&gt;

&lt;p&gt;I'll now add a new element to the DOM with the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r3qbwqIj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmcq63ryvr065sya09cy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r3qbwqIj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmcq63ryvr065sya09cy.png" alt="Image description" width="792" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I now recheck the values of my HTMLCollection and nodeList variables, the difference between live and static collections is made clear:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mo9elxrE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b2z1i2121lk8o3sexe2v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mo9elxrE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b2z1i2121lk8o3sexe2v.png" alt="Image description" width="800" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The HTML Collection has automatically updated its containing nodes to include the added &lt;code&gt;li&lt;/code&gt;, whereas the Node List has not.&lt;/p&gt;

&lt;p&gt;If I wanted the Node List to update its contents, I would have to call the &lt;code&gt;querySelectorAll()&lt;/code&gt; method again.&lt;/p&gt;

&lt;p&gt;Knowing this, I can now make the judgement as to which selector would be best to use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If I want my collection to be responsive to changes on the DOM, I should create a live HTML Collection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If I want my collection to change itself &lt;em&gt;only when redefined&lt;/em&gt; I should create a static Node List&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Live HTML Collections can be good for web apps that require collections to listen to changing elements on the DOM, but they can also lead to potentially confusing bugs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Static Node Lists can be great for knowing exactly what nodes your grabbing and when you want to update your list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Live collections are more dynamic, static collections are simpler to use.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  In Closing
&lt;/h3&gt;

&lt;p&gt;I haven't covered everything that separates a Node list from an HTML Collection (there's a difference in the methods that work with each for example), but I feel like I have way more a feeling now on why I would use one selector over another.&lt;/p&gt;

&lt;p&gt;Now I’m on the other side of this piece- I also feel like I haven't appreciated how valuable a part of the course these blog posts can be. The clarity this has given me over a funny and precise little part of web-dev has made it something I think I'll return to in a heartbeat for niggly problems I don't quite get.&lt;/p&gt;

&lt;p&gt;There’s never a shortage of those.&lt;/p&gt;

&lt;p&gt;Thanks for reading, here's to many more!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
