<?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: Martin Wheeler</title>
    <description>The latest articles on DEV Community by Martin Wheeler (@_martinwheeler_).</description>
    <link>https://dev.to/_martinwheeler_</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%2F392491%2F84f45c4a-f879-44f7-9aff-b31ea04250b5.jpg</url>
      <title>DEV Community: Martin Wheeler</title>
      <link>https://dev.to/_martinwheeler_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_martinwheeler_"/>
    <language>en</language>
    <item>
      <title>Creating A Horizontal Scrolling Web Page. Bonus: With Parallax!</title>
      <dc:creator>Martin Wheeler</dc:creator>
      <pubDate>Tue, 06 Oct 2020 17:32:19 +0000</pubDate>
      <link>https://dev.to/_martinwheeler_/creating-a-horizontal-scrolling-web-page-bonus-with-parallax-5ekm</link>
      <guid>https://dev.to/_martinwheeler_/creating-a-horizontal-scrolling-web-page-bonus-with-parallax-5ekm</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Hi all! I just want to say, before you delve in, that this really is a hard-and-fast explanation of how this is put together. Over the coming days I'm looking to revisit this with a video tutorial, including a more detailed explanation and a start-to-finish approach of how it's made. In the meantime though, I still wanted to share this in the hope that somebody may find it useful.&lt;/p&gt;

&lt;p&gt;I was recently inspired by a portfolio website I discovered for a designer and developer named &lt;a href="https://joseph-berry.webflow.io/" rel="noopener noreferrer"&gt;Joseph Berry&lt;/a&gt;. His website, aside from being both modern and beautiful, really got me interested in the idea of horizontal scrolling.&lt;/p&gt;

&lt;p&gt;Horizontal scrolling has become somewhat of a trend on the web and, in my opinion, it is particularly good at building websites that want to convey a story - this is most likely due to its likeness to the way we scroll through a book.  I also think it’s a nice surprise for a user when they expect to scroll down but, instead, the screen scrolls right. &lt;/p&gt;

&lt;p&gt;Jumping through the code of Mr Berry’s site also got me thinking about something else. Could I do this in CSS alone? I’ve been really intrigued lately by the philosophy of progressive enhancement and seeing what can be done with the browser’s most reliable tools, HTML and CSS. Let’s see what we can come up with.&lt;/p&gt;

&lt;p&gt;I knew off the bat there were a number things I probably wouldn’t be able to achieve with CSS alone, but that’s OK. Let’s focus on what we can do. If you’ve had a look at the website, you’ll see that there are two key visual effects - the horizontal scrolling, and the parallax effect. These are what we’ll be looking at here.&lt;/p&gt;

&lt;p&gt;This is what we'll be making:&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%2Fi%2F66w0br8zl1kcpnms51ya.gif" 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%2Fi%2F66w0br8zl1kcpnms51ya.gif" alt="Gif of the final result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's Dive Right In
&lt;/h3&gt;

&lt;p&gt;We’ll start with the HTML. &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%2Fi%2Fuckykylzbs01xghvuw9v.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%2Fi%2Fuckykylzbs01xghvuw9v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is all we need in our HTML to achieve what we need. Let's break down what's happening. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;main class="viewport"&amp;gt;&lt;/code&gt; element will be home to everything horizontal. Whilst this element isn't strictly necessary, as you could use the &lt;code&gt;body&lt;/code&gt; tag to the same result, using it will allow us to adjust the horizontal scrolling area down the line and allow us to more easily add other semantic HTML like a &lt;code&gt;header&lt;/code&gt; and &lt;code&gt;footer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Following this we have our &lt;code&gt;parallax-parent&lt;/code&gt; element which, unsurprisingly, will be the container for anything we want to apply perspective to. There's a &lt;code&gt;background-colors&lt;/code&gt; element for our background, and some &lt;code&gt;parallax-child-containers&lt;/code&gt; which will house our pages/content.&lt;/p&gt;

&lt;h3&gt;
  
  
  The CSS
&lt;/h3&gt;

&lt;p&gt;Our CSS isn't quite so straightforward, but it's also nothing mind-bending. The key to this entire setup is essentially one magical, almost limitless, CSS property - the &lt;code&gt;transform&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;I've started with some basic style-resets and also, having written this is SCSS, a couple of useful variables. We'll see shortly exactly how these will be used.&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%2Fi%2Fduw37bzhz7wltq6ud4d5.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%2Fi%2Fduw37bzhz7wltq6ud4d5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can, of course, create this is vanilla CSS and simply hard-code these values.&lt;/p&gt;

&lt;p&gt;The below code is all that's needed to style our &lt;code&gt;viewport&lt;/code&gt; element.&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%2Fi%2Fvijkwivxlvj6nq1vvomk.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%2Fi%2Fvijkwivxlvj6nq1vvomk.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This simply ensures that our element takes up 100% of the available screen-space, and doesn't allow for any scrollbars to appear should the content exceed this size - which it will. &lt;/p&gt;

&lt;p&gt;Our parallax-parent element is what will allow us to achieve the cool 3D effect found on many modern websites. You know the one - where one element moves a bit faster than the other, giving the illusion of them being closer and farther away respectively. We do this by applying  &lt;code&gt;perspective: 3px&lt;/code&gt; to the element and setting it's &lt;code&gt;perspective-origin&lt;/code&gt;.&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%2Fi%2Fogaf1fq5sommwa90e1r7.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%2Fi%2Fogaf1fq5sommwa90e1r7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The default value of &lt;code&gt;perspective-origin&lt;/code&gt; is actually what you see above (&lt;code&gt;50% 50% 0&lt;/code&gt;) so there's no need to code this in. I put it there originally so I could play around with the values, so I've left it there in case you want to do the same. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;parallax-parent&lt;/code&gt; also doubles up in one extremely important way, leading me to think later that maybe &lt;code&gt;parallax-parent&lt;/code&gt; wasn't the best naming for this element. It's this element which actually does the thing you came here for. &lt;/p&gt;

&lt;p&gt;Check out line 8 of the code - &lt;code&gt;transform: rotate(-90deg);&lt;/code&gt;. This element is actually being rotated anti-clockwise so that it's top is it's left, it's left is it's bottom, it's...well, so on and so on. &lt;/p&gt;

&lt;p&gt;We've also set the &lt;code&gt;transform-origin: top left;&lt;/code&gt; which means that the rotation will happen around the top left corner. Let me explain with a diagram.&lt;/p&gt;

&lt;p&gt;This blue rectangle represents our &lt;code&gt;parallax-parent&lt;/code&gt; - in this case being displayed on something like a desktop screen. In the top left corner you'll notice a red circle. This is our &lt;code&gt;transform-origin&lt;/code&gt;. &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%2Fi%2F3hfc4qm17h4kwfk2gy3g.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%2Fi%2F3hfc4qm17h4kwfk2gy3g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now, when we rotate this counter-clockwise by 90 degrees, or &lt;code&gt;rotate(-90deg)&lt;/code&gt; as CSS would have it, this is the point at which the rotation will occur.&lt;/p&gt;

&lt;p&gt;And what does that look like? Well, on your screen, it will look like your element vanished! Why is that?&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%2Fi%2Fwhetazhrr8tw47nk347k.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%2Fi%2Fwhetazhrr8tw47nk347k.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, our element has rotated its way out of the viewport and, therefor, can no longer be seen. This is where our use of &lt;code&gt;top: $height&lt;/code&gt; (or &lt;code&gt;top: 100vh&lt;/code&gt; for CSS) comes in to help us out to return the element back into view. You'll also note that our &lt;code&gt;height&lt;/code&gt; is set as &lt;code&gt;$width&lt;/code&gt; and our &lt;code&gt;width&lt;/code&gt; is set as &lt;code&gt;$height&lt;/code&gt;. This now adjusts our element to fit nicely back into the viewport like it was before, only this time rotated -90 degrees.&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%2Fi%2F57m5cv4vucm9onv3doh5.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%2Fi%2F57m5cv4vucm9onv3doh5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This has now become a very important point moving forward, as how we deal with &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, and &lt;code&gt;right&lt;/code&gt; in CSS with our &lt;code&gt;absolute&lt;/code&gt; positioned elements has been affected...and it can be somewhat confusing at first.&lt;/p&gt;

&lt;p&gt;Lastly you'll notice that &lt;code&gt;::-webkit-scrollbar&lt;/code&gt; has been used to hide the scrollbar in our element. An important note here is that this selector is not a web standard and will have different outcomes on different browsers, so be careful. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From the MDN docs:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;::-webkit-scrollbar&lt;/code&gt; is only available in Blink- and WebKit-based browsers (e.g., Chrome, Edge, Opera, Safari, all browsers on iOS, and others). &lt;/p&gt;
&lt;/blockquote&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%2Fi%2Fn6kaa7q8hzycp3h2cry1.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%2Fi%2Fn6kaa7q8hzycp3h2cry1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;background-colors&lt;/code&gt; element incorporates a simple CSS gradient to mimic a colour change as the user scrolls. In the example website I pointed to at the beginning of the post the developer uses JavaScript to change the colour dynamically, most likely with scroll event listeners. As we said we would be using plain S/CSS only, we'll stick with a gradient.&lt;/p&gt;

&lt;p&gt;The element has been sized to cover &lt;code&gt;$width * $pages&lt;/code&gt; (or &lt;code&gt;100vw * 3 = 300vw&lt;/code&gt;) and can be resized as necessary. Bare in mind, using this approach, if you want each page to have its own colour you will need to adjust the gradient accordingly.&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%2Fi%2Fqhnp9gwr8k398ehxy1kg.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%2Fi%2Fqhnp9gwr8k398ehxy1kg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;parallax-child-container&lt;/code&gt; element uses much of the same styling with regards to sizing as its parent element, the &lt;code&gt;parallax-parent&lt;/code&gt;, with the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; still being "reversed". Here I've used a SCSS function to iterate over the elements and apply a &lt;code&gt;top&lt;/code&gt; equivalent to the  &lt;code&gt;nth-of-type - 1 * $width&lt;/code&gt;.  Essentially this gives the first element a &lt;code&gt;top: 0&lt;/code&gt;, the second a &lt;code&gt;top: 100vw&lt;/code&gt;, the third a &lt;code&gt;top: 200vw&lt;/code&gt;, and so on. AGain, you could easily hard code this into the CSS as even with the SCSS we need to know how many elements (or &lt;code&gt;$pages&lt;/code&gt;) we have for the function to work. &lt;/p&gt;

&lt;p&gt;Now, all of our "pages" take up a full-screen each, much like in the example portfolio or Joseph's. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;parallax-child&lt;/code&gt; element is where we start to return back to "vertical viewing". Let's look at the different transforms we're using on this element.&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%2Fi%2Fccjtzmuz799rjlm7r9g0.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%2Fi%2Fccjtzmuz799rjlm7r9g0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To keep the element central within its parent, we apply a value &lt;code&gt;50%&lt;/code&gt; to both &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;left&lt;/code&gt;, and &lt;code&gt;-50%&lt;/code&gt; to both &lt;code&gt;translateX&lt;/code&gt; and &lt;code&gt;translateY&lt;/code&gt;. We also apply &lt;code&gt;rotate(90deg)&lt;/code&gt; to bring everything back to "normal", visually speaking. Again, the default values for &lt;code&gt;transform-origin&lt;/code&gt; have been left so there's no need to keep these should you be happy with them. &lt;/p&gt;

&lt;p&gt;Finally, our z axis gets some love! By applying &lt;code&gt;translateZ(-1px)&lt;/code&gt; we see a shift "backwards" in our elements position. And, when we scroll, we notice that the element scrolls a little more slowly than before. It's very subtle, but noticeable if you focus on the gradient. If you're working against a plain background, you likely wouldn't apply this transform to these elements.&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%2Fi%2Fbjviuibyy3khfq3ergkp.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%2Fi%2Fbjviuibyy3khfq3ergkp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly, we apply similar styling to the &lt;code&gt;parallax-background&lt;/code&gt;, only this time we push it "back" much further at &lt;code&gt;-8px&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;You may have noticed that when we apply a value to &lt;code&gt;translateZ&lt;/code&gt;, we also apply a value to &lt;code&gt;scale&lt;/code&gt;.  There is a useful write-up by &lt;a href="https://developers.google.com/web/updates/2016/12/performant-parallaxing" rel="noopener noreferrer"&gt;Google&lt;/a&gt; explaining this in more detail and why this is done, but essentially it negates the resizing that takes place when we "push" or "pull" our elements backwards or forwards respectively. Imagine driving further away from a building, it get's smaller, right? The only way to make it seem the same size it was before, without driving back, is to scale it up. Voila!  &lt;/p&gt;

&lt;p&gt;Lastly, we size the background to cover the number of pages we have, in this case 3. Once we've applied some styling to the header nested in &lt;code&gt;parallax-background&lt;/code&gt; we're done!&lt;/p&gt;

&lt;p&gt;I hope I was able to share something interesting with you here, and I’d really appreciate any feedback on either the content or the writing. I’d like to do this more often and making it worthwhile would be a massive bonus.&lt;/p&gt;

&lt;p&gt;You can find the sourcecode for this project on &lt;a href="https://github.com/m87wheeler/horizontal-page-parallax" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Create A React Search Bar That Highlights Your Results</title>
      <dc:creator>Martin Wheeler</dc:creator>
      <pubDate>Thu, 24 Sep 2020 12:03:53 +0000</pubDate>
      <link>https://dev.to/_martinwheeler_/create-a-react-search-bar-that-highlights-your-results-4hdh</link>
      <guid>https://dev.to/_martinwheeler_/create-a-react-search-bar-that-highlights-your-results-4hdh</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Sometimes it's fun to put the big projects aside for a while and make something small. That's not to say it can't be challenging - it's most of the time during these small endeavours that I find myself learning something new that I may have been putting off for a while. This is the joy of not having the  distraction of scores of components, state, props and more.&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%2Fi%2Frsa2tb3peze645i723o6.gif" 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%2Fi%2Frsa2tb3peze645i723o6.gif" alt="A gif showing the final outcome of the project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For no specific reason, I was inspired to make a dynamic search bar which does three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes a text input&lt;/li&gt;
&lt;li&gt;Filters the results containing said text&lt;/li&gt;
&lt;li&gt;Highlighting that very text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd made something similar to this a long time ago in vanilla JS, but I don't remember how exactly (and chances are I won't want to).&lt;/p&gt;

&lt;p&gt;However, it was something I hadn't needed up until now in a React project so I thought it would be a good use of time in case, you know, the time ever comes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools For The Job
&lt;/h3&gt;

&lt;p&gt;Being the "bish-bash-bosh" project this was I stuck with React and React alone. OK, there's obviously &lt;em&gt;some&lt;/em&gt; styling, but nothing more than a few imported Material UI components. This really was more about the functionality then anything else.&lt;/p&gt;

&lt;p&gt;We will also be making use of some JSON placeholder from this &lt;a href="https://jsonplaceholder.typicode.com/" rel="noopener noreferrer"&gt;JSONplaceholder&lt;/a&gt; website to populate our app. We're pulling from the following API:&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%2Fi%2Ffufutpgatddvze41d32k.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%2Fi%2Ffufutpgatddvze41d32k.png" alt="API Endpoint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will deliver back to us an array of objects, each like so:&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%2Fi%2Fafvjuj87ymdw8e1wh237.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%2Fi%2Fafvjuj87ymdw8e1wh237.png" alt="Example of the objects we get back"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting It Done
&lt;/h3&gt;

&lt;p&gt;The file structure for this project is as follows:&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%2Fi%2Fgqrpu75o7r61nixml33m.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%2Fi%2Fgqrpu75o7r61nixml33m.png" alt="File structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's go through the components before diving into &lt;code&gt;App.js&lt;/code&gt;, where the bulk of our logic sits, so we can gain an understanding of what's going on in each. &lt;/p&gt;

&lt;p&gt;Let's take a look at &lt;code&gt;Item.js&lt;/code&gt;.&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%2Fi%2Fhk90o3bpl9ddt0sefwaj.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%2Fi%2Fhk90o3bpl9ddt0sefwaj.png" alt="Our Item component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we move on, I just want to point out that &lt;code&gt;Card&lt;/code&gt;, &lt;code&gt;CardContent&lt;/code&gt;, &lt;code&gt;Typography&lt;/code&gt;, and &lt;code&gt;classes.*&lt;/code&gt; are all related to Material UI and not important to what's going on. You can think of them as almost any HTML element you like.&lt;/p&gt;

&lt;p&gt;With that aside, let's look at what is important. &lt;/p&gt;

&lt;p&gt;Well, if we were to look at this without all of the additional styling or function we would have 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%2Fi%2Fjc6au59w31nsfn0hfmci.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%2Fi%2Fjc6au59w31nsfn0hfmci.png" alt="A simplified Item component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, for the most part, this component is essentially our container for each of our objects we receive back from our JSON placeholder API. These values are being passed into the component via &lt;code&gt;props&lt;/code&gt; and rendered as we choose.&lt;/p&gt;

&lt;p&gt;We'll come back to the slightly more complex version once we've look over the rest of our components.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SearchBar.js&lt;/code&gt; is an even more compact component. Beautiful!&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%2Fi%2Fgllsak8egi6rjq7s1zb0.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%2Fi%2Fgllsak8egi6rjq7s1zb0.png" alt="Our SearchBar component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, please note that the &lt;code&gt;Textfield&lt;/code&gt; element is a Material UI component, and could just as easily be an &lt;code&gt;input&lt;/code&gt; element with the &lt;code&gt;type="text"&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;The only &lt;code&gt;prop&lt;/code&gt; that is passed to this component is via &lt;code&gt;props.onInput&lt;/code&gt;, which is responsible for updating our state each time a new character is typed into or deleted from our input field.&lt;/p&gt;

&lt;p&gt;Our last component is &lt;code&gt;Counter.js&lt;/code&gt;. This component isn't strictly required to make this project work, however I thought it was a nice touch.&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%2Fi%2F4mlqjjfe7408dotocyvh.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%2Fi%2F4mlqjjfe7408dotocyvh.png" alt="Our Counter component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You know the deal with the Material UI stuff by now!&lt;/p&gt;

&lt;p&gt;Only one &lt;code&gt;prop&lt;/code&gt; this time. We're simple passing in a result, and we'll come back to exactly what that is very soon.&lt;/p&gt;

&lt;p&gt;OK, it's time for the big one. Let's move on to &lt;code&gt;App.js&lt;/code&gt;. For the sake of readability we'll break this down into smaller sections as it's a fair bit larger than the previous components. Not humongous, but bigger nonetheless. &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%2Fi%2Fbrksccf3dc88eadk6wx1.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%2Fi%2Fbrksccf3dc88eadk6wx1.png" alt="The App.js imports"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This part of the app makes use of the &lt;code&gt;useEffect&lt;/code&gt; and &lt;code&gt;useReducer&lt;/code&gt; hooks provided natively with ReactJS, so we'll start by importing those. We then bring in our 3 components we just went through to complete our imports.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Note On useReducer
&lt;/h3&gt;

&lt;p&gt;As the functionality for this project was all crammed into the &lt;code&gt;App&lt;/code&gt; component, I decided to opt for &lt;code&gt;useReducer&lt;/code&gt; over &lt;code&gt;useState&lt;/code&gt; to save from having four separate state variables, though it could just as well have been implemented that way too.&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%2Fi%2Fn0hrox3cyfnsae1bajnh.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%2Fi%2Fn0hrox3cyfnsae1bajnh.png" alt="The initial state and reducer function set up"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're familiar with &lt;code&gt;useReducer&lt;/code&gt; you can skip along to the Continuing With The App section. Just take note of the code above and the coming snippets.&lt;/p&gt;

&lt;p&gt;We start by declaring our &lt;code&gt;initialState&lt;/code&gt; for the component which consists of four different keys - so what are they for?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;isLoading&lt;/code&gt; accepts a boolean value to essentially let our app know whether the async function has completed or not - or is loading.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data&lt;/code&gt; will be our store for the array we receive back from our API call. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;search&lt;/code&gt; will hold the string which is entered into the &lt;code&gt;SearchBar&lt;/code&gt; component.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;searchData&lt;/code&gt; will be a filtered version of our data state array. This will remain an empty array until something is entered into the search input.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our &lt;code&gt;reducer&lt;/code&gt; function is the tool we use to alter or update our state object as necessary. A note here, you should declare both your &lt;code&gt;initialState&lt;/code&gt; object and &lt;code&gt;reducer&lt;/code&gt; function outside of the component itself. If you are familiar with how &lt;code&gt;useState&lt;/code&gt; works then you're in a good position to understand &lt;code&gt;useReducer&lt;/code&gt; as the two are very similar. I'll explain how.&lt;/p&gt;

&lt;p&gt;I mentioned before that this could have just as easily been implemented with &lt;code&gt;useState&lt;/code&gt; over &lt;code&gt;useReducer&lt;/code&gt;, and here's an example of how the two compare. Both of the code examples below have one thing in common - in the &lt;code&gt;useReducer&lt;/code&gt; example the &lt;code&gt;dataTwo&lt;/code&gt; and &lt;code&gt;isLoading&lt;/code&gt; key/values are able to hold the exact same information as the &lt;code&gt;dataOne&lt;/code&gt; and &lt;code&gt;isLoading&lt;/code&gt; variables in the &lt;code&gt;useState&lt;/code&gt; example. This comes as no surprise as this is plain JavaScript. The difference between them comes in how the state is updated.&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%2Fi%2F5ib5smvzaaooqgkglo4i.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%2Fi%2F5ib5smvzaaooqgkglo4i.png" alt="A comparison of useState and useReducer state management"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;useState&lt;/code&gt; we are provided a function, which we name, as a return value from &lt;code&gt;useState()&lt;/code&gt;. This function is how we update the value of state, for example &lt;code&gt;setData(data)&lt;/code&gt; would update our &lt;code&gt;data&lt;/code&gt; state to contain (in this example) the array returned from our API call, and then we could call &lt;code&gt;setIsLoading(false)&lt;/code&gt; which would update the &lt;code&gt;isLoading&lt;/code&gt; variable from true to false.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;useReducer&lt;/code&gt; we need to provide a reducer function (which we did in our code snippet above) to update the state object. This has the added benefit of being able to update multiple states at once. Take a look at &lt;code&gt;case "SET_DATA":&lt;/code&gt; in our snippet. &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%2Fi%2Fo2yza23zun9n765vq3gp.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%2Fi%2Fo2yza23zun9n765vq3gp.png" alt="Switch statement case"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the return value we start by passing in the initial state using the ES6 spread operator. This essentially ensures we start where we left off and pass all existing state values back into the object we want to return. We then pass in the key/value pair of &lt;code&gt;data: action.payload&lt;/code&gt;. This updates the current value of &lt;code&gt;data&lt;/code&gt; to the one which we pass in when we call the &lt;code&gt;reducer&lt;/code&gt; function (which we'll come to soon). In the same &lt;code&gt;return&lt;/code&gt;, we are also able to update &lt;code&gt;isLoading&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; to end the loading sequence. &lt;/p&gt;

&lt;p&gt;All that's left to do is use the &lt;code&gt;useReducer&lt;/code&gt; function like so :&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%2Fi%2Fzga8bfbepil9yfo6kiek.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%2Fi%2Fzga8bfbepil9yfo6kiek.png" alt="useReducer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gives us access, in the same was as &lt;code&gt;useState&lt;/code&gt;, to our &lt;code&gt;initalState&lt;/code&gt; (and object in this case stored in the state variable) and a function to update our state (in this case stored in &lt;code&gt;dispatch&lt;/code&gt;). We pass in our reducer function and &lt;code&gt;intialState&lt;/code&gt; and we are ready to go! We can now call &lt;code&gt;dispatch&lt;/code&gt; in our component which will fire off our &lt;code&gt;reducer&lt;/code&gt; function and update our &lt;code&gt;initialState&lt;/code&gt; object:    &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%2Fi%2Fh8krpibxudxs1k0wtvgz.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%2Fi%2Fh8krpibxudxs1k0wtvgz.png" alt="An example of dispatch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to pass in the "type" of update we wish to be carried out and, where applicable, the "payload" for the update. &lt;code&gt;type&lt;/code&gt; is determined in the &lt;code&gt;switch&lt;/code&gt; statement of the &lt;code&gt;reducer&lt;/code&gt; function, and &lt;code&gt;payload&lt;/code&gt; is a fancy word for the data we want to store there (be it an array, boolean, string, etc.) And that's state updated!&lt;/p&gt;

&lt;p&gt;Hopefully, you can see how &lt;code&gt;useReducer&lt;/code&gt; could be beneficial. As the complexity of your app and its state grow, and the relationship between those states becomes stronger, you will inevitably find that &lt;code&gt;useReducer&lt;/code&gt; is superior in handling the growing workload. Of course, you would likely want to incorporate a level of error checking to this but for the sake of this project this was sufficient.&lt;/p&gt;

&lt;h3&gt;
  
  
  Continuing With The App
&lt;/h3&gt;

&lt;p&gt;Now we've got a home for our state and the ability to update it we can move on to the functionality. I won't go into how the data is fetched from the API, there are a million tutorials, blog posts and docs on that. All that you will want to know is that we use the &lt;code&gt;dispatch&lt;/code&gt; example above to get that data into our state.&lt;/p&gt;

&lt;p&gt;The return statement for our &lt;code&gt;App&lt;/code&gt; component contains our &lt;code&gt;SearchBar&lt;/code&gt;, &lt;code&gt;Counter&lt;/code&gt;, and &lt;code&gt;Item&lt;/code&gt; components. Let's go through each one and start connecting the dots.&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%2Fi%2F5cmba5veik9cewwlbb1h.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%2Fi%2F5cmba5veik9cewwlbb1h.png" alt="App.js return function and contents"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll start with our &lt;code&gt;SearchBar&lt;/code&gt; component and the function that is called within its &lt;code&gt;onInput&lt;/code&gt; attribute. As you'll remember, we passed a prop down to this component via &lt;code&gt;props.onInput&lt;/code&gt; and this allows us to call the following function when we type something into our text input:&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%2Fi%2Fcictc9s5cywb2m1dcksy.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%2Fi%2Fcictc9s5cywb2m1dcksy.png" alt="Our handleInput function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Woah! That's a lot of code for an input. Well, this function does a little more that just deal with the input itself. Let's deal with that first though, and it's a pretty small part of the function.&lt;/p&gt;

&lt;p&gt;On the second line of the function we declare a variable &lt;code&gt;str&lt;/code&gt; and assign it &lt;code&gt;e.target.value&lt;/code&gt; which simply keeps the string as it is entered into the input field. On the following line we call our dispatch function (go back through the &lt;strong&gt;A Note On useReducer&lt;/strong&gt; section if you've no idea what that means) and pass the type of &lt;code&gt;'SEARCH_INPUT'&lt;/code&gt; and &lt;code&gt;payload&lt;/code&gt; the value of &lt;code&gt;str&lt;/code&gt;. This, together, updates our state to always store the most up-to-date string in the input field. &lt;/p&gt;

&lt;p&gt;The next part of the function deals with the filtering of our data array, stored in &lt;code&gt;state.data&lt;/code&gt;. We make use of the JavaScript &lt;code&gt;.filter()&lt;/code&gt; method to iterate through the &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt; values of our objects and see if the text in our &lt;code&gt;str&lt;/code&gt; variable is included (using JavaScripts &lt;code&gt;.include()&lt;/code&gt; method anywhere in their respective string. The addition of the &lt;code&gt;.toLowerCase()&lt;/code&gt; method ensures that no matter what casing we use when we type into the search bar, if the letters themselves match our filtering will be successful. Without this a search for "Hello World" would not return the result "hello world" - and we don't want to be that pedantic with our users!&lt;/p&gt;

&lt;p&gt;One of the many great thing about JavaScripts array methods is the ability to chain them together. In this instance, we can then call the &lt;code&gt;.map()&lt;/code&gt; method on &lt;code&gt;state.data&lt;/code&gt; to iterate though each of the filtered objects and apply our highlighting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Highlight: The Highlight
&lt;/h3&gt;

&lt;p&gt;This took me a great many attempts to get right, and part of me wishes I could have found a way to do it using only the strings themselves, however I had to call upon the dreaded &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; to make this work. &lt;/p&gt;

&lt;p&gt;At the beginning of this article I showed you the following code: &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%2Fi%2F6gisvn0b2jsfbdblurgz.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%2Fi%2F6gisvn0b2jsfbdblurgz.png" alt="Our item component, again"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is our &lt;code&gt;Item&lt;/code&gt; component, and you've likely noticed that two of the elements make use of &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; to populate themselves. If you want to read more about &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; then I suggest checking out the &lt;a href="https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml" rel="noopener noreferrer"&gt;official docs&lt;/a&gt;.  However, we will make the assumption in our case that we trust our source and the content it provides.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;createMarkup&lt;/code&gt; function returns an object with the key of &lt;code&gt;__html&lt;/code&gt; and value of the HTML itself, as recommended in the React docs, and this value is used to set the inner HTML of each element. This approach turned out to be necessary to be able to inject a &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt; element into the string to function as our highlighter.&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%2Fi%2F6989cq2gi76eujq6nuj2.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%2Fi%2F6989cq2gi76eujq6nuj2.png" alt="mapping through our new array"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will be making use of JavaScript's &lt;code&gt;.replace()&lt;/code&gt; method to highlight our strings, therefore we start by declaring a new variable for the value we will have returned to us by this method. &lt;code&gt;.replace()&lt;/code&gt; takes in two arguments, the first of which is the pattern which we want replaced. This could simply be a string or, as is our approach, a &lt;code&gt;RegExp&lt;/code&gt;. The &lt;code&gt;RegExp&lt;/code&gt; itself takes two arguments - firstly the string (or pattern) we want to identify, and secondly some options (or &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Advanced_searching_with_flags" rel="noopener noreferrer"&gt;flags&lt;/a&gt;) to give the &lt;code&gt;RegExp&lt;/code&gt; some guidance on what we want done. In our case we pass the string &lt;code&gt;"gi"&lt;/code&gt;. This does two things. The g tells the &lt;code&gt;RegExp&lt;/code&gt; that we want to search the entire string and return all matches, and the &lt;code&gt;i&lt;/code&gt; that our search should be case-insensitive and without this, like if we were to omit the &lt;code&gt;.toLowerCase()&lt;/code&gt; method from our filter, we would not highlight words regardless of their case.&lt;/p&gt;

&lt;p&gt;One the has &lt;code&gt;RegExp&lt;/code&gt; has identified the characters we would like to replace it moves on to the second argument in the &lt;code&gt;.replace()&lt;/code&gt; method, which is the what should replace that. This is where and why our use of &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; was necessary as we are inserting the &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt; tag back into our object. Without this we would actually render the characters &lt;strong&gt;&lt;/strong&gt; around our string on the screen.  &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%2Fi%2Fuplor0ticehh1gamnxnj.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%2Fi%2Fuplor0ticehh1gamnxnj.png" alt="Text with the mark tags"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not pretty.&lt;/p&gt;

&lt;p&gt;This second argument is a function with the parameter of &lt;code&gt;match&lt;/code&gt;.  This allows us to re-purpose our original string, wrap it in the new HTML element, and return it. These new values are now the values stored in the &lt;code&gt;newTitle&lt;/code&gt; and &lt;code&gt;newBody&lt;/code&gt; variables. We can now simply return these back into the &lt;code&gt;newArr&lt;/code&gt; constant  in our return statement, being careful not to overwrite our original object values using the spread operator:&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%2Fi%2F8t5jkxlh27lqz5ekvs2s.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%2Fi%2F8t5jkxlh27lqz5ekvs2s.png" alt="The return statement from our filter and map methods"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final piece to this function is to dispatch our new array &lt;code&gt;newArr&lt;/code&gt; of filtered and highlighted objects into our state. &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%2Fi%2F0sqk7pajxgwm9glbowah.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%2Fi%2F0sqk7pajxgwm9glbowah.png" alt="calling dispatch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now all that's left is to render the results.&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%2Fi%2Fc9o09gyj31vafuif46vs.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%2Fi%2Fc9o09gyj31vafuif46vs.png" alt="Ternary operator in App.js return"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This nested ternary operator asks two questions to decide what to do. Firstly, have you finished loading yet? Yes? Right! Then, have you typed anything into the search field (&lt;code&gt;state.search.length &amp;gt; 0 ?&lt;/code&gt;)? Yes? In which case, I'll run through everything that's now in &lt;code&gt;state.searchData&lt;/code&gt; (including their new title and body values and their &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt; elements you filtered out) and generate your &lt;code&gt;Item&lt;/code&gt;s for you.&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%2Fi%2Fb7b1oia7s1tr9grvyeub.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%2Fi%2Fb7b1oia7s1tr9grvyeub.png" alt="The final working app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voila! Would you look at that!&lt;/p&gt;

&lt;p&gt;And if there isn't anything in the search bar? Well then, I'll just render everything you have stored in &lt;code&gt;data&lt;/code&gt;. This is completely unfiltered and untouched.&lt;/p&gt;

&lt;p&gt;But, what happens if I do type something into the search but it doesn't have any matches? Well, typing into &lt;code&gt;SearchBar&lt;/code&gt; will mean that our ternary operator will see that there are characters in our &lt;code&gt;state.searchand&lt;/code&gt; render everything in the array...nothing! &lt;/p&gt;

&lt;h3&gt;
  
  
  A Little Something Extra
&lt;/h3&gt;

&lt;p&gt;The counter shown in the examples above is more of a nice to have, but in some cases it might be useful to give the user some idea of how may items they have filtered down to. For example, typing the string "aut" into my search gives me 66 matches. Maybe I could be more specific before trying to scroll through all of that data. Oh yeah, "aut facere" gives me only 2 results! Great.&lt;/p&gt;

&lt;p&gt;This is a simple little component which simply gets passed the length of the &lt;code&gt;state.searchData&lt;/code&gt; array (or nothing, if there isn't anything, to save displaying 0 all of the time). &lt;/p&gt;

&lt;p&gt;Here's the component itself:  &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%2Fi%2Fzvepluqutvjr787m49ui.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%2Fi%2Fzvepluqutvjr787m49ui.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And its implementation into &lt;code&gt;App.js&lt;/code&gt;:&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%2Fi%2Fitnnqi4icgg917qmr8w0.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%2Fi%2Fitnnqi4icgg917qmr8w0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that’s it! I hope I was able to share something interesting with you here, and I’d really appreciate any feedback on either the content or the writing. I’d like to do this more often and making it worthwhile would be a massive bonus.&lt;/p&gt;

&lt;p&gt;You can find the sourcecode for this project on &lt;a href="https://github.com/m87wheeler/react-search-bar" rel="noopener noreferrer"&gt;Github&lt;/a&gt;, and I will really appreciate a visit over on &lt;a href="https://martinwheelerweb.com/" rel="noopener noreferrer"&gt;my website&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>react</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Create A Responsive Masonry Layout With Horizontal Flow</title>
      <dc:creator>Martin Wheeler</dc:creator>
      <pubDate>Thu, 17 Sep 2020 13:41:41 +0000</pubDate>
      <link>https://dev.to/_martinwheeler_/create-a-responsive-masonry-layout-with-horizontal-flow-2mpk</link>
      <guid>https://dev.to/_martinwheeler_/create-a-responsive-masonry-layout-with-horizontal-flow-2mpk</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;I love online photo galleries. You can get lost in photography for hours, particularly when the photographer really has something special to show off. It’s with that in mind that, as a developer and designer, you feel that justice has to be done to those images.&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%2Fi%2F5jnexc4705aks2cxb4gz.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%2Fi%2F5jnexc4705aks2cxb4gz.png" alt="Screenshot of the gallery"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And this was my take on the infamous photo gallery project. I’m extremely happy with how it turned out and, although it may not seem much of an endeavour on the surface, it introduced me to a little something known as &lt;em&gt;Masonry&lt;/em&gt; layout - and why there are a number of plugins and libraries developed to tackle just this. However, by the time I had decided what I wanted to achieve, I didn’t want to opt for a package to do this for me. I wanted to tackle this myself!&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Masonry?
&lt;/h3&gt;

&lt;p&gt;Masonry in web terms is the layout of unevenly sized tile, or brick, like elements in a way that there are only even gaps between them on both the x and y axis. It allows for a &lt;em&gt;Pinterest&lt;/em&gt;-esque style look to your web page. &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%2Fi%2Fiy9csgk4ix1cnni0q7tf.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%2Fi%2Fiy9csgk4ix1cnni0q7tf.png" alt="Representation of the masonry layout vertically"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A quick search brings up multiple tutorials and suggestions from developers aiming to help you achieve this layout, in particular with a CSS only approach. I too really wanted to achieve this effect with only CSS, however there was always one downside to the solutions I found - the content flowed &lt;em&gt;vertically&lt;/em&gt;. Given that this was a photographers website where content would be updated over time, it made sense to me that the images should flow from left to right, showing the newest uploads at the top of the page.&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%2Fi%2F9gjdgqbr5ydca0hiac32.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%2Fi%2F9gjdgqbr5ydca0hiac32.png" alt="Representation of the masonry layout horizontally"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As it turned out, I wasn’t able to get what I was looking for using CSS alone without having either fixed height rows or vertical flow, both using flex or grid.&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%2Fi%2Fe5zwijxr5s08gkqdklj4.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%2Fi%2Fe5zwijxr5s08gkqdklj4.png" alt="Representation of a fixed height rows layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools For The Job
&lt;/h3&gt;

&lt;p&gt;As is common lately I chose React as my working platform. This was simply because I knew I would be using a lot of components when building the rest of this portfolio site and I like how React, utilising &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt;, makes handling API requests easy. For the CMS I chose Cosmic (formerly CosmicJS), a headless CMS with a very easy to use REST/GraphQL API and user-friendly dashboard for the client. It also provides a seemingly limitless free-tier and Imgix compression abilities. Win win!&lt;/p&gt;

&lt;p&gt;So, without further ado, let’s move on from the why and what, to the how. I’m not planning on going into depth on how the entire site was put together - it’s a fairly simple React site using &lt;code&gt;react-router-dom&lt;/code&gt;. I should also say that this isn’t a tutorial on React, &lt;code&gt;styled-components&lt;/code&gt;, or any of the other tools I’ve used. We’ll jump right in at the gallery part.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting It Done
&lt;/h3&gt;

&lt;p&gt;I used the following file structure for the gallery part of the project:&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%2Fi%2Flk96ilnlyotp1u8c1orl.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%2Fi%2Flk96ilnlyotp1u8c1orl.png" alt="File tree for the project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s start by taking a look at &lt;code&gt;GalleryPage.js&lt;/code&gt;. This is essentially the wrapper which all of the good stuff sits inside.  From there, we can dig deeper.&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%2Fi%2Fd31jpw3wdt1lv1bqa319.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%2Fi%2Fd31jpw3wdt1lv1bqa319.png" alt="Code: React imports"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As always we make our start with our imports. As I mentioned at the beginning, the gallery makes use of the &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt; hooks provided natively by React, so we bring those in along with React itself. We then import &lt;code&gt;styled-components&lt;/code&gt; which, for anyone who is unfamiliar with it, is a fantastic library for utilising JS-in-CSS. Bear in mind, you won’t need styled-components to make this work - you can simply import normal CSS files or S/CSS modules into your project.&lt;/p&gt;

&lt;p&gt;I generally like to structure my imports as above, with native or &lt;code&gt;npm&lt;/code&gt; provided imports at the top, logic/hooks/etc imports just after that, and lastly any components. It’s not gospel of course, it’s just the way I like to keep myself organised.&lt;/p&gt;

&lt;p&gt;I’ll come back to the rest of the imports soon. For now, let’s take a look at the rest of &lt;code&gt;GalleryPage&lt;/code&gt;.&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%2Fi%2F32vnl1itmg5776s5vxxc.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%2Fi%2F32vnl1itmg5776s5vxxc.png" alt="Code: React state and fetch function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There’s quite a lot going on there, so let’s break it down. First, we declare the component name which, in this instance, is &lt;code&gt;GalleryPage&lt;/code&gt;. We then declare a number of variables which will be used to hold our site’s state.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;isLoading&lt;/code&gt; and &lt;code&gt;setIsLoading&lt;/code&gt; will, unsurprisingly, manage our loading sequence whilst we wait for fetch to retrieve our data, and &lt;code&gt;imageData&lt;/code&gt; and &lt;code&gt;setImageData&lt;/code&gt; will look after our data once it is retrieved. We’ll come back to the others shortly.&lt;/p&gt;

&lt;p&gt;Using JavaScript’s &lt;code&gt;fetch&lt;/code&gt; API we then make a request to the CosmicJS endpoint, for which you will need to get yourself an API key, and we receive back a JSON object. We can access the array we need under the object’s &lt;code&gt;media&lt;/code&gt; key, so make sure that this is what you set as your state. Once we’ve set our state to our array using &lt;code&gt;setImageData(data.media)&lt;/code&gt; we will now be able to use it to generate our images.&lt;/p&gt;

&lt;p&gt;In the return statement for our component we need the following code:&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%2Fi%2Fz6jvuyy9fj25sw2moo9p.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%2Fi%2Fz6jvuyy9fj25sw2moo9p.png" alt="Code: React component return statement and contents"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;GalleryWrapper&lt;/code&gt; and &lt;code&gt;GalleryWrapper&lt;/code&gt; elements have been created using &lt;code&gt;styled-components&lt;/code&gt;, for now just think of them as any other React component. Inside here we &lt;code&gt;map&lt;/code&gt; through our array and, ultimately, create our images. Now, the astute of you may have noticed something off in the code snippet above. We originally stored our array in the &lt;code&gt;useState&lt;/code&gt; variable &lt;code&gt;imageData&lt;/code&gt;, so why now are we trying to access something from &lt;code&gt;sortedImageData&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;This is where the important pieces of the puzzle come into play. Earlier we imported two additional modules - &lt;code&gt;useWindowSize&lt;/code&gt;, which is a custom hook, and &lt;code&gt;sortEveryNth&lt;/code&gt;, which is a JS function.&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%2Fi%2F39mca13nmjk9rexyvykj.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%2Fi%2F39mca13nmjk9rexyvykj.png" alt="Code: React function imports"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’ll start by taking a look at the &lt;code&gt;useWindowSize&lt;/code&gt; hook which is a custom hook with one important job to do - to listen out for any changes in our browser size and store that result in a state 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%2Fi%2Fadisjz8adpe792ynrqx3.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%2Fi%2Fadisjz8adpe792ynrqx3.png" alt="Code: useWindowSize react hook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The hook makes use of both the native &lt;code&gt;useLayoutEffect&lt;/code&gt; and &lt;code&gt;useState&lt;/code&gt; hooks, and essentially adds an event listener to the window which fires each time a &lt;code&gt;resize&lt;/code&gt; event occurs. This is the stored, and returned, as the constant size.  To have a look into &lt;code&gt;useLayoutEffect&lt;/code&gt; I recommend the &lt;a href="https://reactjs.org/docs/hooks-reference.html#uselayouteffect" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now we’ll take a look at the &lt;code&gt;sortEveryNth&lt;/code&gt; function and see how this all fits together.&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%2Fi%2Fcqzzchlopzexlilqkpjp.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%2Fi%2Fcqzzchlopzexlilqkpjp.png" alt="Code: sortEveryNth function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function takes in two parameters, an array (the one that we want sorted) and a single number.  This single number will reflect two things - the amount of columns we want to have in our gallery layout and, subsequently, the iteration count for the sorting algorithm.&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%2Fi%2F3bs3d1h7sjx726uvzqu7.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%2Fi%2F3bs3d1h7sjx726uvzqu7.png" alt="Code: useWindowSize import"&gt;&lt;/a&gt;&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%2Fi%2F1bskghgmyo1rjdejj4pt.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%2Fi%2F1bskghgmyo1rjdejj4pt.png" alt="Code: useEffect hook for handling state changes relating to the window event listener"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;width&lt;/code&gt; we are using within this &lt;code&gt;useEffect&lt;/code&gt; hook is the value that is being returned from the &lt;code&gt;useWindowSize&lt;/code&gt; we just created, and from this value it is calculating whether to change state at some arbitrary break points - in this case 1366px, 1024px, and 800px. &lt;/p&gt;

&lt;p&gt;Let’s say for example our browser width increases to, or is initially set at, 1400px. This fits into the first condition of the &lt;code&gt;if&lt;/code&gt; statement, being greater than 1366px. &lt;code&gt;setSortedImageData&lt;/code&gt; now calls the &lt;code&gt;sortEveryNth&lt;/code&gt; function and passes in the &lt;code&gt;imageData&lt;/code&gt; array to the first parameter, and the value of 4 as the second. The function now begins its work sorting the objects in the array by their index and returning a new array.&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%2Fi%2Fgcd7pw7vlnaohdfra9cn.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%2Fi%2Fgcd7pw7vlnaohdfra9cn.png" alt="A representation of how the function works on each element in the array"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As this image hopefully explains well, the function skips through each item by n, which is in this case 4, and pushes the object into the new array. Once this is complete, the new array, imaginatively named &lt;code&gt;newArr&lt;/code&gt;, is returned back to &lt;code&gt;setSortedImageData&lt;/code&gt; and consequently stored into &lt;code&gt;sortedImageData&lt;/code&gt;. And, after all of that, this is where we are mapping our data from, creating our &lt;code&gt;GalleryImage&lt;/code&gt; components and appending them onto  &lt;code&gt;GalleryWrapper&lt;/code&gt;. The &lt;code&gt;useEffect&lt;/code&gt; hook has both width and &lt;code&gt;imageData&lt;/code&gt; in its dependency array, and these are responsible for ensuring everything is re-rendered once any changes occur to the browser size.&lt;/p&gt;

&lt;p&gt;That’s essentially all of the heavy lifting out of the way. The last part to be put in place, to make sure everything works, is the CSS. I found that the use of &lt;code&gt;column-count&lt;/code&gt; gave both the best and most predictable results.&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%2Fi%2Fqw9c0lx15p2cj5cjzq23.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%2Fi%2Fqw9c0lx15p2cj5cjzq23.png" alt="Code: A styled-component showing the required CSS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s important to use media queries at the same breakpoints as you set in the &lt;code&gt;useEffect&lt;/code&gt; hook as these will work in unison to both lay out the page and calculate the sorting correctly. As you can see I actually started this desktop first - not intentionally, it was just how it happened.  And, as I mentioned before, any CSS will work here so don’t get hung up on how this looks outside of the CSS.&lt;/p&gt;

&lt;p&gt;And that’s it! I hope I was able to share something interesting with you here, and I’d really appreciate any feedback on either the content or the writing. This is my first ever post, and I’d like to do this more often and making it worthwhile would be a massive bonus.&lt;/p&gt;

&lt;p&gt;You can check out anything related to me or this project on my &lt;a href="https://martinwheelerweb.com" rel="noopener noreferrer"&gt;website&lt;/a&gt;&lt;/p&gt;

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