<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Persson Dennis RSS</title>
        <link>https://www.perssondennis.com</link>
        <description>RSS Feed for https://www.perssondennis.com</description>
        <lastBuildDate>Thu, 25 Dec 2025 19:21:24 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Persson Dennis RSS</title>
            <url>https://www.perssondennis.com/images/site/og-image.png</url>
            <link>https://www.perssondennis.com</link>
        </image>
        <copyright>All rights reserved 2025, PerssonDennis</copyright>
        <category>Web Development</category>
        <item>
            <title><![CDATA[10 Tips To Get More Readers on DEV]]></title>
            <link>https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev</link>
            <guid>https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev</guid>
            <pubDate>Mon, 04 Jul 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[10 tips to get more readers and followers on dev.to. Learn how to pin posts, how to make series and embed videos and Instagram posts on DEV.]]></description>
            <content:encoded><![CDATA[<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#1-pin-post-to-your-dev-profile">Pin Post to Your DEV Profile</a></li>
<li><a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#2-target-beginners-or-expert-readers">Target Beginners or Expert Readers</a></li>
<li><a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#3-syntax-highlighting-for-code-blocks">Syntax Highlighting for Code Blocks</a></li>
<li><a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#4-add-a-table-of-content-and-link-to-headings">Add a Table of Content and Link to Headings</a></li>
<li><a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#5-how-to-choose-markdown-editor-on-devto">How To Choose Markdown Editor on dev.to</a></li>
<li><a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#6-add-a-canonical-link-to-your-article-on-devto">Add a Canonical Link to Your Article on dev.to</a></li>
<li><a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#7-report-articles-if-someone-steals-them">Report Articles if Someone Steals Them</a></li>
<li><a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#8-how-to-make-series-on-devto">How To Make Series on dev.to</a></li>
<li><a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#9-how-to-embed-videos-and-instagram-posts-on-devto">How To Embed Videos and Instagram Posts on dev.to</a></li>
<li><a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#10-remind-the-reader-to-subscribe">Remind the Reader To Subscribe</a></li>
</ol>
<h2>1. Pin Post to Your DEV Profile</h2>
<p>You can pin articles to your profile page, it will pin <a href="https://dev.to/perssondennis#substories">above your other articles</a>. To do so, go to <a href="https://dev.to/dashboard">your dashboard</a> and click the <em>Manage</em> button beside the article you want to pin. You will find a <em>Pin to profile</em> button there.</p>
<p><img src="https://www.perssondennis.com/images/articles/10-tips-to-get-more-readers-on-dev/dev-pin-to-profile-button.webp" alt="Dev.to pin to profile button">
<em>Pin to profile is available under dashboard > manage</em></p>
<p>From now on, you can pin your most popular posts to attract clicks from curious profile page visitors.</p>
<h2>2. Target Beginners or Expert Readers</h2>
<p>While you're at the <em>Manage</em> page mentioned above, there are another valuable feature you can use. It allows you to target users with a certain experience level so your articles can be shown to the people who are most likely to appreciate it.</p>
<p>Note that they also have some useful tips on that page to help you reach out to more readers, such as sharing your articles to Reddit.</p>
<p><img src="https://www.perssondennis.com/images/articles/10-tips-to-get-more-readers-on-dev/dev-experience-level.webp" alt="Dev.to select experience level">
<em>There's always a target audience for your articles, make sure to specify it!</em></p>
<h2>3. Syntax Highlighting for Code Blocks</h2>
<p>Obviously, it's not unusual to post code on DEV, and DEV certainly supports syntax highlighting for different languages. Still, I once in a while see people posting code without syntax highlighting or posting images of code instead of using code blocks.</p>
<p>Neglecting syntax highlighting or using images for showing code is bad practice. This is because it's harder to read, difficult to copy-paste, and the browser can't scale the font size. Using an image also degrades performance and the code within the picture will not be searchable with <em>ctrl f</em> or on Google (text search).</p>
<p><img src="https://www.perssondennis.com/images/articles/10-tips-to-get-more-readers-on-dev/dev-syntax-highlighting.webp" alt="Dev.to syntax highlighting">
<em>With and without React syntax highlighting on DEV</em></p>
<p>To activate syntax highlighting, just specify which language the code consists of at the first line of the markdown code block. Available options include <em>react</em>, <em>javascript</em>, <em>markdown</em> etc.</p>
<p><img src="https://www.perssondennis.com/images/articles/10-tips-to-get-more-readers-on-dev/dev-syntax-highlighting-code.webp" alt="Dev.to syntax highlighting code">
<em>You can tell markdown to highlight the code block according to React syntax</em></p>
<h2>4. Add a Table of Content and Link to Headings</h2>
<p>Like many other sites, DEV supports anchored links (also known as hashtag links) which links to specific headings in your article, or even <a href="https://dev.to/perssondennis/how-to-report-a-site-that-steals-your-articles-5040#lets-go-to-the-court">another article</a>. Unfortunately, they don't seem to have a UI that allows us to copy the anchor link.</p>
<p>To get the anchor link, you have to inspect the heading element in the web inspector to find it (right click on the heading and choose <em>Inspect</em>). You will find a zero-width link with the hashtag suffix you append to your article's URL. It's basically a <a href="https://alok-verma6597.medium.com/case-styles-in-development-camel-pascal-snake-and-kebab-case-ed8e7b2497af#be85">kebab-cased</a> version of the heading preceded with a hashtag, so you don't really have to copy it from the inspector every time.</p>
<p><img src="https://www.perssondennis.com/images/articles/10-tips-to-get-more-readers-on-dev/dev-anchor-hashtag-link.webp" alt="Dev.to anchor hashtag link">
<em>You can find the anchor link in the chrome's elements inspector</em></p>
<p>You can utilize these anchor links in your DEV post to create a table of content like the one I have added at the top of this article. To do that, just add a regular link that refers to the anchor link for the heading you want to link to.</p>
<pre><code class="language-markdown">[Anchor link to "Add a Table of Content and Link to Headings"](#4-add-a-table-of-content-and-link-to-headings)
</code></pre>
<p>Anchor link above will output this link: <a href="https://www.perssondennis.com/articles/10-tips-to-get-more-readers-on-dev#4-add-a-table-of-content-and-link-to-headings">Add a Table of Content and Link to Headings</a>.</p>
<h2>5. How To Choose Markdown Editor on dev.to</h2>
<p>DEV has two different markdown editors. If you want to get rich on blogging, you need to choose the <em>Rich + markdown</em> editor. Just kidding, it doesn't ducking matter what you choose. But it can be good to know that they both exist, otherwise you may be confused when you google for something and the DEV UI doesn't look like in the guide you are looking at.</p>
<p>The two editors DEV offers are:</p>
<ul>
<li>Rich + markdown</li>
<li>Basic markdown</li>
</ul>
<p>If you don't know which to choose, just go for the rich one. The rich one contains some extra UI elements to choose tags and previewing your articles etc. With the basic markdown you have to specify title and tags etc. via Front Matter. You can find DEVs <a href="https://dev.to/p/editor_guide#front-matter">documentation for it here</a>.</p>
<p>To switch editor, go to your account settings, choose <em>Customization</em> and scroll down to the title <em>Writing</em>.</p>
<p><img src="https://www.perssondennis.com/images/articles/10-tips-to-get-more-readers-on-dev/dev-markdown-editors.webp" alt="Dev.to markdown editors">
<em>I said I was kidding, the rich one won't make you rich!</em></p>
<h2>6. Add a Canonical Link to Your Article on dev.to</h2>
<p>I'm sure a lot of you already know this, but I still mention it because it's quite hidden and definitely the single most important feature if you additionally publish your blog posts to your own blog or other blog portals.</p>
<p>Read about why it's so important for SEO (Search Engine Optimization) on <a href="https://ahrefs.com/blog/canonical-tags/">ahrefs site here</a>, I won't go into details, but what it does is to avoid Google punishing you for posting the same content at different places.</p>
<p>How to add canonical links differs dependent on which markdown editor you are using. If you are using the basic markdown editor, you can do as it says in the <a href="https://dev.to/p/editor_guide#front-matter">Front Matter guide</a>.</p>
<p><img src="https://www.perssondennis.com/images/articles/10-tips-to-get-more-readers-on-dev/dev-canonical-link.webp" alt="Dev.to specify canonical link">
<em>This is how you can specify a canonical link for a blog post</em></p>
<p>That also works for the rich markdown editor, but the rich markdown editor also allows you to specify a canonical link via UI. There's a discrete options button at the bottom of the create post page, beside the <em>Save draft</em> button, see the hexagon button in the image below.</p>
<p><img src="https://www.perssondennis.com/images/articles/10-tips-to-get-more-readers-on-dev/dev-canonical-link-and-series-options.webp" alt="Dev.to specify canonical link via rich markdown editor">
<em>This is how you can specify a canonical link for a blog post with the rich markdown editor</em></p>
<h2>7. Report Articles if Someone Steals Them</h2>
<p>Another quick tip related to the canonical link is to be quick to publish your articles on all sites at once if you publish it on multiple sites. If you wait too long with publishing your article someone may steal it and you can in worst case be banned from some blog portal for publishing articles that are available on other sites already.</p>
<p>Articles do get stolen a lot by <a href="https://dev.to/perssondennis/how-to-report-a-site-that-steals-your-articles-5040">automated sites</a>. If you detect that someone has stolen your blog article, you can read about what to do in <a href="https://www.perssondennis.com/articles/how-to-report-a-site-that-steals-your-articles">my guide here</a>.</p>
<h2>8. How To Make Series on dev.to</h2>
<p>You may have seen that some people create series at dev.to. You do that in the same way as you add a canonical link. If it is your first time adding a series, nothing will happen when you create your article since there's only one article in the series.</p>
<p>Next time you create a new blog article you will see your previously series listed. When you choose an existing series, a series component will be added to all blog articles in that series. It will look as in the image below.</p>
<p><img src="https://www.perssondennis.com/images/articles/10-tips-to-get-more-readers-on-dev/dev-create-a-series.webp" alt="Dev.to create a series">
<em>This is how a series are presented at DEV</em></p>
<h2>9. How To Embed Videos and Instagram Posts on dev.to</h2>
<p>Not very many people embed videos in their DEV posts, but it is doable by using <a href="https://shopify.github.io/liquid/">liquid tags</a>. You have <a href="https://dev.to/p/editor_guide#liquidtags">DEVs docs for it here</a>.</p>
<p>A YouTube video can be embedded either with the <em>embed</em> keyword or <em>youtube</em> keyword.</p>
<pre><code class="language-markdown">{% youtube 9Xd8xq06FCw %}

{% embed https://www.youtube.com/watch?v=9Xd8xq06FCw %}
</code></pre>
<p>Why you should add a video? Well, if you have some video that would need some attention it can be a good idea to include it in your DEV article. I'm sure you also can find good educational or funny movies to add to you blog post as well. Or why not embed on of your Instagram posts? The id to use in the embedded Instagram liquid tag is the last part of the URL to the post.</p>
<pre><code class="language-markdown">// Embed Instagram blog post by adding the post's id.
// Below embedding will embed the url "https://www.instagram.com/p/CfRzNd3seAC/"

{% instagram CfRzNd3seAC %}
</code></pre>
<h2>10. Remind the Reader To Subscribe</h2>
<p>Last but not least. Ensure that people know that your article is available on <a href="https://www.perssondennis.com/">your blog</a> and remind them to hit the like button and make a comment. This can be of course be interpreted as advertising, but in my opinion, it's a fair thing to do.</p>
<p>If you article is inspiring, the reader may get a lot of ideas and eagerly start processing thoughts and making plans. How cheerful the reader ever will be, he or she is not in an optimal condition for remembering to click with his finger on a heart or unicorn icon on a screen. And let's be honest, who will know you have your own website and try to find it if you don't link to it? Most (sane) people don't play hide and seek with strangers over the internet.</p>
<h2>Bonus: Add a Summary</h2>
<p>People have their own life to life, as stressful just as yours may be. Give them a chance to read through your article hastily. Here's my summary. A simple list of the tips, even if people will miss all details about how to do these things if they don't read the whole article.</p>
<ol>
<li>Pin posts to your profile to promote your most popular articles.</li>
<li>DEV to supports targeting beginner or expert readers when managing an article.</li>
<li>Use syntax highlight for code blocks, never use an image to show code.</li>
<li>A table of content with anchor links to headings give a good overview.</li>
<li>You can choose either markdown editor, just be aware that dev.to has two of them.</li>
<li>Always add a canonical tag if you post your article to multiple websites.</li>
<li>Don't wait to post articles on multiple websites, they may be <a href="https://www.perssondennis.com/articles/how-to-report-a-site-that-steals-your-articles">stolen</a>.</li>
<li>DEV supports adding series, a good way to get people to read your old articles.</li>
<li>You can embed YouTube videos and other media in your article.</li>
<li>Remind people to subscribe and hit the like button!</li>
</ol>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Productivity</category>
            <enclosure url="https://www.perssondennis.com/assets/blog/default-article-image-unknown.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[21 Fantastic React Design Patterns and When to Use Them]]></title>
            <link>https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them</link>
            <guid>https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them</guid>
            <pubDate>Sun, 24 Aug 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[21 React design patterns and principles for better code architecture and tips to make React apps more maintainable and scalable. ✓ React ✓ Design Patterns]]></description>
            <content:encoded><![CDATA[<p>Design patterns aren't just for backend developers who can't say a sentence without mentioning architecture or code quality. Frontend developers can benefit from them too, especially in React where component composition and hooks provide perfect opportunities to implement solid React design patterns and improve code architecture.</p>
<p>This article covers 21 design patterns and principles that will make your React code more maintainable, testable, and scalable. Each pattern includes a brief explanation and practical examples of when and how to use them.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#core-design-patterns-in-react">Core Design Patterns in React</a>
<ul>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#component-composition-pattern">Component Composition Pattern</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#custom-hook-pattern">Custom Hook Pattern</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#control-props-pattern">Control Props Pattern</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#provider-pattern">Provider Pattern</a></li>
</ul>
</li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#common-react-design-patterns">Common React Design Patterns</a>
<ul>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#container-presentational-pattern">Container Presentational Pattern</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#compound-components-pattern">Compound Components Pattern</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#headless-components">Headless Components</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#atomic-design-pattern">Atomic Design Pattern</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#error-boundary-pattern">Error Boundary Pattern</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#portal-pattern">Portal Pattern</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#render-props-pattern">Render Props Pattern</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#props-getters-pattern">Props Getters Pattern</a></li>
</ul>
</li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#legacy-patterns">Legacy Patterns</a>
<ul>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#higher-order-components-pattern-hoc">Higher Order Components Pattern (HOC)</a></li>
</ul>
</li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#general-patterns">General Patterns</a>
<ul>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#dry-principle">DRY Principle</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#solid-principles">SOLID Principles</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#dependency-injection">Dependency Injection</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#separation-of-concerns-soc">Separation of Concerns (SoC)</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#mvvm">MVVM</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#stable-dependency-principle-sdp">Stable Dependency Principle (SDP)</a></li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#kiss-principle">KISS Principle</a></li>
</ul>
</li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#design-patterns-to-avoid">Design Patterns to Avoid</a>
<ul>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#clean-architecture">Clean Architecture</a></li>
</ul>
</li>
<li><a href="https://www.perssondennis.com/articles/21-fantastic-react-design-patterns-and-when-to-use-them#note-about-modern-react-patterns-and-frameworks">Note About Modern React Patterns and Frameworks</a></li>
</ul>
<h2>Core Design Patterns in React</h2>
<p>These are the fundamental React design patterns that React is built upon. If you're writing React code, you're probably already using these patterns whether you know it or not. Sometimes we do good things even if we haven't read the book. These patterns form the bedrock of everything we build and are essential React best practices.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/code-by-the-book.webp" alt="Code by the book">
<em>Lintlemore always codes by the book</em></p>
<h3>Component Composition Pattern</h3>
<p>Component composition is the very foundational React design pattern. It's the main way of thinking when writing React components, which is the very first design pattern you should read about when starting with React.</p>
<p>What the design pattern says is that an application is not a big monolith, it's a composition of tens or hundreds of components working together to form an application. Each component has its own reason to exist and can use, or be used by, one or several other components.</p>
<p>A component in this matter is essentially the same as a React component. Either a small leaf component in the component tree like a button, or a high-level component such as a whole page.</p>
<p>There are plenty of articles about component composition to find on Google and by GPTs, so I will not go into details here. But we will see in this article that a lot of the React design patterns serve their part to adhere to this pattern, where the Atomic Design Pattern might be the most obvious one. Every developer begins their journey with this fundamental pattern.</p>
<p><strong>When to use:</strong> Always. This is the foundation of React development. I have sometimes seen React projects which barely use components and instead have a few large page-wide components. Doing that is to abuse React...</p>
<h3>Custom Hook Pattern</h3>
<p>If you have touched React, you probably have written some custom hooks. Doing that, means you are following the custom hook pattern, one of the most essential React best practices. If you aren't doing that, you are not writing proper React code.</p>
<p>Custom Hook Pattern means to lift out and encapsulate logic such as useEffects and useStates into custom hooks to abstract away the React logic in favor of readable hooks.</p>
<p>Too many React developers keep too much logic in their components, resulting in duplicated code, higher maintenance costs, and complex test cases. Following React best practices means separating concerns properly. The time it takes to break out logic from a component into a hook will almost certainly always save time.</p>
<p>Look at the component below, which fetches data from an API and renders it. It takes a brief moment to read it and understand it.</p>
<pre><code class="language-javascript">const PostsComponent = () => {
  const [posts, setPosts] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)

  useEffect(() => {
    const fetchPosts = async () => {
      try {
        const response = await fetch('/api/posts')
        const data = await response.json()
        setPosts(data)
      } catch (err) {
        setError(err)
      } finally {
        setLoading(false)
      }
    }

    fetchPosts()
  }, [])

  if (loading) return &#x3C;div>Loading...&#x3C;/div>
  if (error) return &#x3C;div>{error.message}&#x3C;/div>
  if (!posts) return null

  return (
    &#x3C;div>
      {posts.map(post => (
        &#x3C;div key={post.id}>{post.title}&#x3C;/div>
      ))}
    &#x3C;/div>
  )
}
</code></pre>
<p>Now look at the same component below, but where the logic in the component has been lifted out to a hook.</p>
<pre><code class="language-javascript">// The hook's logic is easy to test
const usePosts = () => {
  const [posts, setPosts] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)

  useEffect(() => {
    const fetchPosts = async () => {
      try {
        const response = await fetch('/api/posts')
        const data = await response.json()
        setPosts(data)
      } catch (err) {
        setError(err)
      } finally {
        setLoading(false)
      }
    }

    fetchPosts()
  }, [])

  return { posts, loading, error }
}

// Main component is much easier to read
const PostsComponent = () => {
  const { posts, loading, error } = usePosts()

  if (loading) return &#x3C;div>Loading...&#x3C;/div>
  if (error) return &#x3C;div>{error.message}&#x3C;/div>
  if (!posts) return null

  return (
    &#x3C;div>
      {posts.map(post => (
        &#x3C;div key={post.id}>{post.title}&#x3C;/div>
      ))}
    &#x3C;/div>
  )
}
</code></pre>
<p>Of course, it contains the same code. Except, this time, the usePosts hook name hints about what the useEffect and three useStates do, which made it a bit quicker to read.</p>
<p>And next time you re-use the usePosts hook for another component, you don't even have to read or write the code in that hook again.</p>
<p>At the same time, you now have a reusable hook which you only have to test once, and which is actually also very easy to test since it's a pure hook without any reason to check for what is being rendered.</p>
<p>If you test your UI components, the PostsComponent component might also need to be tested, and when doing that, you can simply mock the response of the usePosts hook instead of mocking the internals of the usePosts hook, such as the axios request, meaning that even the component test is now easier to write.</p>
<p><strong>When to use:</strong> When you have reusable logic that multiple components need, or when your component is getting too complex. Potentially as a pattern to lift out logic from any component. Custom hooks is one of the most important concepts in React for maintainable code.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/hooktail-spinoff.webp" alt="Hooktail spinoff">
<em>Some say the custom hook pattern originated from the Hooktail spinoff</em></p>
<h3>Control Props Pattern</h3>
<p>Props are passed to components all the time in React, that cannot be avoided. The Control Props Pattern is about whether your components are controlled or uncontrolled, which allows you to choose between passing more props or to have self-controlled components which work on their own using less props.</p>
<p>If a component has a state, it will need to be either controlled or uncontrolled, or both. It's more tricky to allow both - you will see it in UI component libraries and maybe write some of your own, but most of your own components will either be controlled or uncontrolled.</p>
<pre><code class="language-javascript">// Uncontrolled - manages its own state
const UncontrolledInput = () => {
  const [value, setValue] = useState('')
  
  return (
    &#x3C;input 
      value={value} 
      onChange={(e) => setValue(e.target.value)} 
    />
  )
}

// Controlled - state managed by parent
const ControlledInput = ({ value, onChange }) => {
  return (
    &#x3C;input 
      value={value} 
      onChange={onChange} 
    />
  )
}
</code></pre>
<p>Personally I prefer controlled components most often because uncontrolled ones are not as modular and reusable, since they are more difficult to override.</p>
<p>Remember the O in SOLID - components should not have to be modified, but be extendable. Uncontrolled components don't follow that pattern very well.</p>
<p>There are different arguments about what to use out there though. Uncontrolled components look nice and allow you to reuse the code within the component, but it might mean you need to write a new similar component instead of reusing the existing one, or modifying it for future needs.</p>
<p><strong>When to use:</strong> When you need to control component state from a parent. For instance, if you have a form and need to read or modify fields in it, or if you have a context menu, dropdown menu or similar which you need to close programmatically from its outside.</p>
<h3>Provider Pattern</h3>
<p>The Provider Pattern is basically what React Contexts and useContext are. It's used in most major libraries to handle things like theming, routing, and global state management.</p>
<p>This is one of the most common React patterns for sharing state across components.</p>
<pre><code class="language-javascript">const ThemeContext = createContext()

// Provides the theme
const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState('light')
  
  return (
    &#x3C;ThemeContext.Provider 
      value={{ theme, setTheme }}
    >
      {children}
    &#x3C;/ThemeContext.Provider>
  )
}

// Hook to use the theme
const useTheme = () => {
  const context = useContext(ThemeContext)

  if (!context) {
    throw new Error('useTheme must be used within ThemeProvider')
  }

  return context
}

// To provide the theme to the app
const App = () => {
  return &#x3C;ThemeProvider>
    &#x3C;AppContent />
  &#x3C;/ThemeProvider>
}
</code></pre>
<p>This pattern is everywhere in React development. React Router uses it for navigation context, styled-components uses it for themes, and Redux uses it for global state.</p>
<p>You will definitely use this pattern, mostly through libraries, but most apps also benefit from having a few custom-made ones.</p>
<p><strong>Important caveat:</strong> Contexts are not for global state management, they'll create unnecessary re-renders. Use Zustand, Redux, or Jotai for proper state management instead. Neither should you overuse them as a standard dependency injection system.</p>
<p><strong>When to use:</strong> When you need to share data for a component sub-tree without prop drilling, or when using third-party libraries that require context providers. Most common use case is to centralize app-wide configurations which rarely changes (themes, i18n, auth etc.).</p>
<h2>Common React Design Patterns</h2>
<p>These patterns are very often seen in React applications, but they're used as architectural choices rather than fundamental requirements. They are all widely used design patterns for building scalable React applications and improving code maintainability.</p>
<h3>Container Presentational Pattern</h3>
<p>Also called the Container Component Pattern, this separates your components into two categories: containers that handle logic and data, and presentational components that only take props and render them.</p>
<p>Container presentational pattern is probably the most common React design pattern for separating concerns.</p>
<pre><code class="language-javascript">// Presentational - only renders
const UserList = ({ users, onUserClick }) => (
  &#x3C;div>
    {users.map(user => (
      &#x3C;div 
        key={user.id} 
        onClick={() => onUserClick(user)}
      >
        {user.name}
      &#x3C;/div>
    ))}
  &#x3C;/div>
)

// Container - handles logic and data
const UserListContainer = () => {
  const { users } = useUsers()
  const navigate = useNavigate()

  const handleUserClick = (user) => {
    navigate(`/users/${user.id}`)
  }

  return &#x3C;UserList 
    users={users} 
    onUserClick={handleUserClick} />
}
</code></pre>
<p>The presentational component is often stateless and reusable, while the container handles connections to other parts of the application, navigation, React contexts, and networking.</p>
<p>This pattern helps you control which components are responsible for fetching data and doing navigation, and which components you can freely reuse anywhere in your application.</p>
<p>Some might think that hooks like TanStack Query and SWR have made this pattern redundant, but it still solves important issues like the Single Responsibility Principle.</p>
<p><strong>When to use:</strong> You would probably most often want to have this pattern in mind. You don't necessarily need to follow it strictly, but you want some pattern to separate your business logic from the UI and to build reusable components. This is the standard way to do that, along with the custom hook pattern.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/intelliton-and-glimmabelle.webp" alt="Intelliton and Glimmabelle">
<em>Intelliton &#x26; Glimmabelle are for some difficult to tell apart, but one is all beauty and the other one all brain</em></p>
<h3>Compound Components Pattern</h3>
<p>If you are using a UI component library in React, chances are high that you will come across the Compound Components Pattern. This pattern can easily be confused with the Component Composition Pattern because of their similarities in name and purpose. They are not the same though.</p>
<p>While the Component Composition Pattern explains how to divide and conquer an application into smaller components, the Compound Components Pattern explains how to allow a set of components to work together as if they were a single component.</p>
<pre><code class="language-javascript">// Normal modal component
&#x3C;Modal 
  isOpen={isOpen}
  title="Delete User"
  body="Are you sure you want to delete this user?"
  onConfirm={handleDelete}
  onCancel={handleCancel}
  confirmText="Delete"
  cancelText="Cancel"
/>

// Modal consisting of compound components
&#x3C;Modal isOpen={isOpen}>
  &#x3C;Modal.Header>Delete User&#x3C;/Modal.Header>
  &#x3C;Modal.Body>
    Are you sure you want to delete this user?
  &#x3C;/Modal.Body>
  &#x3C;Modal.Footer>
    &#x3C;Button onClick={handleCancel}>Cancel&#x3C;/Button>
    &#x3C;Button onClick={handleDelete}>Delete&#x3C;/Button>
  &#x3C;/Modal.Footer>
&#x3C;/Modal>
</code></pre>
<p>This pattern is mainly a way of solving the issues of prop drilling and the need for adding React contexts to share data between components that need to work together. As a bonus, it comes with great readability.</p>
<p>The main idea is that multiple components work together to achieve the functionality of a single entity.</p>
<p><strong>When to use:</strong> It's great when building complex, flexible UI components that are highly customizable and where the components share a common state. Although it's a bit opinionated pattern, it's a design pattern that works well for component libraries. Can be a bit tricky to set up, but on the other hand, it's nice if some component lib owner has already implemented it for you.</p>
<h3>Headless Components</h3>
<p>Headless components pattern is used in some UI component libraries like Radix UI and Ark UI, they provide complex logic without any styling, leaving the visual presentation completely up to you.</p>
<p>This is one of the modern React design patterns that separates logic from presentation.</p>
<pre><code class="language-javascript">// Headless component of pure logic
const useDropdown = () => {
  const [isOpen, setIsOpen] = useState(false)
  const [selectedIndex, setSelectedIndex] = useState(-1)

  const toggleDropdown = () => setIsOpen(!isOpen)
  
  const selectItem = (index) => {
    setSelectedIndex(index)
    setIsOpen(false) 
  }

  return { 
    isOpen, 
    selectedIndex, 
    toggleDropdown, 
    selectItem 
  }
}

// Stylig is handled by the consumer
const Dropdown = () => {
  const { 
    isOpen, selectedIndex, 
    toggleDropdown, selectItem 
  } = useDropdown()

  return (
    &#x3C;div className="dropdown">
      &#x3C;button onClick={toggleDropdown}>
        {selectedIndex >= 0 
          ? `Item ${selectedIndex + 1}` 
          : 'Select an item'
        }
      &#x3C;/button>
      
      {isOpen &#x26;&#x26; (
        &#x3C;ul className="menu">
          &#x3C;li 
            className="menu-item" 
            onClick={() => selectItem(0)}
          >
            Item 1
          &#x3C;/li>
          &#x3C;li 
            className="menu-item" 
            onClick={() => selectItem(1)}
          >
            Item 2
          &#x3C;/li>
        &#x3C;/ul>
      )}
    &#x3C;/div>
  )
}
</code></pre>
<p>This pattern is perfect for those who are skeptical about choosing a UI library to lock into, because it will give you support for complex components which are cumbersome to write yourself without locking you into a specific style and look.</p>
<p>Headless components give you full control over styling and separate the concerns of UI logic and UI styling. It suits React very well, since hooks are mainly for logic and JSX for UI.</p>
<p><strong>When to use:</strong> When you need complex component logic but want complete control over styling, or when building component libraries that need to be framework agnostic. If you like to follow best practices and build a React architecture that scales, this design pattern is for you.</p>
<p><strong>When not to use:</strong> Don't over-engineer simple components with headless patterns. This pattern is for more logically complex components. It's completely unnecessary for a simple button or switch toggle.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/bareboneux.webp" alt="Bareboneux">
<em>Bareboneux lives its life inside its shell, it doesn't care if you would paint it pink or poke one of its spikes</em></p>
<h3>Atomic Design Pattern</h3>
<p>The Atomic Design Pattern is one of the newer kids on the block, inspired by chemistry, probably because web development wasn't complicated enough already.</p>
<p>It's a pattern for creating design systems that organizes components into a clear hierarchy: atoms, molecules, organisms, templates, and pages. This design pattern is both easy to understand and also very scalable.</p>
<p>You start with the smallest pieces (atoms), combine them into slightly larger pieces (molecules), then build complex structures (organisms), and finally create complete layouts (templates and pages).</p>
<pre><code class="language-javascript">// Atoms - basic building blocks
const Button = ({ children, onClick }) => (
  &#x3C;button className="btn" onClick={onClick}>{children}&#x3C;/button>
)

const Input = ({ value = '' }) => (
  &#x3C;input className="input" value={value} />
)

// Molecules - combinations of atoms
const SearchBox = ({ searchText, onSearch }) => (
  &#x3C;div className="search-box">
    &#x3C;Input value={searchText} />
    &#x3C;Button onClick={onSearch}>Search&#x3C;/Button>
  &#x3C;/div>
)

// Organisms - complex UI components
const Header = () => (
  &#x3C;header className="header">
    &#x3C;Logo />
    &#x3C;SearchBox onSearch={handleSearch} />
    &#x3C;Navigation />
  &#x3C;/header>
)

// Templates &#x26; Pages - full layouts
const HomePage = () => (
  &#x3C;div>
    &#x3C;Header />
    &#x3C;main>
      &#x3C;HeroSection />
      &#x3C;SomeContent />
    &#x3C;/main>
    &#x3C;Footer />
  &#x3C;/div>
)
</code></pre>
<p>This pattern helps you think systematically about your UI components and creates a clear hierarchy that's easy to understand and maintain. It's particularly useful for larger applications where you need consistency across different parts of the UI.</p>
<p>The key insight is that by organizing components this way, you can ensure that your design system is both consistent and scalable. Atoms are reused everywhere, molecules combine atoms in meaningful ways, and organisms create complex but reusable UI sections.</p>
<p>Just don't get too carried away with the chemistry metaphor. Your components don't need to have atomic numbers, and you definitely don't need to create a periodic table of UI elements (though I've seen it attempted).</p>
<p><strong>When to use:</strong> When building large applications that need a consistent design system, or when working with teams that need clear component organization guidelines. I would recommend having this mindset even if you don't officially follow it. It's one of the React design patterns that works well for React applications which need a scalable design system.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/atomunculus.webp" alt="Atomunculus">
<em>Don't be fooled by Atomunculus's size; even a black hole looks insignificant from the outside</em></p>
<h3>Error Boundary Pattern</h3>
<p>Ever had that moment where one tiny bug in your React app brings down the entire application? One component throws an error, and suddenly your users are staring at a blank screen wondering if the internet broke.</p>
<p>This is exactly the problem error boundaries solve. They're React's way of catching JavaScript errors anywhere in the component tree and preventing the entire app from crashing.</p>
<p>An error boundary would look something like this, or if you use any of the hook libraries for it.</p>
<pre><code class="language-javascript">class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props)
    this.state = { hasError: false }
  }

  static getDerivedStateFromError(error) {
    return { hasError: true }
  }

  componentDidCatch(error, errorInfo) {
    console.error('Error caught by boundary:', error, errorInfo)
  }

  render() {
    if (this.state.hasError) {
      return (
        &#x3C;div className="error-boundary">
          &#x3C;h2>Something went wrong&#x3C;/h2>
          &#x3C;button onClick={() => this.setState({ hasError: false })}>
            Try again
          &#x3C;/button>
        &#x3C;/div>
      )
    }

    return this.props.children
  }
}

const App = () => (
  &#x3C;ErrorBoundary>
    &#x3C;UserProfile />
    &#x3C;ProductList />
  &#x3C;/ErrorBoundary>
)
</code></pre>
<p>Error boundaries only catch errors in the components below them in the tree. They don't catch errors in:</p>
<ul>
<li>Event handlers (use try-catch instead)</li>
<li>Async code like setTimeout and promises</li>
<li>Server-side rendering</li>
<li>Code that runs outside the component tree</li>
</ul>
<p>For these cases, you'll need try-catch blocks or other error handling strategies.</p>
<p>The key insight is to place error boundaries strategically around parts of your app that could fail independently. You might have one around your main app, another around the user dashboard, and another around some interactive AI chat.</p>
<p><strong>When to use:</strong> A pattern which should be used more than it is. Most applications I have seen don't really use error boundaries, but they do serve their purpose to build stable applications. They are perfect safe-guards for applications which has several independent features to ensure that the whole app doesn't crash just because one of the features fails.</p>
<h3>Portal Pattern</h3>
<p>You aren't a real frontend developer if you haven't built a context menu or dropdown that got clipped by its parent container, or struggled with z-index issues where a modal appears behind other elements.</p>
<p>This is the problem portals solve. They provide a way to render children into a DOM node that exists outside the parent component's DOM hierarchy. It's a magic door that lets your UI elements escape their container and appear exactly where you want them.</p>
<pre><code class="language-javascript">import { createPortal } from 'react-dom'

const Modal = ({ isOpen, onClose, children }) => {
  if (!isOpen) return null

  return createPortal(
    &#x3C;div 
      className="modal-overlay" 
      onClick={onClose}
    >
      &#x3C;div 
        className="modal-content" 
        onClick={(e) => e.stopPropagation()}
      >
        &#x3C;button 
          className="modal-close" 
          onClick={onClose}
        >×&#x3C;/button>
        {children}
      &#x3C;/div>
    &#x3C;/div>,
    document.body
  )
}

const App = () => {
  const [isModalOpen, setIsModalOpen] = useState(false)

  return (
    &#x3C;div>
      &#x3C;button 
        onClick={() => setIsModalOpen(true)}
      >Open Modal&#x3C;/button>
        
      &#x3C;Modal 
        isOpen={isModalOpen} 
        onClose={() => setIsModalOpen(false)}
      >
        &#x3C;h2>Modal Content&#x3C;/h2>
        &#x3C;p>Rendered in body, not in parent&#x3C;/p>
      &#x3C;/Modal>
    &#x3C;/div>
  )
}
</code></pre>
<p>Portals are particularly useful when you need to render content that should appear above everything else, like modals or notifications. They solve CSS z-index issues and ensure your modal doesn't get clipped by parent containers with overflow: hidden.</p>
<p>The pattern is also useful for tooltips and dropdowns that need to break out of their parent's overflow constraints. Just remember that even though the DOM node is different, the React event bubbling still works as expected.</p>
<p>The alternative to using a portal would be to fiddle with z-indexes and their stacking contexts. And honestly, most web developers don't really know how stacking contexts work for z-indexes, which is why these kinds of issues are severely common.</p>
<p><strong>When to use:</strong> When building modals, tooltips, context menus, dropdowns, etc. which need to escape their parent container's CSS constraints. It's one of the common React patterns for building overlays and popups. If you see your component being cut-off with a z-index issue the portal might the solution.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/voidnibbler.webp" alt="Voidnibbler">
<em>If you use portals frequently, you might one day spot the Voidnibbler, but no one would believe you</em></p>
<h3>Render Props Pattern</h3>
<p>The Render Props Pattern is where you pass a function as a prop that returns JSX. You will use it, otherwise you are probably overusing other design patterns like the Compound Components Pattern.</p>
<p>It feels kinda ugly at first, but it's completely normal and quite powerful.</p>
<pre><code class="language-javascript">const TodosFetcher = ({ url, render }) => {
  const [todos, setTodos] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        setTodos(data)
        setLoading(false)
      })
  }, [url])

  return render({ todos, loading })
}

const App = () => (
  &#x3C;TodosFetcher 
    url="/api/todos" 
    render={({ todos, loading }) => (
      loading 
        ? &#x3C;div>Loading...&#x3C;/div> 
        : (
          &#x3C;div>
            {todos.map(todo => (
              &#x3C;div key={todo.id}>{todo.name}&#x3C;/div>
            ))}
          &#x3C;/div>
        )
    )}
  />
)
</code></pre>
<p>The pattern allows you to share code between components while giving consumers control over what to render. It's particularly useful when you have complex logic that needs to be shared but the UI might vary.</p>
<p>In reality, the App component code would be created with its own components utilizing proper component composition:</p>
<pre><code class="language-javascript">const LoadingSpinner = () => &#x3C;div>Loading...&#x3C;/div>

const TodoList = ({ todos }) => (
  &#x3C;div>
    {todos.map(todo => (
      &#x3C;div key={todo.id}>{todo.name}&#x3C;/div>
    ))}
  &#x3C;/div>
)

const App = () => (
  &#x3C;TodosFetcher
    url="/api/todos" 
    render={({ todos, loading }) => (
      loading 
        ? &#x3C;LoadingSpinner /> 
        : &#x3C;TodoList todos={todos} />
    )}
  />
)
</code></pre>
<p>This example shows how the render props pattern works beautifully with component composition. Each UI concern (loading, data display) is its own focused component, making the code much more readable and maintainable.</p>
<p>While you could put all these components in the same file as your App component, it's better practice to place them in their own files for better organization and reusability.</p>
<p><strong>When to use:</strong> If you prefer to use it. Custom hooks and compound components and props getter pattern have many times replaced this pattern, but it still has its use cases.</p>
<h3>Props Getters Pattern</h3>
<p>The Props getters pattern is similar to the render props pattern we just read about. Instead of passing a function which renders UI components you use a function to provide the props a component needs.</p>
<p>You'll see this pattern in libraries like React Hook Form, where instead of manually setting up all the form props, you get functions that return perfectly configured prop objects.</p>
<pre><code class="language-javascript">const useToggle = (initialValue = false) => {
  const [on, setOn] = useState(initialValue)

  const toggle = () => setOn(!on)

  const getTogglerProps = (props = {}) => ({
    onClick: toggle,
    'aria-pressed': on,
    ...props
  })

  const getIndicatorProps = (props = {}) => ({
    children: on ? 'On' : 'Off',
    ...props
  })

  return { on, toggle, getTogglerProps, getIndicatorProps }
}

const Toggle = () => {
  const { on, getTogglerProps, getIndicatorProps } = useToggle()

  return (
    &#x3C;div>
      &#x3C;button {...getTogglerProps()}>
        Toggle
      &#x3C;/button>
      &#x3C;div {...getIndicatorProps()} />
    &#x3C;/div>
  )
}
</code></pre>
<p>As you can see, we have use a hook which provides us with the data we need instead of a component as we had with the TodosFetcher. We have also baked in some props getters in that hook which return the props we commonly would use together with our data.</p>
<p>If we would want to, we can easily override the properties, but most often we can trivially use the prop getter function as is to get the props we need for our UI elements.</p>
<p>This is particularly useful when you have complex components that need to manage multiple related props. Instead of the consumer having to know about all the internal state and configuration, they just call the appropriate getter function and get exactly what they need.</p>
<p><strong>When to use:</strong> When building reusable components that need to manage complex prop configurations and accessibility attributes. Not seen too often, but kinda useful.</p>
<h2>Legacy Patterns</h2>
<p>Some patterns were used extensively in React in the past, but have been phased out by time and passed on the torch to other patterns.</p>
<p>It doesn't mean they are anti-patterns, but their best before dates have been reached already.</p>
<h3>Higher Order Components Pattern (HOC)</h3>
<p>The HOC pattern is the old way of lifting out reusable code in React, it was one of the most fundamental design pattern for React for quite a while.</p>
<p>It was mainly used with the old class components before the functional components came with hooks. It did live on for a while after the hooks came, but is more rarely seen today.</p>
<p>A typical example of a HOC would be a withAuth hook, which injects a user into a component.</p>
<pre><code class="language-javascript">const withAuth = (Component) => {
  return (props) => {
    const { user } = useContext(AuthContext)

    if (!user) {
      return &#x3C;LoginComponent />
    }

    return &#x3C;Component {...props} user={user} />
  }
}

const Profile = ({ user }) => {
  return &#x3C;div>Welcome, {user.name}!&#x3C;/div>
}

// withAuth provides the user to Profile component
const ProfileWithAuth = withAuth(Profile)
</code></pre>
<p>Today, this hook would most often instead be a custom hook, looking like this. It's a bit more readable and also easier to test.</p>
<pre><code class="language-javascript">const useAuth = () => {
  const { user } = useContext(AuthContext)

  if (!user) {
    // Redirect to login
  }

  return { user }
}

const Profile = () => { 
  const { user } = useAuth()
  return &#x3C;div>Welcome, {user.name}!&#x3C;/div>
}
</code></pre>
<p><strong>When to use:</strong> Legacy pattern - prefer custom hooks instead. Only use when working with older codebases or class components that can't be easily converted.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/overcloak.webp" alt="Overcloak">
<em>Overcloak is from an old time, from an era all apprentices obeyed him</em></p>
<h2>General Patterns</h2>
<p>These patterns are less commonly discussed together with React, but very often discussed among backend developers, who we know usually cannot say a sentence without mentioning design patterns, architecture, or code quality.</p>
<p>However, it definitely doesn't mean that you shouldn't care about these. If you already know React well, these are probably the most important patterns to read about to become a better React developer.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/perfect-architecture-meme.webp" alt="Perfect architecture meme">
<em>Would it be a good time to tell him the project was cancelled two months ago?</em></p>
<h3>DRY Principle</h3>
<p>This principle is more nuanced than most developers realize - it's not a black or white pattern you can generally deem to be good or bad. While DRY is many times good, over-applying it can create more problems than it solves.</p>
<p>Some clear candidates for DRY implementation include atomic components like buttons, inputs, and icons that get reused everywhere. Utility functions such as formatters, validators, and helpers are also perfect since they're pure functions that solve common problems. API integration logic when you're making the same requests in multiple places, and complex state management when multiple components need identical state logic.</p>
<p>But be cautious using this pattern with code which might diverge. I've seen codebases that became impossible to navigate because developers created layers upon layers of abstraction for code that was only used once. Simple solutions became incomprehensible mazes of interfaces, factories, and abstract base classes for the only reason to potentially be able to save a few duplicated lines in the future.</p>
<p>The key insight is that DRY should be applied thoughtfully, not religiously. Sometimes duplication is actually cheaper than the wrong abstraction. It's often easier to extract common patterns later when you have 2-4 similar implementations than to guess what the abstraction should look like upfront.</p>
<p>Modern development tools also change the equation. With AI-powered code completion and refactoring tools, eliminating duplication might literally be one prompt away. This means the cost of both creating and maintaining DRY code has decreased significantly.</p>
<p><strong>When to use:</strong> When you have truly identical logic that is used in multiple places and unlikely to diverge, or when building reusable utility functions and components. The core of the app should be kept as DRY as possible, while the outer top layer of the application is perfectly fine if it's WET. You are very likely to change that code any day.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/deduplica.webp" alt="Deduplica">
<em>Deduplica would probably benefit from a slightly more WET environment</em></p>
<h3>SOLID Principles</h3>
<p>The SOLID principles are fundamental design patterns that apply beautifully to React development. While they're often discussed in backend contexts, they're incredibly valuable for building maintainable React applications.</p>
<h4>Single Responsibility Principle (SRP)</h4>
<p>Each component and hook should have one clear responsibility. Developers violate this principle constantly when they fetch data, handle validations, manage state, perform calculations, and render complex UI all in a single massive component.</p>
<p>Components like that are impossible to test, difficult to reuse, and a nightmare to debug. The Container Component Pattern and custom hooks are your best friends for solving SRP violations.</p>
<p><strong>When to use:</strong> Always. This is the foundation of clean, maintainable React code. Break down complex components into smaller, focused pieces.</p>
<h4>Open/Closed Principle (OCP)</h4>
<p>Components should be open for extension but closed for modification. This sounds fancy, but it's actually quite simple - you want to be able to add new features without breaking existing code.</p>
<p>React's component composition model can help with this if we design our components appropriately. The key is to follow two simple rules:</p>
<ul>
<li>Prefer to compose multiple small components over building large monolith-components</li>
<li>Make commonly used components configurable through props</li>
</ul>
<p>An example of the second rule could be a component for a delete button. That's a normal button which might be red and have a "Delete" text on it. You wouldn't hardcode its text or color in the button, rather you would pass a text and type prop to it so you can reuse the same button as a cancel or OK button without having to update the button component.</p>
<p>By following these rules you won't have a need to modify old components very often and can normally reuse old components to compose new and more advanced components.</p>
<p>In codebases where these rules aren't followed, developers consistently need to modify already existing components and rewrite their tests, which is both time consuming and prone to cause bugs in old features which previously have been proven to work.</p>
<p><strong>When to use:</strong> Make sure to follow React's component composition model and you will naturally build reusable components which are open for extension but closed for modifications.</p>
<h4>Liskov Substitution Principle (LSP)</h4>
<p>Liskov mentions that components that extend or inherit from other components should be completely interchangeable with their base components. For instance, that principle applies if you would have a Button component and then also sub-components as PrimaryButton and SecondaryButton. Liskov then says that the sub-component should take at least the same props as the Button component.</p>
<p>The practical benefit of this is that you can refactor and exchange components without worrying about breaking consumers. It might not be super common to use inheritance like this in React, since React by nature uses composition instead of inheritance, but the principle tells something important about interfaces.</p>
<p>Even if you don't have a hierarchy of buttons you might have multiple clickable components, such as buttons, chips, toggles and so on. Or a set of different dropdown components like a list one, a searchable one, one with check boxes etc.</p>
<p>If you have similar components like that, keep their interfaces similar so it's easy to exchange them if needed. You never know when that UX designer changes its mind.</p>
<p><strong>When to use:</strong> I wouldn't recommend to use actual inheritance as the LSP is about. However, when creating a set of components which all has similarities, then ensure to maintain the same or a similar interface and behavior for all of them.</p>
<h4>Interface Segregation Principle (ISP)</h4>
<p>Many projects have some of those super components/hooks which are used for nearly every component in the app. It has 15+ props and your only mission is to figure out which of those to use in your case, and most of your day goes to figuring out how to retrieve all data you need to even get it to compile without type errors.</p>
<p>That's a typical violation of the ISP which says that components shouldn't be forced to depend on props they don't use. It's better to use multiple hooks with fewer props and combine them for your use case. Or, to look over all the solution in general and see if it can be simplified. Chances are that someone has chosen a poor architectural solution there and that half of the props naturally could be refactored away.</p>
<p><strong>When to use:</strong> When designing component interfaces, keep them focused and specific to what each component actually needs, avoiding bloated prop interfaces.</p>
<h4>Dependency Inversion Principle (DIP)</h4>
<p>Dependency inversion principle tells that high-level components shouldn't depend on low-level implementation details. In short, this means that you should layer your application with abstractions in a way that high-level components don't depend on low-level functionality.</p>
<p>For instance, if you have a component of a user list, then that component shouldn't contain the logic to fetch the users. Instead it should depend on some hook which fetches the users for it, or get the users injected to it via a state manager or similar. Or more precisely, depend on an interface of how to get retrieve the data with clearly defined TypeScript attributes.</p>
<p>In that way, you can replace a low-level axios request in favor of fetch or add a fancy hook like SWR without out having to refactor your user list component, since the user list component only depends on an abstract hook like useUsers rather than having axios-specific logic within it.</p>
<p><strong>When to use:</strong> When building components that need to work with different data sources or implementations, or when you want to make your code more testable and flexible. Chances are that you might replace low-level functionality in your code base some day.</p>
<p>For detailed examples and implementation strategies, see my comprehensive article on <a href="https://www.perssondennis.com/articles/write-solid-react-hooks">writing SOLID React hooks</a>.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/chubby.webp" alt="Chubby">
<em>Chubby has a lot to say, for a good reason</em></p>
<p>For detailed examples and implementation strategies, see my article on <a href="https://www.perssondennis.com/articles/write-solid-react-hooks">writing SOLID React hooks</a>.</p>
<h3>Dependency Injection</h3>
<p>While not as common in React as in backend development, dependency injection can be achieved through Context API and custom hooks. Context API is the obvious choice, but hooks can also solve parts of the same issues.</p>
<p>Dependency injection is also covered in my article about <a href="https://www.perssondennis.com/articles/write-solid-react-hooks">SOLID React hooks</a>.</p>
<p><strong>When to use:</strong> When you need to swap implementations for testing or when building applications that need to work with different services or APIs.</p>
<h3>Separation of Concerns (SoC)</h3>
<p>Separation of Concerns is about organizing code so that different types of logic are kept separate and focused. While it's related to the Single Responsibility Principle (SRP), SoC operates at a higher architectural level.</p>
<p>SRP says each component should have one responsibility, while SoC says different types of concerns (data, business logic, presentation) should be in separate layers with clear boundaries.</p>
<p>Below is a typical violation of SoC. You don't really have to read it, I will spare you from that headache. The important thing to realize is that you hesitate from even reading it.</p>
<pre><code class="language-javascript">// Bad - all concerns mixed together
const UserProfile = ({ userId }) => {
  const [user, setUser] = useState(null)
  const [loading, setLoading] = useState(false)
  const [editing, setEditing] = useState(false)
  const [formData, setFormData] = useState({})

  useEffect(() => {
    setLoading(true)
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(user => {
        setUser(user)
        setLoading(false)
      })
  }, [userId])

  const handleSave = async () => {
    const updatedUser = {
      ...user,
      ...formData,
      displayName: `${formData.firstName} ${formData.lastName}`,
      isActive: formData.status === 'active'
    }

    const response = await fetch(`/api/users/${userId}`, {
      method: 'PUT',
      body: JSON.stringify(updatedUser)
    })

    if (response.ok) {
      setUser(updatedUser)
      setEditing(false)
      toast.success('User updated successfully')
    }
  }

  if (loading) return &#x3C;div>Loading...&#x3C;/div>
  if (!user) return &#x3C;div>User not found&#x3C;/div>

  return (
    &#x3C;div>
      {editing ? (
        &#x3C;div>
          &#x3C;input 
            value={formData.firstName || user.firstName}
            onChange={(e) => setFormData({...formData, firstName: e.target.value})}
          />
          &#x3C;select 
            value={formData.status || user.status}
            onChange={(e) => setFormData({...formData, status: e.target.value})}
          >
            &#x3C;option value="active">Active&#x3C;/option>
            &#x3C;option value="inactive">Inactive&#x3C;/option>
          &#x3C;/select>
          &#x3C;button onClick={handleSave}>Save&#x3C;/button>
        &#x3C;/div>
      ) : (
        &#x3C;div>
          &#x3C;h2>{user.displayName}&#x3C;/h2>
          &#x3C;p>Status: {user.isActive ? 'Active' : 'Inactive'}&#x3C;/p>
          &#x3C;button onClick={() => setEditing(true)}>Edit&#x3C;/button>
        &#x3C;/div>
      )}
    &#x3C;/div>
  )
}
</code></pre>
<p>This component is doing everything: fetching data, transforming it, managing UI state, handling form logic, and rendering. If any of these concerns change, you have to modify this component.</p>
<p>The SoC design principle can be applied by separating each concern into its own layer:</p>
<pre><code class="language-javascript">// Presentation layer - only rendering
const UserProfile = ({ userId }) => {
  const { user, loading } = useUserState(userId)

  if (loading) {
    return &#x3C;LoadingSpinner />
  }

  if (!user) { 
    return &#x3C;NotFound message="User not found" />
  }

  return &#x3C;UserDisplayCard user={user} />
}
</code></pre>
<pre><code class="language-javascript">// State management layer
const useUserState = (userId) => {
  const [user, setUser] = useState(null)
  const [loading, setLoading] = useState(false)
  
  const { getUser } = useUserApi()
  const { transformUserForDisplay } = useUserBusinessLogic()

  const loadUser = async () => {
    setLoading(true)

    try {
      const userData = await getUser(userId)
      setUser(transformUserForDisplay(userData))
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    loadUser()
  }, [userId])

  return { user, loading }
}
</code></pre>
<pre><code class="language-javascript">// Business logic layer - data transformations
const useUserBusinessLogic = () => {
  const transformUserForDisplay = (user) => ({
    ...user,
    displayName: `${user.firstName} ${user.lastName}`,
    isActive: user.status === 'active'
  })

  return { transformUserForDisplay }
}
</code></pre>
<pre><code class="language-javascript">// Data layer - API communication
const useUserApi = () => {
  const getUser = async (userId) => {
    const response = await fetch(`/api/users/${userId}`)
    return response.json()
  }

  return { getUser }
}
</code></pre>
<p>Now each layer has a clear, focused responsibility:</p>
<ul>
<li><strong>Data layer</strong>: Knows how to communicate with APIs</li>
<li><strong>Business logic layer</strong>: Handles data transformations and business rules</li>
<li><strong>State management layer</strong>: Orchestrates data and state changes</li>
<li><strong>Presentation layer</strong>: Only concerned with rendering UI</li>
</ul>
<p>This separation makes the code much easier to understand, test, and maintain. You can test business logic without worrying about API calls or rendering. You can change the API structure without touching business logic. And you can redesign the UI without affecting data handling.</p>
<p>The key insight is that different types of logic change for different reasons and at different rates. By keeping them separate, you minimize the ripple effects when changes are needed.</p>
<p><strong>When to use:</strong> Any non-trivial application should separate types of logic like this. It's necessary for the project to scale and to work effectively in a team.</p>
<h3>MVVM</h3>
<p>MVVM (Model-View-ViewModel) is very popular in many frameworks but rarely spoken about in React. Yet it can be very useful, either as a whole or taking inspiration from it.</p>
<p>You can read my detailed <a href="https://www.perssondennis.com/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript">article about implementing MVVM in React</a> for a complete guide on how to structure larger React applications using this pattern.</p>
<p><strong>When to use:</strong> Wouldn't say it's common to follow this pattern in React and neither would I recommend to follow it strictly. But many apps take inspiration from it and use similar layerings. The goal is to separate the concerns in some scalable way.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/mooview.webp" alt="Mooview">
<em>Who doesn't like Mooview? Look at those puppy eyes!</em></p>
<h3>Stable Dependency Principle (SDP)</h3>
<p>There's always components and hooks in a React app which are stable and well tested - SDP says that those should form the foundation of our app.</p>
<p>Volatile components will of course exist, which are often updated or replaced. The point with SDP is to avoid having other components being dependent on these risky and unstable components to avoid having the whole app to crash for a small change in a seemingly unimportant component.</p>
<p>For instance, browser's built-in functionality rarely changes - that is safe to depend on. A useLocalStorage hook in React which uses local storage should rarely change and can also be considered stable.</p>
<p>On the other hand, the useStoreAnythingYouWant hook my colleague Brad implemented might be more likely to change - consider it unstable (but don't let Brad know I said that).</p>
<p>The point is, avoid using stuff that you know might change. For example, private variables in libraries often start with an underscore. They are marked that way because they might change without any notice. If you see it, don't use it!</p>
<p>In e2e tests with Cypress or similar, use data-test-id attributes, don't use CSS selectors to grab HTML elements or class names. CSS classes disappears just as quickly as Brad when he sees people walking towards the table tennis room.</p>
<p><strong>When to use:</strong> Always. Choose stable, well-established dependencies over experimental or frequently changing ones to avoid breaking changes in your application.</p>
<h3>KISS Principle</h3>
<p>The last principle in this list is very simple, but it would be stupid not to follow. The KISS principle stands for "Keep It Simple, Stupid".</p>
<p>When designing any kind of system, it should always be simple. Don't overcomplicate things! Keep the user interface simple, and the code as well. Think one extra time if you really need to do the things you are trying to do.</p>
<p>The things you might not need to add can be features which might give little value but introduce more complexity to the application. Or it might be a custom-made user authentication mechanism, instead of using a third-party provider for authentication.</p>
<p>Or it might be a library which comes with extra configuration files and a bundle size of 100 kB extra, when you really only use one or two functions from that library.</p>
<p>This complexity can also be in the code itself. A perfect example of how to overcomplicate code in React is to use useEffect when it isn't needed.</p>
<pre><code class="language-javascript">const SomeComponent = () => {
  const [fetchData, setFetchData] = useState(false)
  const [data, setData] = useState()

  useEffect(() => {
    if (fetchData) {
      const dataFromSomewhere = getData()
      setData(dataFromSomewhere)
    }
  }, [fetchData])

  return (
    &#x3C;>
      &#x3C;button 
        onClick={() => setFetchData(true)}
      >Fetch data&#x3C;/button>
      &#x3C;div>{data}&#x3C;/div>
    &#x3C;/>
  )
}
</code></pre>
<p>It's very common that developers use useEffect in scenarios like the one above. In reality, the code would work much better with the simple solution below.</p>
<pre><code class="language-javascript">const SomeComponent = () => {
  const [data, setData] = useState()

  const fetchData = () => {
    const dataFromSomewhere = getData()
    setData(dataFromSomewhere)
  }

  return (
    &#x3C;>
      &#x3C;button 
        onClick={() => fetchData()}
      >Fetch data&#x3C;/button>
      &#x3C;div>{data}&#x3C;/div>
    &#x3C;/>
  )
}
</code></pre>
<p>In my article about <a href="https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer">reactive developers</a>, you can see more complicated code React developers tend to write when it really isn't necessary, and what the consequences of that are.</p>
<p><strong>When to use:</strong> Always. Prefer simple, straightforward solutions over complex ones unless complexity provides clear, significant benefits. This might not sound like a design pattern for many, but it's one of the most trivial and effective design pattern which prevents over-engineering.</p>
<h2>Design Patterns to Avoid</h2>
<p>This is of course opinionated, but be aware of my opinion, because I'm definitely not alone with this opinion. This is important to know when choosing React design patterns for your project. Some forces of nature should remain untamed and preserved in their natural domain.</p>
<h3>Clean Architecture</h3>
<p>I'm listing this here because I have seen backend developers using it in React. MVVM I can feel is alright, but Clean Architecture is a step too much for React.</p>
<p>The problem is kind of too many layers and you will annoy the hell out of your normal frontend colleagues. Plus, it's often a pure rip-off of Clean Architecture that breaks quite some other core design patterns of React.</p>
<p>React already has its own architectural patterns that work well. Don't take architectural patterns from your previous work experience and force them into new code bases where they don't belong. Stick to React best practices and common React patterns instead. Each ecosystem has its own natural laws.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/modulynx.webp" alt="Modulynx">
<em>Modulynx is quite tiny, which allows her to clean the tiniest interfaces</em></p>
<h2>Note About Modern React Patterns and Frameworks</h2>
<p>If you don't think 21 patterns was enough, you might want to stay tuned, there are actually many new patterns which came with React 18 and 19.</p>
<p>You might have familiarized yourself with them already, especially if you are using frameworks like Next.js or Remix.</p>
<p>I haven't included any of those in this article though, since it's already long enough. But for the impatient readers I can give some spoilers, it's about functionalities like:</p>
<ul>
<li>Server Components</li>
<li>Suspense data fetching</li>
<li>Concurrent features</li>
</ul>
<p>These patterns are still evolving, but they represent the future direction of React development. Regardless whether you are using one of the more prominent React
frameworks or if you use pure React Vite.</p>
<p><img src="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/react-vite.webp" alt="React Vite">
<em>Because I love React, I am particularly fond of Vite</em></p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Architecture</category>
            <category>Frontend</category>
            <category>JavaScript</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/21-fantastic-react-design-patterns-and-when-to-use-them/21-fantastic-react-design-patterns-and-when-to-use-them.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[33 Christmas Animations to Easily Add to Your Website]]></title>
            <link>https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website</link>
            <guid>https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website</guid>
            <pubDate>Sun, 10 Dec 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Christmas CSS art for websites. Snowflakes on webpages, animated CSS snow globes, CSS Santa, snowmen, candy canes and Christmas trees for websites.]]></description>
            <content:encoded><![CDATA[<p>Yes, it's already that time of year. Whether you love or hate Christmas, a small Christmas CSS animation can bring a big smile to your website visitors.</p>
<p>In this list, you will find 33 Christmas animation and interactive art which easily can be added you your website. Most of them are CSS only, others requires a small amount of JavaScript.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website#css-snowflakes">CSS Snowflakes!</a></li>
<li><a href="https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website#snow-globes">Snow Globes</a></li>
<li><a href="https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website#css-santa-claus">CSS Santa Claus</a></li>
<li><a href="https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website#christmas-decorations-in-css">Christmas Decorations in CSS</a></li>
<li><a href="https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website#interactive-christmas-animations">Interactive Christmas Animations</a></li>
<li><a href="https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website#css-candy-canes">CSS Candy Canes</a></li>
<li><a href="https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website#css-snowman">CSS Snowman</a></li>
<li><a href="https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website#other-christmas-art">Other Christmas Art</a></li>
<li><a href="https://www.perssondennis.com/articles/33-christmas-animations-to-easily-add-to-your-website#bonus-christmas-games">Bonus - Christmas Games</a></li>
</ul>
<h2>CSS Snowflakes!</h2>
<p>Let's start out with snowflakes. Decorate your webpage with animated snowflakes. Easy to add, delightful to look at.</p>
<ul>
<li><a href="https://codepen.io/chloe47632/pen/ExwgNpg">Slowly drifting CSS snowflakes</a></li>
<li><a href="https://codepen.io/mark_sottek/pen/WrNqJV">Vividly cascading snowflakes using JavaScript</a></li>
<li><a href="https://codepen.io/ethancopping/pen/ExrGYGG">Intensively falling JavaScript snowflakes</a></li>
<li><a href="https://pajasevi.github.io/CSSnowflakes/">CSS-based falling snowflakes</a></li>
</ul>
<h2>Snow Globes</h2>
<p>Can you make a snow globe with pure CSS? Yes, here we have three stunning snow globes made with only CSS.</p>
<ul>
<li><a href="https://codepen.io/alvaromontoro/details/jOGLeJV">Animated snow globe with snowman inside</a></li>
<li><a href="https://codepen.io/shezzor/pen/yLEWewK">Animated snow globe with holiday cottage</a></li>
<li><a href="https://codepen.io/chilliconcode/pen/rWpvOe">Snow globe with snowman and Christmas tree</a></li>
</ul>
<h2>CSS Santa Claus</h2>
<p>What would Christmas be without Santa Claus himself? The tricky thing is too choose which CSS Santa to go for!</p>
<ul>
<li><a href="https://codepen.io/alvaromontoro/pen/gOwYYGJ">Well detailed CSS Santa Claus</a></li>
<li><a href="https://codepen.io/Alireza29675/pen/KwgwMy">Giggling CSS only Santa</a></li>
<li><a href="https://codepen.io/EleftheriaBatsou/pen/jYrydg">Winking Santa Claus</a></li>
<li><a href="https://codepen.io/ksksoft/pen/PowqyNz">Running Santa animation</a></li>
<li><a href="https://codepen.io/Coding-Artist/pen/ExaXZqZ">Animated Santa in helicopter</a></li>
</ul>
<h2>Christmas Decorations in CSS</h2>
<p>Why not adding some small decorative Christmas inspired CSS art? My favorite is definitely the Disney-like Christmas tree, which reasonably requires a good amount of JavaScript. If you don't want to use JavaScript, you have a quite similar mesmerizing CSS only Christmas tree animation in another link.</p>
<ul>
<li><a href="https://codepen.io/chrisgannon/pen/dypvKvR">Beautiful magical animated Christmas tree</a></li>
<li><a href="https://codepen.io/mark_sottek/pen/emdYrG">Two in one, animated candy cane and reindeer</a></li>
<li><a href="https://codepen.io/uchardon/pen/ExvBBpL">Animated CSS only Christmas tree</a></li>
<li><a href="https://codepen.io/tobyj/pen/QjvEex">Christmas lights to place on top of website</a></li>
<li><a href="https://codepen.io/dodozhang21/pen/ApeaLY">Retro styled pixel art Christmas tree</a></li>
<li><a href="https://codepen.io/LimeWub/pen/yQWbNW">Spinning Christmas tree</a></li>
</ul>
<h2>Interactive Christmas Animations</h2>
<p>Here are some interactive Christmas animation. They naturally include a bit of JavaScript since they are interactive, but some manage to get away very easily with almost no JavaScript at all.</p>
<ul>
<li><a href="https://codepen.io/msamways/pen/yyegxq/">Hoverable Christmas cracker with message</a></li>
<li><a href="https://codepen.io/john_r_muir/pen/RwRObMK">Pullable Christmas cracker (click multiple times)</a></li>
<li><a href="https://codepen.io/ihatetomatoes/pen/KwMLGP">Interactive Christmas gift</a></li>
<li><a href="https://codepen.io/Mamboleoo/pen/PZWPZx">Openable Christmas present</a></li>
<li><a href="https://codepen.io/jankohlbach/details/yLzVbpw">Spinning Christmas present (click multiple times)</a></li>
<li><a href="https://codepen.io/danwilson/pen/LYRPYpv">Spinning Christmas tree you can decorate</a></li>
</ul>
<p><img src="https://www.perssondennis.com/images/articles/33-christmas-animations-to-easily-add-to-your-website/christmas-gift-css.webp" alt="Christmas gift CSS"></p>
<h2>CSS Candy Canes</h2>
<p>Wanting something sweet for Christmas? Try these CSS loading and progress bars in candy cane colors!</p>
<ul>
<li><a href="https://codepen.io/woodwoerk/pen/XXJoMa">Candy cane CSS only loading bar</a></li>
<li><a href="https://codepen.io/jkantner/details/rNGYmpL">Peppermint stick progress bar</a></li>
<li><a href="https://codepen.io/jkantner/details/yLqydxv">Candy cane range slider</a></li>
</ul>
<p><img src="https://www.perssondennis.com/images/articles/33-christmas-animations-to-easily-add-to-your-website/candy-cane-progress-bar.webp" alt="Candy cane progress bar"></p>
<h2>CSS Snowman</h2>
<p>Do you know why it is better to add a snowman to your website than building one outside? Because it never melts. Unless your servers overheats...</p>
<ul>
<li><a href="https://codepen.io/alikhalilifar/pen/kGzLrN">CSS Snowman</a></li>
<li><a href="https://codepen.io/alvaromontoro/details/MWEOBPO">Cute CSS snowman</a></li>
</ul>
<h2>Other Christmas Art</h2>
<p>Couldn't decide what CSS art to use to decorate your website with for Christmas? Here's a few more links which may come handy.</p>
<ul>
<li><a href="https://codepen.io/epilande/pen/kxMrYy">Christmas background with dimming lights</a></li>
<li><a href="https://codepen.io/jkantner/pen/VwdExyy">Bouncing Christmas gift</a></li>
<li><a href="https://codepen.io/chrisgannon/pen/VeaBVv">Merry Christmas message</a></li>
<li><a href="https://codepen.io/texxs/pen/WbxYzx">Bouncing Elf</a></li>
</ul>
<p><img src="https://www.perssondennis.com/images/articles/33-christmas-animations-to-easily-add-to-your-website/animated-css-elf.webp" alt="Animated CSS elf"></p>
<h2>Bonus - Christmas Games</h2>
<p>It's Christmas after all, you should get some extra gifts. For you today, I have found two Christmas games you can play!</p>
<ul>
<li><a href="https://codepen.io/natewiley/pen/gbwWMX">Santa running game</a></li>
<li><a href="https://codepen.io/LantareCode/pen/QGoVmP">Christmas maze game</a></li>
</ul>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>UI</category>
            <enclosure url="https://www.perssondennis.com/images/articles/33-christmas-animations-to-easily-add-to-your-website/33-christmas-animations-to-easily-add-to-your-website.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[6 Use Cases for Regex in Your Daily Work]]></title>
            <link>https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work</link>
            <guid>https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work</guid>
            <pubDate>Sun, 27 Nov 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[6 use cases for regular expressions to learn when and how to use regex. Regex can be used to find info, check occurrences and to replace or categorize data.]]></description>
            <content:encoded><![CDATA[<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work#what-is-regex">What Is Regex?</a></li>
<li><a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work#regexes-in-a-nutshell">Regexes in a Nutshell</a></li>
<li><a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work#when-is-regex-used">When Is Regex Used?</a>
<ul>
<li><a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work#searching-through-files-manuals-and-logs">Searching Through Files, Manuals and Logs</a></li>
<li><a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work#regex-search-in-an-ide">Regex Search in an IDE</a></li>
<li><a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work#classic-example-form-validation">Classic Example, Form Validation</a></li>
<li><a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work#find-and-replace-like-a-pro-or-manipulate-strings">Find and Replace Like a Pro (or Manipulate Strings)</a></li>
<li><a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work#usages-in-apis-and-web-consoles">Usages in APIs and Web Consoles</a></li>
<li><a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work#interpret-and-categorize-data-with-regex">Interpret and Categorize Data with Regex</a></li>
</ul>
</li>
<li><a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work#learn-more-about-regex">Learn More About Regex</a></li>
</ol>
<h2>What Is Regex</h2>
<p>Regex, or Regular Expression, is a tough thing to learn. Trying to define it in simple words is almost as difficult. In a short sentence, Wikipedia currently describes regular expressions as a sequence of characters that specifies a search pattern in a text.</p>
<p>What that means, is that regexes are used to find characters in a text. With characters I mean letters, numbers, brackets, new line characters and so on. With regexes, you can write an expression that defines which sequence of characters you want to find in the text.</p>
<p>Understanding the syntax of the expression language is what is hard to learn (and remember). We will go through everything you need to know about that in upcoming articles, both for basic and advanced usage. The aim of this first article in the series is to explain why you should learn regex.</p>
<p><img src="https://www.perssondennis.com/images/articles/6-use-cases-for-regex-in-your-daily-work/plural-of-regex.webp" alt="Plural of regex">
<em>Just another thought to keep you awake</em></p>
<h2>Regexes in a Nutshell</h2>
<p>Regex on its own is only used to find text occurrences (matches) in a string or text. What we want to do with the matches is up to us. When using regexes, we are most often interested in one of three things.</p>
<ul>
<li>find information in a text</li>
<li>check if a string matches a regex, e.g., email validation</li>
<li>replace characters in a text</li>
</ul>
<p>Even if the use cases of regex often boil down to answering a yes or no question, finding text occurrences or to replace some characters, it can be used in a lot of scenarios. We will look at a few of them now.</p>
<h2>When Is Regex Used?</h2>
<p>Most developers can go a life time without learning regex. Often when regex is a good idea to use, it isn't completely necessary to use it. The alternative solutions do unfortunately often take a lot more time to implement and will not scale for use cases where more data needs to be processed.</p>
<p>The short and boring answer to the question "when is regex used?" is "to a lot of things". The long answer follows here.</p>
<h3>Searching Through Files, Manuals and Logs</h3>
<p>The first time I ever encountered regexes was when learning about Unix. First experience was to find information in Unix manual pages and log files. It looked pretty much like this.</p>
<pre><code class="language-bash"># Finds all lines that contain the word "error" and later "vehicle" in the file somelogfile.log. Useful to see if we have logged any errors which mention anything about a vehicle.
grep -i 'error.*vehicle' ./somelogfile.log

# Searches through the Unix manual for scp command and outputs what the v flag does.
man scp | grep -i '\-v'
# Output in Mac terminal:
# -v  Verbose mode.  Causes scp and ssh(1) to print debugging messages
</code></pre>
<p>Above examples may look like school book examples, and they are. That's why we go to school, to learn useful stuff! Sure, you can always google for what flags for Unix commands do, may take longer time, but still quick.</p>
<p>Searching through log files is something you will have to do yourself though. That's something I do daily at work to investigate bugs. For big log files I may find hundreds or thousands matches if I simply search for "warning" or "error". Writing regexes definitely helps me filtering among all those results by specifying a more granular search term with a regex.</p>
<h3>Regex Search in an IDE</h3>
<p>Have you ever accidentally activated that regex checkbox in your IDE when searching for text occurrences in your editor and then wondering why you don't find what you are searching for? Next time you do that, don't uncheck it. Find a way to search for what you want with it activated!</p>
<p><img src="https://www.perssondennis.com/images/articles/6-use-cases-for-regex-in-your-daily-work/regex-search-button-meme.webp" alt="regex-search-button meme">
<em>Sign me up as guilty for that, it has happened a lot.</em></p>
<p>Maybe you know you are invoking a very common function somewhere, but don't remember where it was or what the function is named. Here are some expressions for that! Don't worry if you don't understand them, regex syntax will be explained in another article I will post here in a few weeks.</p>
<pre><code class="language-javascript">// Finds a console log that prints a count variable.
conso.*count
// Example: console.log(count)
// Example: console.log(`Total: ${count}`)
// Example*: console.log(itemCount)

// Finds a function which name ends with "count" and has an argument which includes the text "todo".
count\(.*todo
// Example: count(todoItems)
// Example*: updateCount(oldCount, newTodoItem)

// * these examples only match if case sensitivity is disabled, which is done either in the IDE or by using the regex flag i
</code></pre>
<h3>Classic Example, Form Validation</h3>
<p>This article wouldn't be complete if the classic example wasn't mentioned. This is probably what you are thinking of when you read the word regex, to validate a form using regexes. It's a must have.</p>
<p>You can both validate that an email is a valid email, or that a phone number is of the correct format. You can also forbid curses and vulgar words in user names or detect if a credit card number is a MasterCard or a Visa. Maybe you need to ensure that a password contains special characters. For all of these examples, you can use regexes.</p>
<p><img src="https://www.perssondennis.com/images/articles/6-use-cases-for-regex-in-your-daily-work/form-validation-with-regex.webp" alt="Form validation with regex">
<em>I'm fine with regex, but I won't touch CSS</em></p>
<h3>Find and Replace Like a Pro (or Manipulate Strings)</h3>
<p>Once in a while I get a really boring task at work. It could be that an API endpoint has been updated and it requires a lot of changes because it has been hardcoded all over the place. It could also be that data has been dumped from a production database into a JSON file to be used as development data, and to do that, all email addresses must be replaced with dummy addresses.</p>
<p>The hardcoded API example sounds like a quick find and replace work, and it is, but you may need to know regex to do that. Look at the following URLs.</p>
<ul>
<li>https:// regexexampledomain.com/articles/react/some-react-article</li>
<li>https:// regexexampledomain.com/articles/react/react-is-awesome</li>
<li>https:// regexexampledomain.com/articles/javascript/a-javascript-article</li>
</ul>
<p>The above urls follows the pattern <em>/articles/&#x3C;category>/&#x3C;article-name></em>. Imagine if we have thousands of links like that, with thousands of categories, and we have refactored the site so we don't longer have categories such as react and javascript in the URL.</p>
<p>We could fairly safely find and replace one category after another, e.g., replacing <em>/react/</em> and <em>/javascript/</em> with a single slash character to remove the categories. But remember, the site has thousands of categories, it will take time to manually do that.</p>
<p>With regexes, we can update all of those categories using one single find and replace, regardless of how many categories we have.</p>
<p>What about the email obfuscation example? How can we find and replace any email in a JSON file with <a href="mailto:john.doe@gmail.com">john.doe@gmail.com</a>? The only thing we need for that is a regex for an email address and a replace function in either a programming language or an IDE. Then we can just hit a button and search through the JSON data to see that it actually replaced the emails successfully.</p>
<p><img src="https://www.perssondennis.com/images/articles/6-use-cases-for-regex-in-your-daily-work/sad-john-doe.webp" alt="Sad John Doe">
<em>John Doe didn't get his email obfuscated</em></p>
<h3>Usages in APIs and Web Consoles</h3>
<p>Regex is widely spread. A lot of services and APIs support it. This means it's a fairly good chance that a SaaS which deals with a great amount of data offers some kind of regex solution. It could be a search field in a web console for a logging tool or it could be a SDK or API that allows to use regexes. See for example <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html">Elasticsearch regex queries</a>.</p>
<h3>Interpret and Categorize Data with Regex</h3>
<p>So far, most of the regex examples described have involved processing or validating data. However, regexes can also be used to interpret and categorize data.</p>
<p>Let's take an example where the input data is single words which either can be a string, an integer, a float number, an array or an object. Our goal is to detect which one it is.</p>
<pre><code class="language-markdown">Input: 402
Output: integer

Input: 402 is an integer
Output: string

Input: 4.2
Output: float

Input: the number 4.2 is a float, not an integer
Output: string

Input: ['hello', 4.2]
Output: array

Input: {"hello": 4.2}
Output: object
</code></pre>
<p>The above problem can of course be solved with a lot of if statements and looping through alphabetic letters to detect if the input contains any of those. With regex, we can however solve it much easier. We can use regexes like below to instantly detect the types.</p>
<pre><code class="language-markdown">Regex: /^[0-9]+$/
Detects: integer

Regex: /^[0-9]+\.[0-9]+$/
Detects: float

Regex: /^\[.*\]$/
Detects: array

Regex: /^\{.*\}$/
Detects: object
</code></pre>
<p>With the above regex, we could detect integers, floats, arrays and objects in a few lines of code. To detect strings, we could create a more complex regex, ensuring that it doesn't start with a bracket and that it contains letters from the alphabet, but it would also be sufficient to use string as a default fallback value when the input isn't of any of the other types.</p>
<p>Using regex in this way can save us some lines of code. In other scenarios it may be crucial to use regex. Take clothing sizes as an example. There are many ways to write a size like XL. What if we want to map all possible ways to write it into one of the ways?</p>
<pre><code class="language-markdown">## Examples of input: l, L, large, Large, lg, LG, L slim, L wide
Output: L

## Examples of input: xl, XL, extra large, extra-large, x large, x-large, X-Large
Output: XL

## Examples of input: xxl, XXL, 2xl, 2XL
Output: XXL
</code></pre>
<p>Starting to see the problem? This issue is fairly easy to solve with regex. Without it, we kind of would have to hardcode a lot of mappings for the sizes. That's totally a valid solution. But what if the sizes also could be numbers?</p>
<p>Say for example that we have a t-shirt in size L which is described with the European size 52, or maybe as a range from 52-54? We would have a lot of things to hardcode there.</p>
<p>Although regex is of great use in a case like this, we can not solve this problem with a single regex, we need quite a few of them. However, we do not need a lot of them, a single regex can match a lot of different variations of how to write a size.</p>
<h2>Learn More About Regex</h2>
<p>The use cases of regex we have seen in this article are just examples. These kinds of issues don't always need to be solved with regex. Sometimes it is just overkill to use regex. Sometimes it's just as easy without regex as it is with regex. It is a decision you will have to take when facing a problem. For some problems, you will come to realize that it isn't even feasible to solve the problem without regex.</p>
<p>If you want to learn more about regex. Save this article for later or follow me. I will post another article during next month.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>JavaScript</category>
            <category>Productivity</category>
            <enclosure url="https://www.perssondennis.com/images/articles/6-use-cases-for-regex-in-your-daily-work/6-use-cases-for-regex-in-your-daily-work.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Answers to Common Next.js Questions]]></title>
            <link>https://www.perssondennis.com/articles/answers-to-common-nextjs-questions</link>
            <guid>https://www.perssondennis.com/articles/answers-to-common-nextjs-questions</guid>
            <pubDate>Sun, 05 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Answers to common Next.js questions such as how Server Components work and how to read params in components. ✓ Next.js 14 ✓ Server Components ✓ App Router]]></description>
            <content:encoded><![CDATA[<p>Web development went from server rendered applications to single page applications rendered fully on the client, and then it all got complicated. Next.js have now cleared away the old perspective of client and servers and provided us with a high performance framework which is a big black box containing both client and server. But don't worry, I'll here provide a FAQ with common questions about Next.js and its Server Components.</p>
<p><img src="https://www.perssondennis.com/images/articles/answers-to-common-nextjs-questions/frontend-devs-got-tricked.webp" alt="Frontend devs got tricked">
<em>At least we get to use JavaScript for the server code</em></p>
<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#1-how-to-read-url-params-in-a-client-component">How To Read URL Params in a Client Component?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#2-how-to-read-url-params-in-a-page-file">How To Read URL Params in a Page File?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#3-how-to-read-url-params-in-a-nextjs-layout-file">How To Read URL Params in a Next.js Layout File?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#4-how-to-read-url-params-in-a-server-component">How To Read URL Params in a Server Component?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#5-why-doesnt-searchparams-exist-in-nextjs-layout-files">Why Doesn't searchParams Exist in Next.js Layout Files?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#6-how-can-i-skip-the-root-layout-for-some-pages-in-nextjs">How Can I Skip the Root Layout for Some Pages in Next.js?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#7-how-to-set-metadata-tags-in-app-router">How To Set Metadata Tags in App Router?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#8-how-to-set-metadata-dynamically-for-an-app-router-page">How To Set Metadata Dynamically for an App Router Page?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#9-can-i-set-metadata-in-a-layout-file">Can I Set Metadata in a Layout File?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#10-can-i-use-contexts-with-app-router">Can I Use Contexts with App Router?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#11-how-to-use-react-context-in-server-components">How To Use React Context in Server Components?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#12-is-it-possible-to-render-a-client-component-in-a-server-component">Is it Possible to Render a Client Component in a Server Component?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#13-can-i-pass-props-from-a-server-component-to-a-client-component">Can I Pass Props from a Server Component to a Client Component?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#14-can-i-use-server-components-in-client-components">Can I Use Server Components in Client Components?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#15-can-i-pass-props-from-a-client-component-to-a-server-component">Can I Pass Props from a Client Component to a Server Component?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#16-can-i-use-server-actions-in-server-components">Can I Use Server Actions in Server Components?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#17-can-i-use-server-actions-in-client-components">Can I Use Server Actions in Client Components?</a></li>
<li><a href="https://www.perssondennis.com/articles/answers-to-common-nextjs-questions#18-are-server-actions-stable-in-nextjs">Are Server Actions Stable in Next.js?</a></li>
</ol>
<h2>1. How To Read URL Params in a Client Component?</h2>
<p>If you need to read the pathname or query params from the URL in a Client Component, you can use the <a href="https://nextjs.org/docs/app/api-reference/functions/use-pathname">usePathname</a> or <a href="https://nextjs.org/docs/app/api-reference/functions/use-search-params">useSearchParams</a> to do so.</p>
<pre><code class="language-javascript">'use client'

import { usePathname, useSearchParams } from 'next/navigation'

const ClientComponent({ children, href }) {
  const pathname = usePathname()
  const searchParams = useSearchParams()
  const search = searchParams.get('search')

  return (
    &#x3C;div>Next.js usePathname and useSearchParams example&#x3C;/div>
    &#x3C;div>{pathname}&#x3C;/div>
    &#x3C;div>{search}&#x3C;/div>
  )
}

export default ClientComponent
</code></pre>
<p>If you need to navigate programatically in a Client Component, you can use <a href="https://nextjs.org/docs/app/api-reference/functions/use-router">useRouter</a>. For normal navigation, please use the built in Link component Next.js has.</p>
<pre><code class="language-javascript">'use client'

import { useRouter } from 'next/navigation'

const ClientComponent({ children }) {
  const router = useRouter()

  const handleClick = () => {
    router.push('someUrl')
  }

  return (
    &#x3C;div onClick={handleClick}>Click me&#x3C;/div>
  )
}

export default ClientComponent
</code></pre>
<h2>2. How To Read URL Params in a Page File?</h2>
<p>Params are automatically passed as props to the page component. You can simply use the provided prop.</p>
<pre><code class="language-javascript">const PageComponent({ params, searchParams }) {
  const { slug } = params

  return &#x3C;div>Next.js URL params in page.tsx file&#x3C;/div>
}

export default PageComponent
</code></pre>
<h2>3. How To Read URL Params in a Next.js Layout File?</h2>
<p>If you need to read URL params in a layout component file, you have two options. First option is to create a Client Component inside the layout and read the params in the Client Component instead.</p>
<p>This may sound like a bad option if you use Next.js with the expectations to mostly use Server Components, but it actually is completely natural. The rest of your layout file, can still be rendered as a Server Component, it's just the Client Component itself which will need to be rendered on the client.</p>
<p>For instance, if you would use URL params to filter articles on a blog with the help of chips components, then only the component containing the chips would need to be a Client Component, the rest of the header could remain a Server Component.</p>
<p><img src="https://www.perssondennis.com/images/articles/answers-to-common-nextjs-questions/client-component-in-server-component-header.webp" alt="Client component in server component header">
<em>On the website above, the red rectangle can be a Server Component, while the blue rectangle which depends on URL params can be a Client Component</em></p>
<p>The other option, might be the lesser good alternative. This is to add a middleware to your application which reads the URL params and passes it on to your layout component. This will give you flexibility to access the URL params, on the cost of disabling static rendering and client-side caching of your Server Components.</p>
<h2>4. How To Read URL Params in a Server Component?</h2>
<p>In a arbitrary Server Component, which is neither a layout component or page component, you can get the URL params by passing them down as props from other components.</p>
<p>Important to remember is that Server Components which aren't page file components aren't normally refreshed during navigation, the components as a whole are serialized and sent to the client and only updates in rare cases. For that reason, you must be careful when using information from the URL in Server Components. The URL params will get outdated upon navigation.</p>
<h2>5. Why Doesn't searchParams Exist in Next.js Layout Files?</h2>
<p>searchParams are only available in page files for a reason. Page files will always re-render when you navigate between two pages. Since the component re-renders when the URL changes, we can for sure know that the URL params passed to the component are up to date.</p>
<p>The purpose of layout components, is to avoid unnecessary renderings and to contain static parts of the UI which aren't updated when the user navigates between pages. A layout component does therefore only re-render when the user navigates to another part of the screen where that component isn't visible. In the code, that means to navigate between two pages which don't share a common layout file as ancestor in the file tree.</p>
<p>Effectively, this means that the URL will change more often than layout files renders, and if we were to read URL params in a layout component, the component <a href="https://nextjs.org/docs/app/api-reference/file-conventions/layout#layouts-do-not-receive-searchparams">wouldn't get to know when the URL params updated</a>. Remember that the layout file is a Server Component, it is rendered to HTML when it is first fetched and then cached on client so it never has to re-render.</p>
<p>To learn more, read the section above about how to read URL params in a Next.js layout file.</p>
<h2>6. How Can I Skip the Root Layout for Some Pages in Next.js?</h2>
<p>A Next.js project can have many layout files, technically each page can have its own. The top level layout file which wraps your whole application is called Root Layout.</p>
<p>Layout files allow you to re-use a component as a wrapper component for several pages. Most commonly, each Next.js applications has a Root Layout file which includes the applications main menu, such as a header menu or hero image.</p>
<p>While doing that, you will soon run into a question; can you skip the Root Layout for specific pages? And the answer is, yes you can. Next.js has a feature called <a href="https://nextjs.org/docs/app/building-your-application/routing/route-groups#creating-multiple-root-layouts">Route Groups</a> which allows you to have multiple Root Layouts. This means that different parts of your application can have different layouts, which also makes it possible to skip having any components at all in the layout for certain pages.</p>
<p>One thing to note here is that navigation between route groups will trigger a full page load. That is a natural consequence of replacing the top level Server Component in the application. It basically means, you render a completely new part of your application which is independent from the rest of all pages.</p>
<h2>7. How To Set Metadata Tags in App Router?</h2>
<p>Next.js makes it very easy for you to set metadata for your app and pages. The only thing you have to do is to <a href="https://nextjs.org/docs/app/building-your-application/optimizing/metadata#static-metadata">export a metadata object</a> from any layout or page file in your application to set the metadata for that layout/page and down.</p>
<pre><code class="language-typescript">import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Next.js Metadata Example',
  description: 'Example of metadata in Next.js',
}

export default function MyPage() { ... }
</code></pre>
<p>If you need dynamic data, see the question below.</p>
<h2>8. How To Set Metadata Dynamically for an App Router Page?</h2>
<p>For most SEO optimized applications, setting static metadata isn't enough, since data will be unique to almost every page and even be loaded at runtime from a server. To set metadata dynamically in a Next.js page, use the <a href="https://nextjs.org/docs/app/building-your-application/optimizing/metadata#dynamic-metadata">provided generateMetadata function</a>.</p>
<pre><code class="language-typescript">import type { Metadata } from 'next'

export async function generateMetadata(): Promise&#x3C;Metadata> {
  const data = await fetch('someUrl').then((res) => res.json())

  return {
    title: 'Next.js Dynamic Metadata Example',
    description: data.pageDescription,
  }
}

export default function MyPage() { ... }
</code></pre>
<p>Good to know is that the fetch function in Next.js by default caches duplicated requests. This is a general behavior, it isn't specific to metadata. Even requests in Server Components are cached when fetch is used. Although, it can be opted out from and even disabled automatically when certain Next.js features are used.</p>
<h2>9. Can I Set Metadata in a Layout File?</h2>
<p>Yes, you can set metadata in a layout file, both static and dynamically. Please see the questions about setting metadata above.</p>
<h2>10. Can I Use Contexts with App Router?</h2>
<p>It is possible to use React Contexts with the App Router in Next.js. You can preferably place the contexts in the root layout to make it available to all Client Components. The context will not be available to use in Server Components, and it will not mess up the render behavior of Server Components.</p>
<p>You can read about how it works in <a href="https://www.perssondennis.com/articles/do-contexts-in-nextjs-13-make-the-whole-app-render-on-the-client">this article</a>.</p>
<h2>11. How To Use React Context in Server Components?</h2>
<p>In Next.js, you can only use React contexts in Client Components. Server Components will not be affected by contexts in Client Components and it cannot read the context. See "<a href="https://www.perssondennis.com/articles/do-contexts-in-nextjs-13-make-the-whole-app-render-on-the-client">Do Contexts in Next.js 13 Make the Whole App Render on the Client?</a>" for more information.</p>
<p>However, dependent on your need, you might be fine with not having a context in your Server Component. By default, Next.js caches data retrieved in requests sent with the fetch function, meaning that you don't have to worry about duplicated request. If multiple Server Components need to fetch the same data, you can rely on the cache as an alternative to a sharing data through a context.</p>
<h2>12. Is it Possible to Render a Client Component in a Server Component?</h2>
<p>It's completely normal to <a href="https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#passing-props-from-server-to-client-components-serialization">render Client Components in Server Components</a>. All props which are passed to the Client Component must be serializable though. Data which isn't serializable must be handled from within the Client Component instead.</p>
<h2>13. Can I Pass Props from a Server Component to a Client Component?</h2>
<p>Yes it is possible to pass props from a Server Component to a Client Component. As mentioned in the previous question, the data must be serializable.</p>
<h2>14. Can I Use Server Components in Client Components?</h2>
<p>It is possible to user Server Components in a Client Component, but with limitations. You <a href="https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#unsupported-pattern-importing-server-components-into-client-components">cannot import Server Components in Client Components as usual</a>, they will not be Server Components when doing so. What you will have to do, is to <a href="https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#supported-pattern-passing-server-components-to-client-components-as-props">pass the Server Component as a prop or child to the Client Component</a>.</p>
<p>Note specifically, because this tricks many developers. Next.js claim that components are Server Components by default, and that you have to use the "use client" directive to make it a Client Component. That is not the whole truth, because when you import any component in a Client Component, the imported component will be a Client Component, not a Server Component.</p>
<p>As mentioned above, you have to pass the Server Component as a prop if it should be treated as a Server Component. Next.js don't complain if you import what you think are Server Components into Client Components, they are simply just treated as Client Components without any warnings. So if you think you are using a lot of Server Components, you may actually not have that many at all.</p>
<h2>15. Can I Pass Props from a Client Component to a Server Component?</h2>
<p>No, it isn't possible to pass props from a Client Component to a Server Component. Server Components are rendered into HTML on server already before Client Components are rendered.</p>
<h2>16. Can I Use Server Actions in Server Components?</h2>
<p>Yes of course, they are made for that. See <a href="https://nextjs.org/docs/app/api-reference/functions/server-actions#with-server-components">this example in the docs</a>.</p>
<h2>17. Can I Use Server Actions in Client Components?</h2>
<p>Yes, but with a caveat. You cannot use server actions directly in your Client Component. What you can do, is can write the server action in a separate file, and use it in a Client Component, like shown in <a href="https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#client-components">the docs</a>.</p>
<p>However, if you try to use server actions directly in a component like it is done in a Server Component, then you would get this error.</p>
<blockquote>
<p>It is not allowed to define inline "use server" annotated Server Actions in Client Components. │ To use Server Actions in a Client Component, you can either export them from a separate file with "use server" at the top, or pass them down through props from a Server Component.</p>
</blockquote>
<p>As you can read there, you have one more option. You can define the server action in a Server Component and pass it as a prop to the Client Component if you would want that.</p>
<h2>18. Are Server Actions Stable in Next.js?</h2>
<p>In Next.js 14 server actions are considered stable. One thing to note though, Next.js is built upon React features which are still marked as <a href="https://react.dev/reference/react/use-server">experimental</a>.</p>
<p>Server actions were experimental back in Next.js 13, so if in version 13, you will be asked to add server actions as an experimental feature in next.config.js</p>
<blockquote>
<p>to use server actions, please enable the feature flag in your next.js config.</p>
</blockquote>
<p>This is what you would need to add to next.config.js. Although I rather recommend to upgrade to Next.js 14.</p>
<pre><code class="language-markdown">  experimental: {
    serverActions: true,
  },
</code></pre>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>JavaScript</category>
            <category>Next.js</category>
            <enclosure url="https://www.perssondennis.com/images/articles/answers-to-common-nextjs-questions/answers-to-common-nextjs-questions.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Complete Guide To Make You a Regex Guru]]></title>
            <link>https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru</link>
            <guid>https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru</guid>
            <pubDate>Sun, 15 Jan 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Complete regex guide and cheat sheet 2023. Explains quantifiers, special characters, regex flags, special tokens and character classes with examples.]]></description>
            <content:encoded><![CDATA[<p>This is the second article in a series of regex articles. In <a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work">the first article</a>, you can read about common use cases for regex. This article explains everything you need to know about regex for daily usage, with both examples and cheat sheets. An upcoming article will later explain the most advanced use cases of regex, which unleashes the real power of regex, but which are rarely used.</p>
<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#explain-regex-like-im-five">Explain Regex Like I'm Five</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#what-is-the-syntax-for-regex">What is the Syntax for Regex?</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#most-common-regex-flags">Most Common Regex Flags</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#start-and-end-of-regexes">Start and End of Regexes</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#regular-characters-literal-characters">Regular Characters (Literal Characters)</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#special-characters-metacharacters">Special Characters (Metacharacters)</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#multi-special-characters">Multi-Special Characters</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#list-of-regular-characters-in-regex">List of Regular Characters in Regex</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#list-of-special-characters-in-regex">List of Special Characters in Regex</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#special-tokens">Special Tokens</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#quantifiers-repetition-of-characters">Quantifiers - Repetition of Characters</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#character-classes">Character Classes</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#negative-character-classes">Negative Character Classes</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#combine-character-classes-with-quantifiers">Combine Character Classes with Quantifiers</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#regex-groups-101-or-operator">Regex Groups 101 - Or Operator</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#greedy-modifier">Greedy Modifier</a></li>
<li><a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru#become-a-regex-sensei">Become a Regex Sensei</a></li>
</ol>
<h2>Explain Regex Like I'm Five</h2>
<p>Regex (or Regular expressions) is a language for searching for and matching patterns in text, using special characters to describe the type of characters or sequence of characters you want to find or replace.</p>
<p>Most fundamental thing to understand about regex is how it works when you don't write any kind of special characters or use any of the regex language specific features. In that case, each written character in the regex, will match the corresponding character in a text, if those characters are present in the text, just like a regular text search field.</p>
<p><img src="https://www.perssondennis.com/images/articles/complete-guide-to-make-you-a-regex-guru/how-does-regex-work.webp" alt="How does regex work">
<em>Results for when searching a text with the regex /all/gm</em></p>
<p>In the picture above, we can see the exact matches a regex will find in a string for the regex <em>/all/</em> with the flags <em>g</em> and <em>m</em>. It finds a total of six matches in the string.</p>
<p>Note that the regular expression is only used to find those six matches. What we want to do with the matches is up to us. A common thing to do is to replace the matched characters with other characters. In other case it is only necessary to know whether a text matches a regex or not, for example to be able to detect if a user has entered a valid email or not. To learn more about what regex is used for, please read <a href="https://www.perssondennis.com/articles/6-use-cases-for-regex-in-your-daily-work">the previous article in this series</a>.</p>
<p><a href="https://regex101.com/r/aXjsSV/1">Try writing regex on Regex101</a></p>
<h2>What is the Syntax for Regex?</h2>
<p>Regexes are often defined in between two forward slashes and followed by a few letters.</p>
<pre><code class="language-javascript">// Common syntax for a regex.
/someregex/ig
</code></pre>
<p>The slashes only defines that it is a regex we are writing, and the trailing letters are called flags which can alter how the regex should be interpreted.</p>
<p>In some languages we can define regexes in another way. For example, in JavaScript, you can use the <em>RegExp</em> constructor.</p>
<pre><code class="language-javascript">// In JavaScript you can define a regex with a regex constructor.
const myRegex = new RegExp('someregex', 'i');

// Above is the same as defining a regex with the standard slashes syntax.
const myRegex = /someregex/i;
</code></pre>
<p>In UIs, such as search fields in IDEs, it's common to allow regexes by enabling a regex button. When doing that, you normally don't need to write the surrounding slashes, and flags are sometimes possible to edit, but not always.</p>
<p><img src="https://www.perssondennis.com/images/articles/complete-guide-to-make-you-a-regex-guru/vscode-activate-regex-button.webp" alt="VS Code activate regex button">
<em>You can activate regex in VS Code search field with the button with the .* icon</em></p>
<p>A short note before we continue explaining flags. You should be aware of that the regex syntax can differ slightly between implementations in different programming languages. They do not all interpret regexes exactly the same, but most of them adhere very well to the standard.</p>
<h2>Most Common Regex Flags</h2>
<p>There are many regex flags. All languages and editors do not support all of them. I will therefore only present the most common ones here, which normally is supported.</p>
<p>The <em>i</em> and the <em>g</em> flag is far most used. The <em>s</em> and <em>m</em> flag is also something you will have to use some day, but not for certain.</p>
<h3>Flag: i</h3>
<p>The regex flag <em>i</em>, is the easiest flag to understand. What it does is to make the regex interpretation case <strong>i</strong>nsensitive. This means that the regex will match both capital and lower-case letters regardless of what you write. Without specifying this flag, regexes are case sensitive.</p>
<pre><code class="language-javascript">// This regex will not find a match in the string "Regex explained",
// since "Regex explained" has a capital R in it.
/regex explained/

// When using the i flag, this regex will match "Regex explained" string.
/regex explained/i
</code></pre>
<h3>Flag: g</h3>
<p>Another very common flag is the <em>g</em> flag, short for <strong>g</strong>lobal. That flag tells the regex interpretator to find all matches of the regex expression rather than only finding the first match, which it will do without the flag. That is best explained with a picture!</p>
<p><img src="https://www.perssondennis.com/images/articles/complete-guide-to-make-you-a-regex-guru/regex-g-flag.webp" alt="Regex g flag">
<em>The g flag tells the regex engine to find all possible matches, not just the first one</em></p>
<p>The tricky part here is probably not to understand what the g flag does, but when it matters. If you use a regex to only test if a text matches a pattern, such as when checking if a text contains your name, then the g flag doesn't really matter. Regardless of whether you find your name once, twice or a thousand times, the answer will be that it contains your name. The only difference is that the regex engine will have to work harder to find all thousand occurrences.</p>
<p>If you use the regex for another purpose, such as replacing all occurrences of a word in a text, then the g flag is something you would want, otherwise you would only replace the first occurrence of the word!</p>
<pre><code class="language-javascript">const text = 'What is regex? What can you do with regex?';

// Without the g flag, regex engine will only replace the first match of the regex.
console.log(text.replace(/regex/, 'love'));
// Output: What is love? What can you do with regex?

// With g flag, regex engine will replace all matches of the regex.
console.log(text.replace(/regex/g, 'love'));
// Output: What is love? What can you do with love?
</code></pre>
<p><a href="https://regex101.com/r/D3XKpE/1">Try g flag on Regex101</a></p>
<h3>Flag: s</h3>
<p><em>s</em> stands for <strong>s</strong>ingle line. It effectually means that the regex will be treated as a single line even if it contains new lines. Normally regexes will not search for matches over multiple lines. What it means in regex language, is that the dot regex character, which means any character, can match newline characters (\n).</p>
<p><img src="https://www.perssondennis.com/images/articles/complete-guide-to-make-you-a-regex-guru/regex-s-flag.webp" alt="Regex s flag">
<em>The s flag lets the regex engine ignore new line characters and treats the whole string as a single line</em></p>
<p>In the example above, the <em>.*</em> part of the regex means any amount of characters. That will be explained more in detail later in the article. For now, it's sufficient to understand that the s flag allows regexes to stretch over multiple lines.</p>
<p><a href="https://regex101.com/r/tGVlAI/1">Try m flag on Regex101</a></p>
<h3>Flag: m</h3>
<p><em>m</em> flag stands for <strong>m</strong>ulti line. Confusing? Didn't we just explain that above when we talked about single line? Don't worry, no need to raise a white flag.</p>
<p>While the <em>s</em> flag affects how the dot character is interpreted in a regex, the <em>m</em> flag affects how the start and end characters ^ and $ should be treated. Let's move on to talk about them now, m flag will be further explained there.</p>
<p><img src="https://www.perssondennis.com/images/articles/complete-guide-to-make-you-a-regex-guru/never-quit.webp" alt="Never quit">
<em>Wouldn't it be better if they just had worked together?</em></p>
<h2>Start and End of Regexes</h2>
<p>Writing a regex that ensures that a string starts and/or end with certain characters is a very common use case. Regex language uses a caret (<em>^</em>) to express the beginning of a string and a dollar sign (<em>$</em>) to represent the end of a string.</p>
<p>Normally, the start and the end of a regex indicates the start and end of the whole string the regex searches in, regardless of the number of lines in the string. The <em>m</em> character, changes the meaning of the caret and dollar sign so they instead represent the start and end of each line in a regex. In practice, that means that each newline character (<em>\n</em>) in the searched string will be treated as an end of a line, and also a start of a new line.</p>
<p><img src="https://www.perssondennis.com/images/articles/complete-guide-to-make-you-a-regex-guru/regex-m-flag.webp" alt="Regex m flag">
<em>The m flag changes the meaning of caret (^) symbol to match the beginning of a line instead of begging of the whole string</em></p>
<p>Note that we cannot always expect the caret and dollar sign to match start end ends of strings. That's probably why regex is such a complex language, because it changes meaning of characters dependent on the surrounding characters. Let's talk a bit about that, to clarify which characters are normal in regex and what all the special characters do.</p>
<p><a href="https://regex101.com/r/xfUSgH/1">Try m flag on Regex101</a></p>
<h2>Regular Characters (Literal Characters)</h2>
<p><strong>Alternative names</strong>: regular characters, literal characters</p>
<p>Flags, special characters, dots and carets which change meaning with flags... Are there no regular characters in regexes? Yes! There are! They are called literal characters and you can safely use those characters without having to worry about them being treated in a strange way.</p>
<ul>
<li><strong>Letters</strong>: a-z, both in upper-cases and lower-case</li>
<li><strong>Numbers</strong>: all numbers, 0 to 9</li>
</ul>
<p>Ya, that's about it... Wasn't that many after all.</p>
<p>Just joking, there's a lot of them! You have <em>@</em>, <em>&#x26;</em> and <em>%</em> for example. Actually most characters are regular characters. It is easier to learn which characters has a special meaning in regex and then expect every other character to be a regular character.</p>
<h2>Special Characters (Metacharacters)</h2>
<p><strong>Alternative names</strong>: special characters, metacharacters</p>
<p>The regex syntax includes quite many special characters which are used by a regex engine to understand the regex. These characters are called metacharacters. Metacharacter is a general term for a character that has a special meaning to a computer program, interpretator or in this case, a regex engine.</p>
<p>One example of a special character is the plus sign character (<em>+</em>) which means that the preceding character should exist one or multiple times (see quantifiers section). If you want the regex to interpret a special character as the character literal itself, you will need to escape it with a backslash character (<em>\</em>).</p>
<pre><code class="language-markdown">// The + character means that the character before it should exist at least once.
Regex /bun+y/ will match string "buny".
Regex /bun+y/ will match string "bunny".
Regex /bun+y/ will match string "bunnny".
Regex /bun+y/ will NOT match string "buy", because one n is required by the + sign.
Regex /bun+y/ will NOT match string "bu+y", because the plus character is treated as a metacharacter.

// If you want to match a + sign, you will need to escape it with a backslash.
Regex /bun\+y/ will match string "bun+y".
</code></pre>
<p>So in short, a special character is a character that needs to be escaped if it should be treated as the character itself in a regex. If not escaped, it will be a part of the regex syntax to describe to the regex engine how to interpret the regex.</p>
<p>We will soon see a full list of special characters in regex, but before that, we should look at what I call multi-special characters.</p>
<h2>Multi-Special Characters</h2>
<p><strong>Alternative names</strong>: special characters, metacharacters</p>
<p>Let's be honest, multi-special characters is not an official term, it's just something I am making up right now. That's because I need a way to differentiate multi-purpose special characters from singe-purpose special characters.</p>
<p>The confusing thing with regexes is that special characters aren't always special. Other special characters are always special, but they change meaning when combined with other special characters. That's why I refer to these special characters as multi-special, special characters which plays many roles in the regex syntax.</p>
<p>Luckily, there are not very many multi-special characters. One very important one though, is the hyphen character (<em>-</em>). It is normally interpreted as a regular hyphen character, but when a hyphen is used within a character class (square brackets), it is instead treated as a range character that defines a range of characters.</p>
<pre><code class="language-markdown">// A hyphen in a regex is normally treated as a hyphen literal.
Regex /a-d/i will match string "a-d".
Regex /a-d/i will NOT match the strings "a", "b", "c" or "d".

// Within square brackets, hyphen is treated as a range character.
Regex /[a-d]/i will NOT match strings "a", "-" or "d", because the hyphen is in a character class.
Regex /[a-d]/i will match the strings "a", "b", "c" and "d", because a-d is treated as a range of characters.

// If you want to match a hyphen in a character class, you need to escape it.
Regex /[a\-d]/i will match strings "a", "-" and "d", because hyphen is escaped.

// Meaning of square brackets is explained in detail in character classes section.
</code></pre>
<p>As mentioned before when talking about start and end characters, the caret character (<em>^</em>) can also change its meaning in regex. Just as the hyphen, it behaves differently within square brackets. It's then called negative character classes, which we will look at later in this article.</p>
<p>Now answer, does multi-special characters confuse you? No worries. You can think of them as any other special character, only thing you need to take with you is the knowledge that some special characters can be used for multiple things.</p>
<h2>List of Regular Characters in Regex</h2>
<table>
<thead>
<tr>
<th align="left">Character</th>
<th align="left">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Letters</td>
<td align="left">Letters a-z, both in upper-case and lower case.</td>
</tr>
<tr>
<td align="left">Language Specific Letters</td>
<td align="left">Often supported and treated as regular characters.</td>
</tr>
<tr>
<td align="left">Numbers</td>
<td align="left">All numbers are regular characters.</td>
</tr>
<tr>
<td align="left">&#x26;</td>
<td align="left">Ampersand is a regular character in regex.</td>
</tr>
<tr>
<td align="left">@</td>
<td align="left">At sign is a regular character in regex.</td>
</tr>
<tr>
<td align="left">,</td>
<td align="left">Comma is a regular character in regex.</td>
</tr>
<tr>
<td align="left">#</td>
<td align="left">Hashtag is a regular character in regex.</td>
</tr>
<tr>
<td align="left">%</td>
<td align="left">Percentage sign is a regular character in regex.</td>
</tr>
<tr>
<td align="left">_ (underscore)</td>
<td align="left">Underscore is a regular character in regex.</td>
</tr>
</tbody>
</table>
<p>This list isn't complete since there are endless of regular characters. If in doubt, look in the list of special characters which is a complete list.</p>
<h2>List of Special Characters in Regex</h2>
<p>Each special character is described in detail in this article. This list also refers to the terms lookahead and lookbehinds. Those are used for advanced use cases and will be explained in another article.</p>
<table>
<thead>
<tr>
<th align="left">Character</th>
<th align="left">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">- (hyphen)</td>
<td align="left">Treated as a hyphen literal, or a range character if it's within a character class. Will need to be escaped to be treated as a hyphen when it's used in character classes.</td>
</tr>
<tr>
<td align="left">=</td>
<td align="left">Equal sign is treated as a regular character unless it is used to define a lookahead or lookbehind expression, <em>(?=)</em> or <em>(?&#x3C;=)</em>.</td>
</tr>
<tr>
<td align="left">!</td>
<td align="left">An exclamation mark is a regular character unless it is used to define a negative lookahead or negative lookbehind expression, <em>(?!)</em> or <em>(?&#x3C;!)</em>.</td>
</tr>
<tr>
<td align="left">?</td>
<td align="left">A question mark is a quantifier for an optional character. Can also serve as a greedy modifier when it follows a quantifier, which is explained at the end of this article. Lastly used in lookahead and lookbehind syntax when placed as the first character in a set of parentheses (?!), (?=,) (?&#x3C;=) or (?&#x3C;!).</td>
</tr>
<tr>
<td align="left">{}</td>
<td align="left">Used in syntax for quantifiers and is otherwise treated as regular curly braces.</td>
</tr>
<tr>
<td align="left">[]</td>
<td align="left">Square brackets are the syntax for character classes.</td>
</tr>
<tr>
<td align="left">\</td>
<td align="left">Backslash is used to escape characters or to write special tokens such as newline character (\n). If you need to match a backslash sign, you need to escape it with another backslash.</td>
</tr>
<tr>
<td align="left">+</td>
<td align="left">Plus sign is a quantifier to tell that the preceding character or should be matched one or more times.</td>
</tr>
<tr>
<td align="left">*</td>
<td align="left">Asterisk is a quantifier to tell that the preceding character or should be matched zero or more times.</td>
</tr>
<tr>
<td align="left">.</td>
<td align="left">A dot character is used to match any other character. Will only match a single character unless combined with a a quantifier. It does not match a newline character unless the s flag is used.</td>
</tr>
<tr>
<td align="left">|</td>
<td align="left">Pipe character is used as an <em>or</em> operator.</td>
</tr>
<tr>
<td align="left">/</td>
<td align="left">Slash i often used to enclose a regex in programming languages. It will have to be escaped with a backslash if it should be treated as a slash literal.</td>
</tr>
<tr>
<td align="left">"</td>
<td align="left">Double quote is treated as a regular character in regex, but may need to be escaped in programming languages if the regex is a part of a string that is defined with double quotes.</td>
</tr>
<tr>
<td align="left">'</td>
<td align="left">Singe quote is treated as a regular character in regex, but may need to be escaped in programming languages if the regex is a part of a string that is defined with single quotes.</td>
</tr>
<tr>
<td align="left">&#x3C;></td>
<td align="left">Less than and greater than characters are treated as regular characters unless they are used to define a positive or negative lookbehind expression, <em>(?&#x3C;=)</em> or <em>(?&#x3C;!)</em>.</td>
</tr>
<tr>
<td align="left">^</td>
<td align="left">Caret is used to define the start of the string. When the <em>m</em> flag is used, it matches the start of each line separated by a newline character (<em>\n</em>). Carets are also used in the syntax for negative character classes, <em>[^]</em>.</td>
</tr>
<tr>
<td align="left">$</td>
<td align="left">Dollar sign is used to define the end of a string. When the <em>m</em> flag i used, it matches the end of each line separated by a newline character (<em>\n</em>) will be treated as the end of a line.</td>
</tr>
<tr>
<td align="left">()</td>
<td align="left">Parentheses are used to define character groups.</td>
</tr>
</tbody>
</table>
<h2>Special Tokens</h2>
<p><strong>Alternative names</strong>: special characters, metacharacters</p>
<p>When googling regex you will see people name things differently on every site. Therefore you may know special tokens as just metacharacters, special characters or just tokens. In this article, I do call them special tokens, because syntactically they look different to the other special characters in regex.</p>
<p>Looking at the syntax, they are kind of the opposite to other special characters, because special tokens use the backslash escape character, in front of an otherwise normal character literal, to make it be interpreted as a special character.</p>
<p>Below is a list of special tokens. As you can see, it is possible to write most of them in alternative ways. This table is not complete. Many special tokens has been omitted here since they are rarely used or seen.</p>
<table>
<thead>
<tr>
<th align="left">Token</th>
<th align="left">Description</th>
<th align="left">Alternatives</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">\d</td>
<td align="left">Matches a single digit</td>
<td align="left">[0-9], [0123456789]</td>
</tr>
<tr>
<td align="left">\D</td>
<td align="left">Opposite to \d. Matches any character that isn't a digit</td>
<td align="left">[^0-9], [^0123456789]</td>
</tr>
<tr>
<td align="left">\w</td>
<td align="left">Matches any letter in alphabet, any number and underscore</td>
<td align="left">[a-zA-Z0-9_]</td>
</tr>
<tr>
<td align="left">\W</td>
<td align="left">Opposite to \w. Matches any character that is not a number, underscore or a letter in the latin alphabet</td>
<td align="left">[^a-zA-Z0-9_]</td>
</tr>
<tr>
<td align="left">\s</td>
<td align="left">Matches a whitespace character</td>
<td align="left">Regular space character usually works, but note that also tabs, new lines and a few other whitespace character exist.</td>
</tr>
<tr>
<td align="left">\S</td>
<td align="left">Opposite to \s. Matches any character but whitespace</td>
<td align="left">See \s for more info.</td>
</tr>
<tr>
<td align="left">\n</td>
<td align="left">Matches a newline character</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">\r</td>
<td align="left">Matches a carriage return character</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">\t</td>
<td align="left">Matches a horizontal tab character</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">\b</td>
<td align="left">Matches a word boundary, which is the start or end of a word. So the regex <em>/\bex/</em> matches <em>ex</em> in <em>example</em>, but not the <em>ex</em> in <em>regex</em>.</td>
<td align="left">One may think whitespace character \s would be the same as \b, but unlike \b, \s doesn't work in the beginning or end of a sentence, since there are no whitespaces there.</td>
</tr>
<tr>
<td align="left">\B</td>
<td align="left">Opposite to \b. Ensures that it isn't the beginning or end of a word.</td>
<td align="left"></td>
</tr>
</tbody>
</table>
<h2>Quantifiers - Repetition of Characters</h2>
<p><strong>Alternative names</strong>: occurrence indicators, repetition operators</p>
<p>Normally when writing a character in a regex, the regex engine will only match one and exactly one of that character. There are some special characters in the regex syntax which can be used to change that behavior. These special characters are called quantifiers and are always placed directly after the character it will affect.</p>
<p>As an example, the question mark character means that the previous character should be present 0 or 1 times, which basically means that it's an optional character. The question mark can for example be used to accept both American and English spelling.</p>
<pre><code class="language-markdown">// The question mark quantifier can be used to match a character zero or one time.
Regex /colou?r/ will match the string "color".
Regex /colou?r/ will match the string "colour".
Regex /colou?r/ will NOT match the string "colouur".
</code></pre>
<p>All other quantifiers work in the same way. They demand the preceding character to be repeated a certain amount of times.</p>
<table>
<thead>
<tr>
<th align="left">Character</th>
<th align="left">Description</th>
<th align="left">Example</th>
<th align="left">Match</th>
<th align="left">No Match</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">?</td>
<td align="left">Matches the preceding character zero or one time</td>
<td align="left">bun?y</td>
<td align="left">buy, buny</td>
<td align="left">bunny</td>
</tr>
<tr>
<td align="left">*</td>
<td align="left">Matches the preceding character zero or more times</td>
<td align="left">bun*y</td>
<td align="left">buy, buny, bunny</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">+</td>
<td align="left">Matches the preceding character one or more times</td>
<td align="left">bun+y</td>
<td align="left">buny, bunny</td>
<td align="left">buy</td>
</tr>
<tr>
<td align="left">{2}</td>
<td align="left">Matches the preceding character exactly two times</td>
<td align="left">bun{2}y</td>
<td align="left">bunny</td>
<td align="left">buy, buny, bunnny</td>
</tr>
<tr>
<td align="left">{2,4}</td>
<td align="left">Matches the preceding character two to four times</td>
<td align="left">bun{2,4}y</td>
<td align="left">bunny, bunnny, bunnnny</td>
<td align="left">buy, buny, bunnnnny</td>
</tr>
<tr>
<td align="left">{2,}</td>
<td align="left">Matches the preceding character two or more times</td>
<td align="left">bun{2,}y</td>
<td align="left">bunny, bunnny, bunnnny, bunnnnny</td>
<td align="left">buy, buny</td>
</tr>
</tbody>
</table>
<h2>Character Classes</h2>
<p><strong>Alternative names</strong>: bracket expressions</p>
<p><strong>Syntax</strong>: []</p>
<p>Character classes is a very important part of regex. It allows you do declare a set of characters to match instead of specifying one exact character to match. To use it, write all alternative characters within square brackets ([]).</p>
<pre><code class="language-markdown">// One and only one of the characters in a character group will be matched.
Regex /optimi[sz]ation/ will match both "optimization" and "optimisation".
Regex /optimi[sz]ation/ will NOT match "optimiation", because either s or z is required.
Regex /optimi[sz]ation/ will NOT match "optimiszation", because only one of s and z is allowed.
</code></pre>
<p>In the example above, you can see that when a character class is defined, a regex engine will only accept one of the characters in the group to be present. If you would want to match more than one of the characters, you can combine it with a quantifier.</p>
<pre><code class="language-markdown">// Combine a character class with a quantifier if you want to accept more
// than one of the characters within the group to be matched.
Regex /m[isp]+/ will match "mississippi".
Regex /m[isp]+/ will match "miss".
Regex /m[isp]+/ will NOT match "sim", because m must be placed before i, s and p.
</code></pre>
<p>In many cases, you may want to put a lot of characters into a character class. Declaring all of them can be cumbersome though. In that case, you can define a range of characters in the character class. The syntax for a range is two characters with a hyphen in between them, such as a-z and 0-9.</p>
<pre><code class="language-markdown">Regex /[a-z]/ will match any one character in the alphabet.
Regex /[a-z]/ will NOT match a number.
Regex /[a-z]/ will NOT match a whitespace character.
Regex /[a-z]+/ will match any characters in the alphabet, one or multiple (i.e. a word).
Regex /a[a-z]+/ will match any word starting with the letter a.
Regex /a[a-z]+a/ will match any word starting and ending with an a.
Regex /a[a-z]+a/ will NOT match "a hyena", because whitespace is not included in the character class.
Regex /a[a-z ]+a/ will match "a hyena", because whitespace is now included in the character class.
Regex /a[a-z\s]+a/ will match "a hyena", because \s represents a whitespace character.
</code></pre>
<p>You can define any number of ranges in a character group, just add them as you need.</p>
<pre><code class="language-markdown">Regex /[1-3]/ will match one of the integers 1, 2 and 3.
Regex /[1-36-9]/ will match one of the integers 1, 2, 3, 6, 7, 8, 9
Regex /[6-91-3]/ is the same as above, just a suspicious way to write it...
Regex /[1-36-9]/ will NOT match any of the integer 4, 5 or 6.
Regex /[a-z0-9] will match any lower-case letter or any integer.
Regex /[0-15-7A-Ceg]/ will match any of the characters 0, 1, 5, 6, 7, A, B, C e and g.
</code></pre>
<pre><code class="language-markdown">// Remember that regexes are case sensitive without the i flag?
Regex /[a-z]/ will match any lower case letter.
Regex /[A-Z]/ will match any upper case letter.
Regex /[a-zA-Z]/ will match any letter, upper or lower case.
Regex /[a-z]/i will match any letter, upper or lower case, because the i flag is specified.
</code></pre>
<p>Now, do you remember reading about multi-special characters? Characters which can both behave as a regular character and a special character. A hyphen is one of those. Most often, it is treated as a normal character, but within a character class it is instead used as the range syntax. This also means that you will have to escape the hyphen character if you would want the character class to use it to find matches.</p>
<pre><code class="language-markdown">Regex /[a-c]+/ will match "aaa", "abc", "acb" and "cccccc".
Regex /[a-c]+/ will match NOT matchc "a-a", because it contains a hyphen.
Regex /[a\-c]+/ will match "a-a", "a-c", and "c-a", because the hyphen is escaped (and treated as a hyphen character).
Regex /[a\-c]+/ will NOT match "abc", because the hyphen is not a range character, so b is not included in the character class.
Regex /[a-c\-]+/ will match "a-a" and "abc", because we both have a regular hyphen and a range character in the character class.
Regex /a-[cd]/ will match "a-c" and "a-d", because a hyphen outside a character class is treated as a hyphen.
Regex /a-[cd]/ will NOT match "ac" or "ad", because the hyphen is required.
</code></pre>
<p>You will use character classes a lot when writing regex. Although, most of the times you will use the same ones over and over again. The ranges a-z, A-Z and 0-9 is very common to use in regexes, especially when they are combined with quantifiers to match any word or sequences of words.</p>
<pre><code class="language-markdown">Regex /[a-z]+/ will match any word, but no whitespaces.
Regex /[a-z\s]+/ will match multiple words.
Regex /the[a-z\s]+green/ will match any text that starts with "the" and ends with "green".
</code></pre>
<p>Observant readers may have noticed that I used the special token \s as a replacement for a whitespace within a character group in one of the examples here above. You can use the special tokens within character classes as normal, just as you would use them outside of a character class.</p>
<pre><code class="language-markdown">Regex /a\scobra/ will match "a cobra".
Regex /a\scobra/ will NOT match "acobra", because the whitespace is required.
Regex /a[abcor\s]/ will match "a cobra".
Regex /a[abcor\s]/ will match "acobra", because the whitespace is not required.
</code></pre>
<h2>Negative Character Classes</h2>
<p><strong>Alternative names</strong>: negative bracket expressions</p>
<p><strong>Syntax</strong>: [^]</p>
<p>When you write a caret (^) at beginning of a character class, it will be treated as a negative character class. Negative character classes are the opposite to character classes. They work in the same way as character classes, but instead of declaring which characters to be present, it instead defines which characters that must no be present.</p>
<pre><code class="language-markdown">Regex /pineapple/ will match "pineapple".
Regex /pin[e]apple/ will match "pineapple".
Regex /pin[^e]apple/ will NOT match "pineapple", because the letter e is not allowed between n and a.
Regex /pin[^e]apple/ will match "pinkapple", because it is only the e between the n and a that is forbidden.
</code></pre>
<h2>Combine Character Classes with Quantifiers</h2>
<p>Just as with regular character literals and special tokens, character classes only substitutes a single character unless combined with a quantifiers.</p>
<pre><code class="language-markdown">Regex /[0-9]/ will match 3 or 8, but NOT 38.
Regex /[0-9][0-9]/ will match 38, but NOT 3 or 8.
Regex /[0-9]{2}/ will match 38, but NOT 3 or 8.
Regex /[0-9]{1-2}/ will match 38, 3 or 8.
Regex /[0-1][0-9]{2}/ will match a three digit number starting with 0 or 1.
Regex /0[1-9]{2}-[0-9]{7}/ will match a phone number on format 0XX-XXXXXXX.
Regex /[0-1]+/ will match any binary number.
</code></pre>
<h2>Regex Groups 101 - Or Operator</h2>
<p>Groups is one of the most difficult things to understand with regex, and they are rarely needed in daily work. For that reason, they will be explained in the next article in this regex series. Right now, we will satisfy by look at a simple and very frequent use case of it, to include only one of two or more words in regex. To do that, we use the <em>or</em> operator, the pipeline character.</p>
<pre><code class="language-markdown">Regex /(a|b)c/ will match "ac" or "bc", but NOT "abc".
Regex /(a|b)c/ will NOT match "c", because a or b is required.
Regex /optimi(s|z)ation/ will match "optimisation" or "optimization".
Regex /(red|blue)/ will match "red" or "blue", but NOT "redblue" or "lue".
Regex /(red|blue) color/ will match "red color" or "blue color", but NOT " color".
</code></pre>
<h2>Greedy Modifier</h2>
<p><strong>Alternative names</strong>: greedy quantifier, greedy operator</p>
<p>We have already seen that the question mark symbol can be used as a quantifier to specify that the preceding character shall be matched zero or one times. The question mark has another important usage in regex though, it is also used as the greedy modifier, which makes a quantifier "lazy" instead of "greedy".</p>
<p>Normally, quantifiers are greedy. This means that they will try to match as many characters as possible. If the greedy modifier is added after a quantifier, that quantifier will instead match as few characters as possible.</p>
<p><img src="https://www.perssondennis.com/images/articles/complete-guide-to-make-you-a-regex-guru/regex-greedy-modifier.webp" alt="Regex greedy modifier">
<em>The greedy modifier makes the preceding character match as few characters as possible</em></p>
<p><a href="https://regex101.com/r/rr65dJ/1">Try greedy modifier on Regex101</a></p>
<h2>Become a Regex Sensei</h2>
<p>We have now went through almost everything there is to know about regex syntax. There are a few things left to know to take the step from regex expert to ninja. Those things will be covered in an upcoming article.</p>
<blockquote>
<p>If you enjoy regex and puzzle games, you can the <a href="https://www.perssondennis.com/games/perssons-pyramid">programmer puzzle game</a> at my website. Regex will be needed to know for the more advanced levels!</p>
</blockquote>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>JavaScript</category>
            <category>Productivity</category>
            <enclosure url="https://www.perssondennis.com/images/articles/complete-guide-to-make-you-a-regex-guru/complete-guide-to-make-you-a-regex-guru.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Do Contexts in Next.js 13 Make the Whole App Render on the Client?]]></title>
            <link>https://www.perssondennis.com/articles/do-contexts-in-nextjs-13-make-the-whole-app-render-on-the-client</link>
            <guid>https://www.perssondennis.com/articles/do-contexts-in-nextjs-13-make-the-whole-app-render-on-the-client</guid>
            <pubDate>Sun, 30 Jul 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Can React contexts be used with Next.js 13? Yes, they can, Server Components will work as expected. ✓ Next.js 13 ✓ React Contexts ✓ Server Components ✓ App Router]]></description>
            <content:encoded><![CDATA[<p>React contexts are quite crucial for React development. Most projects depends on it, either directly or through libraries. The question is, can they be used with Next.js 13 App Router? And can the application still benefit from the power of Server Components when contexts are used? Let's answer that!</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/do-contexts-in-nextjs-13-make-the-whole-app-render-on-the-client#difference-between-client-and-server-components">Difference Between Client and Server Components</a></li>
<li><a href="https://www.perssondennis.com/articles/do-contexts-in-nextjs-13-make-the-whole-app-render-on-the-client#can-i-use-react-context-in-server-components">Can I Use React Context in Server Components?</a></li>
<li><a href="https://www.perssondennis.com/articles/do-contexts-in-nextjs-13-make-the-whole-app-render-on-the-client#will-my-complete-nextjs-application-be-rendered-on-client-if-i-use-react-contexts">Will My Complete Next.js Application Be Rendered on Client if I Use React Contexts?</a></li>
</ul>
<h2>Difference Between Client and Server Components</h2>
<p>For this article to make sense, you should have grasp about what the difference between Client Components and Server Components are. In Short, Client Components are regular old React components rendered with JavaScript on the client, while Server Components are React components which are rendered into HTML on the server. The rendered Server Components can then be used as none-interactive components anywhere in the applications React tree.</p>
<p>Does it make sense? If not, you can learn more about Server Components, read <a href="https://nextjs.org/docs/getting-started/react-essentials">Next.js docs about it</a> or my article about, <a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web">why Server Components matter</a>.</p>
<h2>Can I Use React Context in Server Components?</h2>
<p>React contexts are well used in React applications to share states between components. Since Client Components and Server Components are rendered on different machines, the client and the server, you might think that React contexts cannot be used.</p>
<p>Server Components are simply HTML markup which certainly don't have a React state. If you try to use a context in a Server Component it will throw an error.</p>
<pre><code class="language-markdown">ReactServerComponentsError:

You're importing a component that needs useContext. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.

-[/path/to/file/MyComponent.ts:1:1]
1 | import { useContext } from 'react'
</code></pre>
<p>While Server Components are incompatible with React contexts, Client Components can handle them perfectly fine. As long as you provide the context provider in a Client Component, all Client Components in that component's child-tree will be able to read and use the context. It doesn't matter whether you have any Server Components in the sub-tree or not, Server Components are HTML markup, which don't care!</p>
<p><img src="https://www.perssondennis.com/images/articles/do-contexts-in-nextjs-13-make-the-whole-app-render-on-the-client/server-components-dont-care.webp" alt="Server components don&#x27;t care meme">
<em>It's not you, he's always like that...</em></p>
<h2>Will My Complete Next.js Application Be Rendered on Client if I Use React Contexts?</h2>
<p>The answer is no. Your whole site will not be forced to render on the client if you use React contexts. As mentioned, Server Components do not care about contexts, which also means it doesn't interfere with them.</p>
<p>Let's list a few statements about Next.js App Router.</p>
<ol>
<li>The <a href="https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#root-layout-required">RootLayout in Next.js is always a Server Component</a></li>
<li>The children prop passed to RootLayout is also a Server Component</li>
<li>Server Components can include Client Components (the Client Components <a href="https://nextjs.org/docs/getting-started/react-essentials#composing-client-and-server-components">will be ignored</a> when the server renders the Server Component)</li>
<li>Server Components can be included in Client Components if they are <a href="https://nextjs.org/docs/getting-started/react-essentials#recommended-pattern-passing-server-components-to-client-components-as-props">passed as children to the Client Component</a></li>
</ol>
<p>Now look at this code example, it's taken from <a href="https://vercel.com/guides/react-context-state-management-nextjs">Next.js guide for how to set up contexts</a>.</p>
<pre><code class="language-typescript">import { ContextProviders } from './providers';

export default function RootLayout({ children }) {
  return (
    &#x3C;html>
      &#x3C;body>
        &#x3C;ContextProviders>{children}&#x3C;/ContextProviders>
      &#x3C;/body>
    &#x3C;/html>
  );
}
</code></pre>
<p>What we can see in that code is:</p>
<ul>
<li>The Root Layout, which is a Server Component by statement #1</li>
<li>The ContextProviders component which includes the contexts is a Client Component (statement #3 allows that)</li>
<li>The children prop for the RootLayout is a Server Component (statement #2)</li>
<li>The children is passed to the ContextProviders Client Component (accepted by statement #4)</li>
</ul>
<p>By default, Next.js can handle intervened Client and Server Components, and with this setup we are following all the rules of how to use the components. The above code will result in a React tree looking as below.</p>
<pre><code class="language-xml">&#x3C;RootLayout (Server Component)>
  &#x3C;ContextProviders (Client Component)>
    &#x3C;Page (Server Component)>
      &#x3C;Potential other Client Components using the context />
      &#x3C;Potential other Server Components ignoring the context />
    &#x3C;/Page>
  &#x3C;/ContextProviders>
&#x3C;/RootLayout>
</code></pre>
<p>Although using contexts work fine, it does create a bit of confusion. You must remember that you will only be able to use the context within Client Components, the context is not available on the server.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>JavaScript</category>
            <category>Next.js</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/do-contexts-in-nextjs-13-make-the-whole-app-render-on-the-client/do-contexts-in-nextjs-13-make-the-whole-app-render-on-the-client.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Errors Received When Migrating Next.js 13 to New App Folder]]></title>
            <link>https://www.perssondennis.com/articles/errors-received-when-migrating-nextjs-13-to-new-app-folder</link>
            <guid>https://www.perssondennis.com/articles/errors-received-when-migrating-nextjs-13-to-new-app-folder</guid>
            <pubDate>Sun, 18 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Solutions to common Next.js errors when using app folder and server components. ✓ Next.js 13 ✓ Server Components ✓ Client Components ✓ App folder ✓ TypeScript]]></description>
            <content:encoded><![CDATA[<p>Next.js is evolving. Fairly recently, Next.js has added a new powerful routing mechanism which is used but adding files to the a <em>app</em> folder instead of the old <em>pages</em> folder. With new routing and new features like Server Components, comes also new errors to detect. This article will present solutions to four errors which are likely to happen the first hour of trying out the new Next.js features.</p>
<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/errors-received-when-migrating-nextjs-13-to-new-app-folder#exporting-async-server-component-when-fetching-data">Exporting Async Server Component When Fetching Data</a></li>
<li><a href="https://www.perssondennis.com/articles/errors-received-when-migrating-nextjs-13-to-new-app-folder#server-components-are-not-the-same-as-client-components">Server Components Are Not the Same as Client Components</a></li>
<li><a href="https://www.perssondennis.com/articles/errors-received-when-migrating-nextjs-13-to-new-app-folder#using-client-side-hooks-in-server-components">Using Client-Side Hooks in Server Components</a></li>
<li><a href="https://www.perssondennis.com/articles/errors-received-when-migrating-nextjs-13-to-new-app-folder#infinite-loading-with-nextjs-13-development-server">Infinite Loading With Next.js 13 Development Server</a></li>
<li><a href="https://www.perssondennis.com/articles/errors-received-when-migrating-nextjs-13-to-new-app-folder#should-you-use-nextjs-13">Should You Use Next.js 13?</a></li>
</ol>
<h2>Exporting Async Server Component When Fetching Data</h2>
<p><em><strong>Error</strong>: 'MyComponent' cannot be used as a JSX component. Its return type 'Promise' is not a valid JSX element</em></p>
<p><em><strong>Reason to error</strong>: You are using an old version of TypeScript</em></p>
<p><em><strong>Solution</strong>: Bump TypeScript or suppress the error with @ts-expect-error</em></p>
<p><em><strong>Note</strong>: This error is a TypeScript error. Next.js 13 is TypeScript-first. which means you have to opt-out of it if you don't want it</em></p>
<p>To fetch data in server components, Next.js recommends trying out their <a href="https://nextjs.org/docs/app/building-your-application/data-fetching/fetching">built-in fetch API</a> which is based on an RFC. Their <a href="https://nextjs.org/docs/app/building-your-application/data-fetching/fetching">example code</a> for that uses an async Page function.</p>
<p>The problem arise when trying to use an async component like that in another page component. Doing that, will result in a TypeScript error.</p>
<pre><code class="language-markdown">'MyComponent' cannot be used as a JSX component.
  Its return type 'Promise&#x3C;Element>' is not a valid JSX element.
  Type 'Promise&#x3C;Element>' is missing the following properties from type 'ReactElement&#x3C;any, any>': type, props, key
</code></pre>
<p>The error is thrown since the used TypeScript version doesn't recognize the async component. The <a href="https://github.com/vercel/next.js/issues/42292">issue has been solved recently in TypeScript version 5.1.3</a>, but if you are bootstrapping templates or if you are checking out old git repositories you may have an outdated TypeScript version.</p>
<p>The solution is therefore to bump TypeScript version. If that for some reason cannot be done, you can suppress the warning with @ts-expect-error, which was the recommended solution from Next.js before it was fixed in TypeScript.</p>
<pre><code class="language-typescript">export default function Home() {
  return (
    &#x3C;main>
      {/* @ts-expect-error Server Component */}
      &#x3C;MyComponent />
    &#x3C;/main>
  )
}
</code></pre>
<h2>Server Components Are Not the Same as Client Components</h2>
<p><em><strong>Error</strong>: You're importing a component that needs useState. It only works in a Client Component</em></p>
<p><em><strong>Reason to error</strong>: You are using client-side only functionality in a Server Component</em></p>
<p><em><strong>Solution</strong>: Add 'use client' directive to convert the Server Component to a Client Component</em></p>
<p>The most fundamental part when upgrading to Next.js 13 is to understand Server Components and Client Components. Traditionally in React and Single Page Applications (SPA) overall, the application has been rendered on the client side, in contrast to even more traditional websites that were rendered on the server. In modern programming, rendering is shared between the client and the server.</p>
<p>Next.js 13 gives you the full power to granularly fine-tune where you want to render each of your component, either on client or server, dependent on your needs. If you don't actively state that a Client Component should be a Client Component, you will run into a ReactServerComponentsError error.</p>
<pre><code class="language-markdown">ReactServerComponentsError:

You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.

-[/path/to/file/MyComponent.ts:1:1]
1 | import { useState } from 'react'
</code></pre>
<p>The error above will show up when you have a component or hook which uses some client-side only functionality, but which isn't explicitly declared with a "use client" directive.</p>
<pre><code class="language-javascript">import { useState } from 'react'

const MyComponent = () => {
  const [value, setValue] = useState()

  // Some code...

  return &#x3C;div>{value}&#x3C;/div>
}

export default MyComponent
</code></pre>
<p>To fix the error, simply add the "use client" directive at the top of the file.</p>
<pre><code class="language-javascript">'use client'

import { useState } from 'react'

const MyComponent = () => {
  const [value, setValue] = useState()

  // Some code...

  return &#x3C;div>{value}&#x3C;/div>
}

export default MyComponent
</code></pre>
<p>Before you convert your component to a Client Component, take a minute to reflect over if you really need a Client Component or if you are better off with a Server Component. I think <a href="https://nextjs.org/docs/getting-started/react-essentials#when-to-use-server-and-client-components">Next.js explains very well which one to use</a> with a simple table.</p>
<p><img src="https://www.perssondennis.com/images/articles/errors-received-when-migrating-nextjs-13-to-new-app-folder/nextjs-client-vs-server-components.webp" alt="Differences between Client and Server Components in Next.js">
<em>A good rule of thumb, only use a Client Component if you need browser functionality or keeping a state</em></p>
<p>In short, one can say, components and hooks which uses useState, useReducer and useEffect are client-side components/hooks.</p>
<p>Secondly, components which relies on user interactions via the DOM tree are client-side, which means that DOM elements which have attached listeners like onClick and onChange belongs to Client Components.</p>
<p>A third case is also when the component or hook relies on a web API such as <a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API">Geolocation API</a>. There exist <a href="https://developer.mozilla.org/en-US/docs/Web/API">a lot of Web APIs</a>, and they are often meant to run in a browser.</p>
<h2>Using Client-Side Hooks in Server Components</h2>
<p><em><strong>Error</strong>: Attempted to call the default export of /path/to/file/file.ts from the server but it's on the client</em></p>
<p><em><strong>Reason to error</strong>: You are using client side functions in a Server Component</em></p>
<p><em><strong>Solution</strong>: Convert the component to a Client Component or create a sub-client-component which uses the hook</em></p>
<p>In the previous header, we learned briefly what Server Components and Client Components, are and that we have to mark Client Components with the "use client" directive. That error was then resolved by using the directive, since Client Components can be used anywhere in Server Components. However, if the component you converted to a client component is a hook, you may see another error as well.</p>
<p>Let's say we have this hook:</p>
<pre><code class="language-javascript">'use client'

import { useState } from 'react'

const useSomeClientOnlyCode = () => {
  const [value, setValue] = useState()

  // Some code...

  return { value }
}

export default useSomeClientOnlyCode
</code></pre>
<p>Then we use it in a Server Component as follow:</p>
<pre><code class="language-javascript">import useSomeClientOnlyCode from '@/hooks/useSomeClientOnlyCode'

const MyServerComponent = async () => {
  const { value } = useSomeClientOnlyCode()

  return(&#x3C;div>{value}&#x3C;/div>)
}
</code></pre>
<p>If we run this code, we will see an error like this:</p>
<pre><code class="language-markdown">Error: Attempted to call the default export of /path/to/file/useSomeClientOnlyCode.ts from the server but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.
    at Component (./app/server-components/MyServerComponent.tsx:12:118)
    at stringify (&#x3C;anonymous>)
</code></pre>
<p>What is happening here, is that the hook contains client-side only code and is used in a Server Component. Whilst Next.js supports Client Components in Server Component, they don't support client functions or hooks to be used in Server Components.</p>
<p>Hooks are essentially just a part of a component, so if a hook uses client-side logic, then the whole component must be a client side Component as well.</p>
<p>The trivial way to solve this error is therefore to declare the component which uses the hook as a Client Component, by using the "use client" directive.</p>
<pre><code class="language-javascript">'use client'

import useSomeClientOnlyCode from '@/hooks/useSomeClientOnlyCode'

const MyServerComponent = async () => {
  const { value } = useSomeClientOnlyCode()

  return(&#x3C;div>{value}&#x3C;/div>)
}
</code></pre>
<p>If you don't want to convert your whole component to a Client Component you can always lift out the parts of the component which utilizes the hook into a child component, and then make the child component a Client Component.</p>
<pre><code class="language-javascript">const MyServerComponent = async () => {
  return(&#x3C;div>
    &#x3C;MyClientComponentWhichUsesTheHook />
    &#x3C;div>Some other server rendered elements...&#x3C;/div>
  &#x3C;/div>)
}
</code></pre>
<h2>Infinite Loading With Next.js 13 Development Server</h2>
<p><em><strong>Error</strong>: Node.js development server does not work</em></p>
<p><em><strong>Reason to error</strong>: Varies, in my case I had an async Client Component</em></p>
<p><em><strong>Solution</strong>: In this case, remove the async keyword</em></p>
<p>Next.js 13 introduces a new <em>app</em> folder, which offers a new and improved way to perform routing. I have been using Next.js 13 a long time with the old <em>pages</em> folder without any issues with the development server or build, but as soon as I tried to use the new <em>app</em> folder I ran into severe problems. The development server wasn't working.</p>
<p>What happened in detail was that the web page never finished loading. Next.js hot reloading didn't work, and the page stopped responding. Even when I stopped the development server it continued to serve a non-working build on the port.</p>
<p>I read GitHub threads as <a href="https://github.com/vercel/next.js/issues/10061">Next.js dev server gets stuck after a while, requests just spin</a> and browsed <a href="https://stackoverflow.com/questions/61033562/hot-module-reload-is-not-working-on-my-nextjs-app">Stack Overflow</a> for similar errors. Nothing could fix my problem. Changing ports didn't help, and neither did upgrading or downgrading versions of node or packages. Removing <em>node_modules</em>, <em>.next</em> folder and <em>package-lock.json</em> or swapping to Turbopack did nothing good.</p>
<p>It was really frustrating to troubleshoot when Next.js development server didn't work. And when I finally found the solution, the culprit wasn't more than five characters long. You recognize that feeling, don't you?</p>
<p>My mistake was a silly copy-paste mistake after having tested out to use <a href="https://nextjs.org/docs/app/building-your-application/data-fetching/fetching">fetch in a Server Component</a>. Lesson learned there, look out so you don't have any Client Components with the <em>async</em> keyword. Only Server Components can be async in Next.js.</p>
<p>If you find any async Client Component in your code, remove the <em>async</em> keyword and start the development server again on another port with <em>next dev -p 1234</em>.</p>
<h2>Should You Use Next.js 13?</h2>
<p>If you already are using Next.js 12 and are thinking if you should migrate to version 13, I would say, do it. Next.js 13 is more or less backward compatible. You can bump to 13 and partly upgrade to use the new features according to your time and requirements. See their <a href="https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration">migration guide here</a>.</p>
<p>If starting a new project or migrating an existing one to version 13, you should know that some of the features are still in beta. The <em>app</em> folder routing which is discussed in this article is production ready since version 13.4.</p>
<p>If you are not using Next.js at all, try it out. Remember that React itself is still just a library. Next.js is a complete framework based on React which have just made it all better.</p>
<p><img src="https://www.perssondennis.com/images/articles/errors-received-when-migrating-nextjs-13-to-new-app-folder/nextjs-react-replacement.webp" alt="Next.js and React meme">
<em>I'm here to extend you didn't sound as good...</em></p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>React</category>
            <category>Next.js</category>
            <enclosure url="https://www.perssondennis.com/images/articles/errors-received-when-migrating-nextjs-13-to-new-app-folder/errors-received-when-migrating-nextjs-13-to-new-app-folder.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[How to Avoid Estimating Time Using the Agile Metrics Velocity and Capacity]]></title>
            <link>https://www.perssondennis.com/articles/estimating-with-agile-metrics</link>
            <guid>https://www.perssondennis.com/articles/estimating-with-agile-metrics</guid>
            <pubDate>Sun, 20 Mar 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Agile methods like Scrum do estimations by calculating velocity and capacity. Estimating work with such metrics can make your estimations time independent.]]></description>
            <content:encoded><![CDATA[<p>I read <a href="https://dev.to/chrisvasqm/how-do-you-deal-with-estimates-50f2">this article on DEV</a> asking about how to deal with estimates. It's a great question to ask and it reminds me of my days at the University. Teachers told me not to estimate projects in time. Later I became a teacher myself and I brought that knowledge on to my own students. Honestly I didn't really understand back then how to actually do that.</p>
<p>I started working at a company in the Volvo Group concern and my team used points for estimations. Except, they didn't. The truth is they only believed they were doing that but in reality, they used time as a measurement. Roughly they defined each point as one day of work for two developers pair programming. They empathized we shouldn't think about it as time, rather as points. In the end, the points were still bound to time so we were in reality still estimating time.</p>
<p>I must say I was a bit tired of people urging to use points over time when it in practice was the same thing. It was somewhere there I actually figured out how to get time out of the picture completely.</p>
<h2>How to Use Agile Metrics to Avoid Measuring Time</h2>
<p>Substituting time for points is a great start. It's hard to estimate what time something will take and it's even harder to estimate how much time will be spent on other tasks, assignments, meetings, bug fixes, testing and unexpected hindrances.</p>
<p>The tricky part is how to make the points time independent. The solution to how to do that is to calculate a <a href="https://www.scrum.org/resources/blog/agile-metrics-velocity">velocity</a> using the outcome of the previous work. <strong>Velocity is basically the amount of story points your team succeeds to develop in a sprint on average</strong>.</p>
<p>When you know the velocity, you can calculate what <a href="https://www.agile-academy.com/en/agile-dictionary/capacity/">capacity</a> the team has in an upcoming sprint. <strong>The capacity is what is left of the velocity points after having removed team member vacancies and time allocated to other work, such as maintenance and bug fixes</strong>.</p>
<p>Even though many people know about the terms velocity and capacity, many teams neglect the velocity and fixates the capacity to a constant number instead of calculating it from on the velocity. By doing that they miss the whole point with it. The purpose of velocity and capacity is to make points time independent.</p>
<p>A constant capacity is nothing other than masqueraded time. By <a href="https://www.wrike.com/scrum-guide/faq/what-is-velocity-in-scrum/">recalculating the velocity</a>, the team's capacity will become dependent on the team's actual work effort rather than time.</p>
<p><img src="https://www.perssondennis.com/images/articles/estimating-with-agile-metrics/masqueraded-time-meme.webp" alt="Masqueraded time meme">
<em>It doesn't matter what you call it, it's still time behind the mask if you ignore velocity</em></p>
<h2>You Can Not Compare Developer Performance</h2>
<p>Not all developers work equally fast. One story can take hours for one developer and days for another. After a couple of month or so, the second developer may have become better and can work faster than before. <strong>You can't easily estimate performance</strong> of developers and say that one developer works half as fast as another one. I will vary dependent on work tasks and as time goes.</p>
<p><strong>One thing you can do though, is to evaluate performance</strong>. That is exactly what is done when you calculate a velocity. You look at the tasks that have been done recently by the whole team to get a concrete number of which velocity the team has. That number can be used to estimate what capacity the team has for the work ahead.</p>
<p><img src="https://www.perssondennis.com/images/articles/estimating-with-agile-metrics/estimation-cycle.webp" alt="Estimation cycle">
<em>Estimation cycle. Use the velocity when planning upcoming work</em></p>
<h2>The Process of Planning a Sprint</h2>
<p>Enough of chattering. Let's describe how to plan a sprint the agile way and how to get the estimation to be time independent.</p>
<h3>1. Break Down Features Into Stories</h3>
<p>Make sure you have divided each feature to be developed into small tasks (<a href="https://www.atlassian.com/agile/project-management/user-stories">stories</a>). There's no way you will succeed estimating tasks that are greater than a few days or a week in size. On top of that, destructuring features into smaller tasks will help you plan your work and foresee possible pitfalls.</p>
<h3>2. Assign Points to Stories</h3>
<p>Let the developer team together estimate how many points each story should be assigned. You can preferably use <a href="https://www.atlassian.com/blog/platform/a-brief-overview-of-planning-poker">Planning Poker</a> to let every team member vote without being influenced by other teammates.</p>
<p>When assigning points, you can think of some abstract size of the story. Is it a small, mid-sized or large task? Or, you can actually think in time; will it take around one, three or five days to implement? That may sound strange since the goal is to avoid thinking in time, but it's actually completely fine and it falls natural to humans to do that. Merely by using the approach I describe in this article, <strong>you will go from speaking about points and estimating time, to speak about time and estimating points!</strong></p>
<p>If your idea of one day of work is inaccurate, that won't be an issue. When the velocity is adjusted later on, your idea of time will be corrected so the points you assign to the task reflects you real work. No worries if you get headache trying to understand that, we will get back to that later.</p>
<h3>3. Develop</h3>
<p>You can't spend all time in meetings. Do the work you have planned to do. If you are familiar with Scrum and agile methodologies, this will be you sprint, commonly a period of two weeks.</p>
<h3>4. Adjust the Velocity</h3>
<p>This is the step most people forget about, which is unfortunate. <strong>Without this step you are measuring time and not points!</strong> What you should do here is to calculate how many points you had time to develop during the sprint. That is the velocity you had that sprint. Take the average of that velocity and each velocity a few sprints back in time and the result is the velocity your team have.</p>
<h3>5. Repeat</h3>
<p>Continue the process from the beginning, starting by breaking down new stories and then assigning them points. This time, you will have another velocity than you had when you planned your previous sprint, hopefully better reflecting how much work you actually will have time to do.</p>
<p>Regardless whether you thought in points or if you thought in time when you planned your last sprint, your new velocity will "give you" either less or more points when you calculate the capacity you have in the next sprint.</p>
<hr>
<p><strong>Note:</strong> The example below assumes the complete velocity is counted as capacity. Normally you will count away parts of the velocity when determining the capacity to adjust for absence and maintenance etc.</p>
<p>Maybe you originally had a capacity of ten points for a two weeks long sprint and you planned to do ten one-point stories. If you had time to do some extra work and your new velocity turned out to be 12 points, then each day in the sprint would equal to 1.2 points.</p>
<p>When you plan your next sprint, you can continue estimating the stories the same way you did the last sprint. Your new velocity will correct the estimation error you did when you estimated the stories. What you thought to be one point, or one day of work, turned out to take around 0.8 days (1 / 1.2 ≈ 0.8).</p>
<p>With the new velocity at 12 points per sprint, you will get the capacity to plan 12 points into the next sprint, which is more likely to better match the actual workload you will have time to complete. Repeating this process for each sprint will eventually make your estimations fairly accurate.</p>
<p><img src="https://www.perssondennis.com/images/articles/estimating-with-agile-metrics/velocity.webp" alt="Points velocity table">
<em>If you estimate to fit ten one-point stories into one ten days sprint and it turns out you have time for 12 of them, then your velocity that sprint was 12 points, i.e. 1.2 points per day</em></p>
<h2>Conclusion</h2>
<p>All teams try to estimate workload, a lot of them using agile methods like Scrum. Many of them are aware of the concepts of velocity and capacity and knows they should be measuring points rather than time when estimating their stories. Unfortunately, a lot of teams forget to consider their velocity when they calculate their capacity for a sprint.</p>
<p>When a team forgets to consider the velocity, their estimation in story points becomes nothing other than an estimation of time. They will plan each sprint with a fixed number of points, which in turn will correlate to a fixed amount of time.</p>
<p>This is a problem because humans aren't good at estimating time. By ensuring to <a href="https://www.wrike.com/scrum-guide/faq/what-is-velocity-in-scrum/">recalculate</a> the velocity after each sprint, you will be able to measure how much work you are able to finish in reality. The recalculated velocity will adjust for any misestimations you do when the work is planned.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Productivity</category>
            <enclosure url="https://www.perssondennis.com/assets/blog/default-article-image-unknown.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Every Way a Startup Can Fail]]></title>
            <link>https://www.perssondennis.com/articles/every-way-a-startup-can-fail</link>
            <guid>https://www.perssondennis.com/articles/every-way-a-startup-can-fail</guid>
            <pubDate>Sun, 02 Nov 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover the 22 most common reasons why startups fail and learn how to avoid them. Essential guide for entrepreneurs and startup founders.]]></description>
            <content:encoded><![CDATA[<p>Startups and relationships have a lot in common. Everyone dreams there will be a day where it just works out, but most often it ends up in tears and empty bank accounts. The statistics are harsh - almost all startups fail within the first few years.</p>
<p>Here's the thing though, most of these failures are completely preventable.</p>
<p>In this article, we'll look at the 22 most common reasons why startups crash and burn and how to avoid becoming another cautionary tale that people reference in business school - if you even get that far.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#1-founders-give-up-too-easily">1. Founders Give Up Too Easily</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#2-founder-team-conflicts">2. Founder Team Conflicts</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#3-giving-away-too-much-ownership">3. Giving Away Too Much Ownership</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#4-no-market-for-your-product">4. No Market for Your Product</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#5-your-product-costs-too-much">5. Your Product Costs Too Much</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#6-too-much-competition">6. Too Much Competition</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#7-too-little-competition">7. Too Little Competition</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#8-bad-timing">8. Bad Timing</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#9-not-being-quick-enough">9. Not Being Quick Enough</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#10-cash-flow-problems">10. Cash Flow Problems</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#11-gambling-with-money">11. Gambling With Money</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#12-scaling-issues-and-technical-debt">12. Scaling Issues and Technical Debt</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#13-first-time-founder-syndrome">13. First-Time Founder Syndrome</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#14-not-using-your-data">14. Not Using Your Data</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#15-poor-customer-service">15. Poor Customer Service</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#16-branding-and-reputation-issues">16. Branding and Reputation Issues</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#17-regulatory-and-legal-problems">17. Regulatory and Legal Problems</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#18-partner-and-vendor-issues">18. Partner and Vendor Issues</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#19-founder-burnout">19. Founder Burnout</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#20-geographical-and-cultural-issues">20. Geographical and Cultural Issues</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#21-hiring-the-wrong-people">21. Hiring the Wrong People</a></li>
<li><a href="https://www.perssondennis.com/articles/every-way-a-startup-can-fail#22-not-understanding-your-funding-model">22. Not Understanding Your Funding Model</a></li>
</ul>
<h2>1. Founders Give Up Too Easily</h2>
<p>Let's start with the most obvious one - founders simply give up. Maybe the idea was wrong from the beginning, or maybe startups just aren't for you. And you know what? That's totally fine.</p>
<p>The truth is, not everyone is cut out for the startup life. It might seem perfect in your dreams, but just like having a toddler in a relationship, you'll be up at 3 AM debugging production issues while your friends post vacation photos from Bali.</p>
<p>At that point, you might start questioning your life choices.</p>
<p><strong>The Problem</strong>: Many founders start with a romanticized view of entrepreneurship. They think it's all about working from coffee shops and making millions while wearing hoodies.</p>
<p>Reality hits hard when you realize you're working 80-hour weeks for months without a paycheck.</p>
<p><strong>The Solution</strong>: Before you quit your day job, ask yourself some hard questions:</p>
<ul>
<li>Are you prepared to work harder than you've ever worked in your life?</li>
<li>Can you handle the uncertainty and stress?</li>
<li>Do you actually believe in your idea, or are you just chasing the startup dream?</li>
</ul>
<p>If you're not 100% committed, save yourself the heartache and stick to your day job. There's no shame in that.</p>
<p><img src="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/devastated-man-1.webp" alt="Devastated man 1">
<em>Sometimes your coffee and your motivation run out at the same time</em></p>
<h2>2. Founder Team Conflicts</h2>
<p>This is the classic "we're best friends, so starting a business together will be fun!" scenario they teach you in school. Remember all those weeks you spent writing team contracts before you implemented the actual product in a day or two?</p>
<p><strong>The Problem</strong>: Founders often have different visions, work styles, and expectations.</p>
<p>What starts as a beautiful partnership can quickly turn into a toxic relationship that makes your last breakup look like a walk in the park.</p>
<p><strong>The Solution</strong>: Before you start anything, have the uncomfortable conversations:</p>
<h4>What Do You Want and Why?</h4>
<p>Sit down with your co-founders and discuss:</p>
<ul>
<li>What's your end goal? IPO? Acquisition? Lifestyle business?</li>
<li>How much money do you want to make?</li>
<li>How long are you willing to work without a salary?</li>
<li>What's your exit strategy?</li>
</ul>
<h4>What's Important?</h4>
<p>Decide on your priorities:</p>
<ul>
<li>Are you building for growth or profitability?</li>
<li>How important is work-life balance?</li>
<li>What's your risk tolerance?</li>
</ul>
<h4>How Do You Make Decisions When You Disagree?</h4>
<p>This is crucial. Have a clear process for resolving conflicts:</p>
<ul>
<li>Who has the final say on what decisions?</li>
<li>How do you handle deadlocks?</li>
<li>What happens if you fundamentally disagree on the direction?</li>
<li>What happens if one of you wants to quit?</li>
</ul>
<p>Remember, it's better to have these conversations now than when you're in the middle of a crisis and emotions are running high.</p>
<p><img src="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/devastated-man-2.webp" alt="Devastated man 2">
<em>Losing a company or a friend - why not both?</em></p>
<h2>3. Giving Away Too Much Ownership</h2>
<p>Giving away too much ownership can be troublesome if the other people quit or aren't actively involved. Investors dislike investing in companies owned by people who don't help move the company forward. They want the owner to have a strong incentive to stay involved.</p>
<p><strong>The Problem</strong>: Many founders give away large chunks of equity to co-founders, early employees, or investors without thinking about the long-term implications.</p>
<p>When someone owns a significant portion of your company but isn't contributing anymore, it creates a major problem.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Keep majority ownership</strong>: As the founder, you should always maintain control of your company</li>
<li><strong>Use vesting schedules</strong>: Make sure equity is earned over time, not given away upfront</li>
<li><strong>Be careful with investors</strong>: Remember, investors also take parts of the ownership that the founder loses</li>
<li><strong>Think long-term</strong>: Don't give away equity just to solve short-term problems</li>
<li><strong>Document everything</strong>: Have clear agreements about what happens if someone leaves</li>
</ul>
<h2>4. No Market for Your Product</h2>
<p>This is the mother of all startup failures. You build something amazing, launch it with fanfare, and then... silence.</p>
<p><strong>The Problem</strong>: Too many founders build products based on what they think people want, rather than what people actually want.</p>
<p>They fall in love with their idea and assume everyone else will too.</p>
<p><strong>The Solution</strong>: Never build a product before you know you have a market. Here's the process:</p>
<ol>
<li><strong>Start with Market Research</strong>: Talk to potential customers. Lots of them. Figure out what problems they experience in their lives today</li>
<li><strong>Validate Your Assumptions</strong>: Don't just ask if they like your idea - ask what they'd pay for it</li>
<li><strong>Have a Clear Customer</strong>: Know exactly who your customer is, what problem they have, and how you're solving it</li>
</ol>
<p>The worst thing you can do is spend months building something only to discover that no one actually needs it. Trust me, it's not as easy as putting your meal in the freezer and ordering pizza when you find out your guest is allergic to the dish you made - it's a real breakup with your company.</p>
<p>If the math doesn't work, don't build it. It's that simple. You can't wish your way to profitability.</p>
<p><img src="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/devastated-man-no-users.webp" alt="Devastated man no users">
<em>It's a fine line between having customers and having paying customers</em></p>
<h2>5. Your Product Costs Too Much</h2>
<p>Here's a harsh truth: the worst idea isn't the one that fails after a week. The worst idea is the one you spend years and thousands of dollars on, only to realize it can never be profitable.</p>
<p><strong>The Problem</strong>: Founders often underestimate costs and overestimate what customers are willing to pay.</p>
<p>They build increasingly advanced solutions when the intended customers are perfectly fine with simple alternatives.</p>
<p><strong>The Solution</strong>: Do the math before you build anything. When you know what the customer wants:</p>
<ol>
<li><strong>Calculate Your Costs</strong>: Development, marketing, operations, everything</li>
<li><strong>Determine Your Price Point</strong>: What will customers actually pay?</li>
<li><strong>Check the Numbers</strong>: Will you make enough profit to sustain the business?</li>
</ol>
<p><img src="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/devastated-man-20-years.webp" alt="Devastated man 20 years">
<em>Some early calculations could have told you day one that it wouldn't work</em></p>
<h2>6. Too Much Competition</h2>
<p>Sometimes the market is just too crowded. You might have a great idea, but if there are already 50 companies doing the same thing, you're going to have a hard time standing out.</p>
<p>Just like on the dating market, no one searches for the vanilla ice cream partner they can find anywhere - they want that Ben &#x26; Jerry's or the kind with a sweet cherry on top. If you aren't completely sure you can offer luxury like that, you better go for something with less competition.</p>
<p>Of course, it could be possible to go the Spotify way and do something no one else would dare to touch, to be bold and challenge both record labels and pirates, risking both lawsuits and competing against "free" options for music.</p>
<p>However, you have to be a real unicorn to succeed with that and probably quite a bit of a narcissist to even believe you can succeed with it.</p>
<p><strong>The Problem</strong>: Entering a saturated market means you're competing on price, features, and marketing spend.</p>
<p>Unless you have a significant advantage, you're fighting an uphill battle.</p>
<p><strong>The Solution</strong>: Either find a niche within the market or pivot to something less crowded. Don't try to be everything to everyone - find a specific problem that no one else is solving well.</p>
<h2>7. Too Little Competition</h2>
<p>Wait, isn't no competition a good thing? Not necessarily. If an idea sounds too good to be true, it probably is.</p>
<p>Maybe you don't see it the first weeks or year, but with time you might start noticing some red flags.</p>
<p>If you find a new idea, try to investigate why it doesn't exist. You might find a reason to why it isn't a good idea, or even better, find a solution to the issue others had.</p>
<p><strong>The Problem</strong>: If there's no competition, there might be no market.</p>
<p>Other companies have likely tried similar ideas before and failed for a reason.</p>
<p><strong>The Solution</strong>: If you have no competition, it's even more important to validate that customers actually need your product and are willing to pay for it. Don't assume you're the first person to think of this - you're probably not.</p>
<h2>8. Bad Timing</h2>
<p>Timing is everything in startups. You can have the best idea in the world, but if you launch at the wrong time, you're doomed.</p>
<p>Remember Pokemon GO? On their first release they had severe problems with overloaded servers and security issues. It wasn't a production-ready product and they lost a third of their users in a month (15 million users).</p>
<p>On the other hand, they released the app in July when the majority of its players (living in the Northern Hemisphere) had summer and school holidays.</p>
<p>Their option would have been to release it later in the Autumn or Winter when people want to stay inside, or to wait almost a whole year until spring comes around again. Maybe the timing was worth all the production issues after all?</p>
<p><strong>The Problem</strong>: Being too early means the market isn't ready for your product.</p>
<p>Being too late means someone else has already captured the market.</p>
<p><strong>The Solution</strong>: Pay attention to market trends and timing. Sometimes it's better to wait for the right moment than to rush to market with the wrong timing.</p>
<p><img src="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/devastated-woman-1.webp" alt="Devastated woman 1">
<em>Think you start to see a pattern here...</em></p>
<h2>9. Not Being Quick Enough</h2>
<p>Startups bleed money - we're talking millions per month or even millions per week. If you aren't quick, you will bleed out. Plus, if you aren't quick enough to win the market, someone else will take it right in front of your eyes!</p>
<p><strong>The Problem</strong>: Many founders get stuck in analysis paralysis, trying to perfect everything before launching.</p>
<p>Meanwhile, their competitors are moving fast, capturing market share, and building momentum.</p>
<p>In the startup world, speed is often more important than perfection.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Move fast without breaking things</strong>: Everything doesn't have to be pitch perfect</li>
<li><strong>Launch early, iterate often</strong>: Get something out there and improve based on feedback</li>
<li><strong>Set aggressive timelines</strong>: If you think it will take 6 months, aim for 3</li>
<li><strong>Don't over-engineer</strong>: Build the minimum viable product, not the perfect product</li>
<li><strong>Make decisions quickly</strong>: Don't let perfect be the enemy of good</li>
</ul>
<p>Remember, a mediocre product that launches today is better than a perfect product that launches next year. The market doesn't wait for anyone.</p>
<h2>10. Cash Flow Problems</h2>
<p>This is extremely common and often fatal. A company can have a huge net worth and tied-up capital but still fail because it can't pay its bills this month.</p>
<p>The value of the company and its theoretical capital doesn't matter if they don't have liquidity to pay their bills. If the cash stops flowing, the company will stop glowing.</p>
<p><strong>The Problem</strong>: Many startups focus on revenue and growth but ignore cash flow.</p>
<p>They might be making sales, but if customers take 90 days to pay while you have bills due every 30 days, you're in trouble.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li>Monitor your cash flow religiously</li>
<li>Have a buffer for unexpected expenses</li>
<li>Don't spend money you don't have</li>
<li>Consider payment terms when making sales</li>
</ul>
<p>Cash is king in startups. You can have the best product in the world, but if you run out of cash, you're done.</p>
<h2>11. Gambling With Money</h2>
<p>Here's a simple rule: gambling is gambling. Whether you're at a casino or starting a business, spending more money than you have comes with risk.</p>
<p>Your company might be founded on loans and investments that might be lost if the company doesn't work out - that's fine, it might be the only option you have.</p>
<p>Gambling with your company's liquidity so it could go below zero any day if you don't get your expected revenue in time is not okay.</p>
<p>It isn't fair to your investors, employees, partners or customers who could lose all their investments just because you decided to expose the company to a completely unnecessary risk. And trust me, they will not be happy when you tell them - I have been on the receiving side of this.</p>
<p><strong>The Problem</strong>: Some founders spend money they don't have because they assume success is guaranteed if they just work hard enough.</p>
<p>They blindly invest money and hope they will find a way to get the money in time.</p>
<p><strong>The Solution</strong>: If you're going to gamble with money, really think over that decision. Ask yourself:</p>
<ul>
<li>Can you afford to lose this money?</li>
<li>What's your backup plan if things go wrong?</li>
<li>How long can you survive without income?</li>
<li>Am I gambling with other people's money?</li>
</ul>
<p>Remember, there's a difference between calculated risk and reckless gambling. Make sure you know which one you're doing.</p>
<p><img src="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/devastated-man-3.webp" alt="Devastated man 3">
<em>Sometimes it's not only the owner of the company who gets affected</em></p>
<h2>12. Scaling Issues and Technical Debt</h2>
<p>Despite what was said in the previous point, you don't want to end up in a company-wide "it works on my machine" state. Make sure to get the overall architecture in place so you know how you should scale your application the day it's time for it. And remember, that could be tomorrow.</p>
<p><strong>The Problem</strong>: Many startups build quick and dirty solutions to get to market fast, which is smart.</p>
<p>But they never go back to clean up the mess. Before you know it, you're spending more money on band-aids than you would have spent building it right the first time.</p>
<p><strong>The Solution</strong>: An MVP is probably enough to start, but make sure it's good and can scale! Here's what that means:</p>
<ul>
<li><strong>Build for the future</strong>: Don't just build for today's 10 users, think about tomorrow's 10,000</li>
<li><strong>Pay down technical debt</strong>: Set aside time and money to refactor and improve your systems where bottlenecks can appear and for core functionality</li>
<li><strong>Hire the right people</strong>: Don't just hire developers who can code fast - hire ones who can build systems that last</li>
</ul>
<h2>13. First-Time Founder Syndrome</h2>
<p>A first-time founder who doesn't know how to run or scale a company is like a pilot who's never flown before - they might get the plane off the ground, but keeping it in the air or landing it safely is a whole different story.</p>
<p><strong>The Problem</strong>: Many first-time founders are great at building products but have no idea how to run a business.</p>
<p>They don't know how to hire, manage people, handle finances, negotiate deals, or scale operations.</p>
<p>They learn everything the hard way, which is expensive and time-consuming.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Get a mentor</strong>: Find someone who's been there and done that</li>
<li><strong>Read books</strong>: There are plenty of resources on entrepreneurship and business management</li>
<li><strong>Take courses</strong>: Invest in your business education</li>
<li><strong>Hire experienced people</strong>: Don't be afraid to hire people who know more than you</li>
<li><strong>Join founder communities</strong>: Learn from other founders' mistakes</li>
<li><strong>Start small</strong>: Don't try to build a unicorn on your first try</li>
</ul>
<p>Remember, being a first-time founder isn't a death sentence - it's just a learning curve. The key is to recognize what you don't know and actively work to fill those gaps.</p>
<h2>14. Not Using Your Data</h2>
<p>Data-driven decisions are key to success. It's one of the most important tools for making good decisions for a company. If you don't do it, you have no idea where your company is going - you are basically blindfolded.</p>
<p>You might have a great vision in your mind, but without clear sight others might reach your customers before you.</p>
<p><strong>The Problem</strong>: Many startups collect tons of data but don't actually use it to make decisions.</p>
<p>They rely on gut feelings, hunches, and "what feels right" instead of what the data tells them.</p>
<p>Soon enough, they realize they made a big mistake which cannot be undone.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Collect the right data</strong>: Focus on metrics that actually matter</li>
<li><strong>Analyze regularly</strong>: Don't just collect data, use it</li>
<li><strong>Make data-driven decisions</strong>: Let the numbers guide your strategy</li>
<li><strong>Share insights</strong>: Make sure your team understands what the data means</li>
<li><strong>Iterate based on data</strong>: Use what you learn to improve your product</li>
</ul>
<p>Remember, data doesn't lie. Your gut feelings might.</p>
<p><img src="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/devastated-man-new-way.webp" alt="Devastated man new way">
<em>Didn't have to be new if you would have read my article...</em></p>
<h2>15. Poor Customer Service</h2>
<p>There's a reason why most big companies try to include "customer service" in their mission statement. I know there are lots of companies that succeed even though they treat their customers poorly, but after all, the customers are what makes the company successful.</p>
<p>Creating a company is really expensive. A great deal of that is finding, reaching out to and convincing customers. When you have them there, you better keep them there. Their opinions will affect how quickly you gain or lose new customers.</p>
<p><strong>The Problem</strong>: Many startups focus so much on acquiring new customers that they forget to take care of the ones they already have.</p>
<p>Bad customer service can kill your reputation faster than anything else.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Make customer service a priority</strong>: Not an afterthought</li>
<li><strong>Respond quickly</strong>: Customers expect fast responses</li>
<li><strong>Empower your team</strong>: Give them the tools and authority to solve problems</li>
<li><strong>Listen to feedback</strong>: Your customers will tell you exactly what's wrong with your product</li>
<li><strong>Measure satisfaction</strong>: Track NPS, response times, and resolution rates</li>
</ul>
<p>Remember, it's much cheaper to keep an existing customer than to acquire a new one.</p>
<h2>16. Branding and Reputation Issues</h2>
<p>A bad reputation is something that could definitely kill a company. Although your branding might not kill your company, a lack of branding could definitely be a reason for your company to not succeed and in the long term kill your company.</p>
<p><strong>The Problem</strong>: Many startups think branding is just about having a nice logo.</p>
<p>But branding is about how people perceive your company, and that perception can make or break you.</p>
<p>Your whole company and all your products should breathe your brand.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Define your brand</strong>: What do you stand for? What makes you different?</li>
<li><strong>Be consistent</strong>: Your brand should be reflected in everything you do</li>
<li><strong>Build trust</strong>: Your reputation is your most valuable asset</li>
<li><strong>Monitor your brand</strong>: Know what people are saying about you</li>
<li><strong>Respond to criticism</strong>: Don't ignore negative feedback</li>
</ul>
<h2>17. Regulatory and Legal Problems</h2>
<p>Make sure you know the market you enter and the regulations you need to follow. Mistakes can cost you money, time, and your reputation - sometimes all three at once.</p>
<p><strong>The Problem</strong>: Many founders focus so much on building their product that they forget about the legal and regulatory requirements.</p>
<p>By the time they realize they're breaking the law, it's too late.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Do your homework</strong>: Research the regulations in your industry and market</li>
<li><strong>Get legal advice</strong>: Don't try to be your own lawyer</li>
<li><strong>Build compliance into your product</strong>: Don't bolt it on later</li>
<li><strong>Stay updated</strong>: Laws change, and ignorance isn't a defense</li>
</ul>
<p>Whether it's data privacy laws, industry regulations, or employment law, compliance isn't optional. It's part of doing business.</p>
<h2>18. Partner and Vendor Issues</h2>
<p>Make sure you know the terms of your contracts and that you're not getting ripped off. Your suppliers' failures can be your own failure. Think twice before you sign a contract with a supplier or choose a partner.</p>
<p><img src="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/devastated-woman-out-of-coffee.webp" alt="Devastated woman out of coffee">
<em>Your vendor's "99.9% uptime" means they're down when you need them most</em></p>
<p><strong>The Problem</strong>: Many startups rely heavily on third-party vendors and partners, but they don't properly vet them or understand the terms of their contracts.</p>
<p>When a vendor fails, the startup fails too.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Vet your vendors</strong>: Check their track record, financial stability, and references</li>
<li><strong>Read the fine print</strong>: Understand your contracts inside and out</li>
<li><strong>Have backup plans</strong>: Don't put all your eggs in one vendor's basket</li>
<li><strong>Monitor performance</strong>: Track uptime, response times, and quality</li>
<li><strong>Negotiate terms</strong>: Don't just accept whatever they offer</li>
</ul>
<p>Remember, you're only as strong as your weakest link. Choose your partners wisely.</p>
<h2>19. Founder Burnout</h2>
<p>A common saying and truth is that investors don't invest in companies, they invest in people. The founder is the most important person in the company, and if they're not able to handle the stress and pressure of running a company, the company will fail.</p>
<p><img src="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/devastated-woman-2.webp" alt="Devastated woman 2">
<em>A real entrepreneur's blood type is coffee</em></p>
<p><strong>The Problem</strong>: Many founders work themselves to exhaustion, thinking that more hours equals more success.</p>
<p>But burnout leads to poor decisions, health problems, and ultimately, company failure.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Take care of yourself</strong>: Sleep, exercise, and eat properly</li>
<li><strong>Set boundaries</strong>: Work-life balance isn't just a buzzword</li>
<li><strong>Delegate</strong>: You can't do everything yourself</li>
<li><strong>Build a support system</strong>: Have people you can talk to about the stress</li>
</ul>
<p>Remember, you're no good to your company if you're dead or in the hospital.</p>
<h2>20. Geographical and Cultural Issues</h2>
<p>Just like with timing, the place and environment matter a lot as well. Don't put your sailboat in a sea with no wind. Maybe the sea isn't even deep enough.</p>
<p><strong>The Problem</strong>: Many founders don't consider the geographical and cultural factors that can affect their business.</p>
<p>What works in Silicon Valley might not work in Stockholm, and what works in Stockholm might not work in Tokyo.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Research your market</strong>: Understand the local culture, regulations, and business practices</li>
<li><strong>Adapt your approach</strong>: Don't assume your way is the only way</li>
<li><strong>Build local relationships</strong>: Find local partners, advisors, and mentors</li>
<li><strong>Consider logistics</strong>: Shipping, time zones, and local infrastructure matter</li>
<li><strong>Test the waters</strong>: Start small and expand gradually</li>
</ul>
<p>Remember, you're not just competing with local companies - you're competing with local culture and expectations.</p>
<h2>21. Hiring the Wrong People</h2>
<p>As mentioned earlier in this article, it's important that co-founders and early employees agree to what the company should stand for.</p>
<p>Something some people may forget here, is that your employees are a representation of your company and your brand as well.</p>
<p>Hire the wrong person, and they can single-handedly destroy everything you've built if you are unlucky.</p>
<p>It can be done in many ways: ruin your reputation, ruin a business deal or investment, or maybe by changing the team spirit so the company slows down or starts to drift in a wrong way.</p>
<p>The risks are many here. If you wonder what problem they might cause - then read this article again with the mindset of what an employee can cause.</p>
<p><strong>The Problem</strong>: Many founders hire people who are technically skilled but culturally toxic, or who don't share the company's vision and values.</p>
<p>One bad hire can poison your entire team and drive away your best employees.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Culture fit matters more than skills</strong>: You can teach someone to code, but you can't teach them to be a decent human being</li>
<li><strong>Take your time</strong>: Don't rush hires just because you're desperate for help</li>
<li><strong>Involve your team</strong>: Let your existing employees interview candidates</li>
<li><strong>Know your hirings</strong>: Take some time to learn your hiring candidates before employing them, it costs more time to make a wrong decision</li>
<li><strong>Trust your gut</strong>: If something feels off, it probably is</li>
</ul>
<h2>22. Not Understanding Your Funding Model</h2>
<p>Before we wrap up, there's one distinction that affects everything else: whether you're bootstrapped or venture-backed. These two paths have completely different failure patterns and success metrics.</p>
<p><strong>Bootstrapped Startups</strong> (self-funded):</p>
<ul>
<li><strong>Failure Pattern</strong>: Usually die slowly from cash flow problems or founder burnout</li>
<li><strong>Success Metric</strong>: Profitability and sustainable growth</li>
<li><strong>Timeline</strong>: Can take years to reach meaningful scale</li>
<li><strong>Risk</strong>: Lower risk of catastrophic failure, higher risk of stagnation</li>
</ul>
<p><strong>Venture-Backed Startups</strong> (investor-funded):</p>
<ul>
<li><strong>Failure Pattern</strong>: Commonly die quickly from running out of runway or missing growth targets</li>
<li><strong>Success Metric</strong>: Rapid growth and market capture</li>
<li><strong>Timeline</strong>: Expected to scale quickly or die trying</li>
<li><strong>Risk</strong>: Higher risk of complete failure, but potential for massive success</li>
</ul>
<p><strong>The Problem</strong>: Many founders don't understand which path they're on or try to mix strategies. A bootstrapped startup trying to grow like a venture-backed one will burn out. A venture-backed startup trying to be profitable too early will miss growth targets.</p>
<p><strong>The Solution</strong>:</p>
<ul>
<li><strong>Choose your path early</strong>: Decide if you're building for profitability or growth</li>
<li><strong>Align your metrics</strong>: Focus on the right KPIs for your funding model</li>
<li><strong>Set realistic expectations</strong>: Don't expect venture-scale growth without venture funding</li>
<li><strong>Understand the trade-offs</strong>: Each path has different risks and rewards</li>
<li><strong>Be consistent</strong>: Don't switch strategies mid-journey unless you're prepared for the consequences</li>
</ul>
<p>Remember, there's no right or wrong choice - just different paths with different failure modes. The key is understanding which path you're on and playing by those rules.</p>
<h2>The Bottom Line</h2>
<p>Starting a business is hard. Really hard. But most failures are preventable if you're honest with yourself and do your homework.</p>
<p>The key is to validate your assumptions early and often. Don't fall in love with your idea - fall in love with solving a real problem for real customers who are willing to pay real money.</p>
<p>And remember, there's no shame in failing. Every successful entrepreneur has failed multiple times. The important thing is to learn from your mistakes and keep moving forward, and more importantly, learn from mistakes others have already made.</p>
<p><img src="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/could-it-be-any-easier.webp" alt="Could it be any easier">
<em>Don't forget, sometimes it actually works out</em></p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Productivity</category>
            <category>SoftSkills</category>
            <category>Business</category>
            <enclosure url="https://www.perssondennis.com/images/articles/every-way-a-startup-can-fail/every-way-a-startup-can-fail.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Extensive List of Best Development Resources - 121 Links to Guides, Cheat Sheets and More List of Resources]]></title>
            <link>https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources</link>
            <guid>https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources</guid>
            <pubDate>Sun, 13 Nov 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Collection of development resources every developer needs. Roadmaps, complete guides, books and cheat sheets. Everything you need to know as a developer]]></description>
            <content:encoded><![CDATA[<p>This is a collection of top rated web development resources every developer needs. Roadmaps, guides, free tools, programmer books, cheat sheets and more. All articles are of high quality and you have everything from soft skills to visual explanations of JavaScript internals. If you don't think this list is complete enough, you will find a lot more list like this at the end of this article.</p>
<h2>List of Content</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#roadmaps">Roadmaps</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#visualized-learning">Visualized Learning</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#crash-courses-and-complete-guides">Crash Courses and Complete Guides</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#for-the-interview">For the Interview</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#tools-templates-and-resources">Tools, Templates and Resources</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#soft-skills-career-and-productivity">Soft Skills, Career and Productivity</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#algorithms-and-data-structures">Algorithms and Data Structures</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#lists-of-programmer-books">Lists of Programmer Books</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#coding-tips-and-tricks">Coding Tips and Tricks</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#cheat-sheets">Cheat Sheets</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#security">Security</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#apis">APIs</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#uncatogorized-reading">Uncatogorized Reading</a></li>
<li><a href="https://www.perssondennis.com/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources#more-lists-like-this">More Lists Like This</a></li>
</ol>
<h2>Roadmaps</h2>
<p>Roadmaps lets you know what you will have to learn to becoming a developer of some kind, providing you with useful guides and resources.</p>
<ul>
<li><a href="https://dev.to/ender_minyard/full-stack-developer-s-roadmap-2k12">Full Stack Developer's Roadmap</a></li>
<li><a href="https://dev.to/javinpaul/the-2019-web-development-frontend-backend-roadmap-4le2">The 2022 Web Development (Frontend + Backend) RoadMap</a></li>
<li><a href="https://dev.to/tyaga001/if-i-were-to-restart-javascript-again-from-scratch-then-i-will-follow-this-roadmap-5c02">If I were to restart JavaScript again from scratch then I will follow this roadmap</a></li>
<li><a href="https://dev.to/kelly/freelancing-101-how-to-get-started-36kg">Freelancing 101: How to get started</a></li>
<li><a href="https://dev.to/theme_selection/reactjs-roadmap-for-developers-2824">ReactJS Roadmap For Developers</a></li>
<li><a href="https://dev.to/theme_selection/how-to-become-a-pro-front-end-developer-5gbo">How to Become a Pro Front End Developer</a></li>
<li><a href="https://dev.to/ankit01oss/the-complete-devops-roadmap-28n1">The complete DevOps roadmap</a></li>
<li><a href="https://dev.to/marwamejri/best-way-to-become-flutter-developer-a-complete-roadmap-5h56">Best Way to Become Flutter Developer – A Complete Roadmap</a></li>
<li><a href="https://dev.to/envoy_/blockchain-app-developer-roadmap-31p5">Blockend Developer Roadmap</a></li>
<li><a href="https://dev.to/codesandtags/roadmap-web-developer-front-end-2020-h0g">Roadmap Web Developer Front End 2020</a></li>
</ul>
<h2>Visualized Learning</h2>
<p>Regardless of whether you are a visual learner or not, these articles provides you with top quality visualized descriptions of how the web works in detail.</p>
<ul>
<li><a href="https://dev.to/nodedoctors/an-animated-guide-to-nodejs-event-loop-3g62">An animated guide for Node.js event loop</a></li>
<li><a href="https://dev.to/lydiahallie/javascript-visualized-the-javascript-engine-4cdf">JavaScript Visualized: the JavaScript Engine</a></li>
<li><a href="https://dev.to/lydiahallie/cs-visualized-useful-git-commands-37p1">CS Visualized: Useful Git Commands</a></li>
<li><a href="https://dev.to/joyshaheb/css-grid-cheat-sheet-illustrated-in-2021-1a3">CSS Grid Cheat Sheet Illustrated in 2021</a></li>
<li><a href="https://dev.to/lydiahallie/cs-visualized-cors-5b8h">CS Visualized: CORS</a></li>
<li><a href="https://dev.to/joyshaheb/flexbox-cheat-sheets-in-2021-css-2021-3edl">Complete Flexbox Tutorial w/ Cheat Sheet</a></li>
<li><a href="https://dev.to/swastikyadav/algorithms-in-javascript-with-visual-examples-gh3">Algorithms in JavaScript with visual examples</a></li>
<li><a href="https://dev.to/narottam04/how-javascript-works-visually-explained-269j">How JavaScript Works Visually Explained</a></li>
<li><a href="https://dev.to/lydiahallie/javascript-visualized-promises-async-await-5gke">JavaScript Visualized: Promises &#x26; Async/Await</a></li>
<li><a href="https://dev.to/blarzhernandez/javascript-service-workers-visualized-1683">JavaScript Service Workers, Visualized</a></li>
</ul>
<h2>Crash Courses and Complete Guides</h2>
<p>Complete guides and beginner guides to learn web development. Learn React and full stack development to master web programming.</p>
<ul>
<li><a href="https://dev.to/awwsmm/101-bash-commands-and-tips-for-beginners-to-experts-30je">101 Bash Commands and Tips for Beginners to Experts</a></li>
<li><a href="https://dev.to/edge-and-node/the-complete-guide-to-full-stack-web3-development-4g74">The Complete Guide to Full Stack Web3 Development</a></li>
<li><a href="https://dev.to/iuliagroza/complete-introduction-to-the-30-most-essential-data-structures-algorithms-43kd">Complete Introduction to the 30 Most Essential Data Structures &#x26; Algorithms</a></li>
<li><a href="https://dev.to/dabit3/the-complete-guide-to-full-stack-ethereum-development-3j13">The Complete Guide to Full Stack Ethereum and EVM Development</a></li>
<li><a href="https://dev.to/ender_minyard/the-ultimate-guide-to-web-performance-ci4">The Ultimate Guide to Web Performance</a></li>
<li><a href="https://dev.to/aspittel/a-complete-beginners-guide-to-react-2cl6">A Complete Beginner's Guide to React</a></li>
<li><a href="https://dev.to/surajondev/40-useful-resources-for-mastering-web-1i0h">40+ Useful Resources for Mastering Web</a></li>
<li><a href="https://dev.to/edge-and-node/the-complete-guide-to-full-stack-solana-development-with-react-anchor-rust-and-phantom-3291">The Complete Guide to Full Stack Solana Development with React, Anchor, Rust, and Phantom</a></li>
<li><a href="https://dev.to/aspittel/a-complete-beginners-guide-to-vue-422n">A Complete Beginner's Guide to Vue</a></li>
</ul>
<h2>For the Interview</h2>
<p>Huge lists of questions to prepare for you next programming interview. Practise interview questions for JavaScript and React to become a software engineer.</p>
<ul>
<li><a href="https://dev.to/seattledataguy/the-interview-study-guide-for-software-engineers-764">The Interview Study Guide For Software Engineers</a></li>
<li><a href="https://dev.to/macmacky/70-javascript-interview-questions-5gfi">70 JavaScript Interview Questions</a></li>
<li><a href="https://dev.to/sakhnyuk/300-react-interview-questions-2ko4">300+ React Interview Questions</a></li>
<li><a href="https://dev.to/javinpaul/101-coding-problems-and-few-tips-to-crack-your-next-programming-interviews-402a">101 Coding Problems and few Tips to Crack Your Next Programming Interviews</a></li>
<li><a href="https://dev.to/aviyel/300-react-interview-questions-4dag">React Interview Questions</a></li>
<li><a href="https://dev.to/emmabostian/i-passed-the-google-technical-interviews-you-can-too-4i6m">I Passed The Google Technical Interviews; You Can Too</a></li>
<li><a href="https://dev.to/elliot/my-google-technical-interview-cheat-sheet-1lbd">My Google Technical Interview Cheat Sheet</a></li>
<li><a href="https://dev.to/javinpaul/50-data-structure-and-algorithms-problems-from-coding-interviews-4lh2">50+ Data Structure and Algorithms Problems from Coding Interviews</a></li>
</ul>
<h2>Tools, Templates and Resources</h2>
<p>Lists of free resources and tools for programmers. Browse through templates and other tools every designer needs.</p>
<ul>
<li><a href="https://dev.to/cruip/50-free-tools-and-resources-to-create-awesome-user-interfaces-1c1b">50+ free tools and resources to create awesome user interfaces</a></li>
<li><a href="https://dev.to/perssondennis/list-of-free-image-tools-every-frontend-developer-needs-489a">List of Free Image Tools Every Frontend Developer Needs</a></li>
<li><a href="https://dev.to/joserfelix/40-high-quality-free-resources-for-web-development-10o3">40+ High-Quality Free Resources for Web Development</a></li>
<li><a href="https://dev.to/davidepacilio/35-free-react-templates-and-themes-32ci">35+ Free React templates and themes</a></li>
<li><a href="https://dev.to/jsmanifest/22-miraculous-tools-for-react-developers-in-2019-4i46">22 Miraculous Tools for React Developers in 2019</a></li>
<li><a href="https://dev.to/fayaz/this-free-tools-for-developers-are-45p3">These free tools for developers are fire</a></li>
<li><a href="https://dev.to/iainfreestone/50-developer-tools-to-make-your-life-a-little-easier-4oc5">50 Developer tools to make your life a little easier</a></li>
<li><a href="https://dev.to/madza/17-killer-websites-you-should-use-to-increase-productivity-2enk">17 Killer Web Apps You Should Use to Increase Productivity</a></li>
<li><a href="https://dev.to/davidepacilio/40-free-html-landing-page-templates-3gfp">40 Free HTML landing page templates</a></li>
<li><a href="https://dev.to/kiranrajvjd/the-ultimate-web-developer-resources-list-200-resources-2gf5">The Ultimate Web Developer Resources List Awesome 200+ Resources</a></li>
<li><a href="https://dev.to/hrishikesh1990/i-made-100-high-quality-illustrations-totally-free-use-it-anywhere-without-attribution-452o">I made 100 high-quality illustrations, totally free. Use it anywhere without attribution</a></li>
<li><a href="https://dev.to/denicmarko/50-free-tools-and-resources-you-re-gonna-love-4hd0">50 free tools and resources you're gonna love</a></li>
<li><a href="https://dev.to/akshay35c/productive-tools-for-web-development-4bd5">Productive Tools For Web Development</a></li>
<li><a href="https://dev.to/theme_selection/ultimate-reactjs-resources-for-web-developers-2021-424c">Ultimate ReactJS Resources For Web Developers 2022</a></li>
<li><a href="https://dev.to/theme_selection/best-design-resources-websites-every-developer-should-bookmark-1p5d">Best design resources websites every developer should bookmark</a></li>
<li><a href="https://dev.to/theme_selection/best-typography-resources-tools-for-every-developers-and-designer-49hp">Best Typography Resources &#x26; Tools for Every Developers and Designer </a></li>
</ul>
<h2>Soft Skills, Career and Productivity</h2>
<p>Boost your programmer career with soft skills and productivity tips. Tips to get the job you want and to be a better programmer.</p>
<ul>
<li><a href="https://dev.to/emmabostian/101-tips-for-being-a-great-programmer-human-36nl">101 Tips For Being A Great Programmer (&#x26; Human)</a></li>
<li><a href="https://dev.to/perssondennis/10-tips-to-get-more-readers-on-dev-4p7h">10 Tips To Get More Readers on DEV</a></li>
<li><a href="https://dev.to/rinaarts/how-to-ruin-your-career-in-8-easy-steps-71">How to Ruin Your Career in 8 Easy Steps</a></li>
<li><a href="https://dev.to/kethmars/what-i-learned-after-reviewing-over-40-developer-portfolios-9-tips-for-a-better-portfolio-4me7">What I learned after reviewing over 40 developer portfolios - 9 tips for a better portfolio</a></li>
<li><a href="https://dev.to/exampro/700-web-developers-asked-me-to-give-them-linkedin-profile-feedback-and-these-are-my-5-top-tips-5382">700+ Web Developers Asked Me To Give Them LinkedIn Profile Feedback And These Are My 5 Top Tips</a></li>
<li><a href="https://dev.to/sobolevn/i-am-a-mediocre-developer--30hn">I am a mediocre developer</a></li>
<li><a href="https://dev.to/samborick/i-read-21-articles-about-how-to-become-a-senior-developer-so-you-don-t-have-to-4dap">I Read 21 Articles About How to Become a Senior Developer So You Don't Have To</a></li>
<li><a href="https://dev.to/duomly/18-websites-where-you-can-find-a-remote-job-3a91">18 websites, where you can find a remote job</a></li>
<li><a href="https://dev.to/simonholdorf/101-tips-to-make-you-a-better-developer-2jo3">101 Tips to Make You a Better Developer</a></li>
<li><a href="https://dev.to/perigk/30-tips-for-software-engineering-careers-after-30-years-of-life-5ddf">30 Tips for Software Engineering Careers, After 30 Years of Life</a></li>
<li><a href="https://dev.to/maxwell_dev/how-to-take-notes-on-everything-32fc">How To Take Notes on Everything</a></li>
<li><a href="https://dev.to/brandonskerritt/how-to-get-any-job-you-want-a-guide-to-employability-skills-1i3m">How To Get Any Job You Want - A Guide To Employability Skills</a></li>
<li><a href="https://dev.to/emmabostian/19-tips-for-software-engineers-in-2019-4okm">19 Tips For Software Engineers In 2019</a></li>
<li><a href="https://dev.to/aspittel/25-tips-for-new-developers-advice-from-a-mostly-self-taught-software-engineer-1ff1">25 Tips for New Developers: Advice from a (Mostly) Self-Taught Software Engineer</a></li>
<li><a href="https://dev.to/gurutobe/keys-for-you-to-become-a-better-frontend-web-developer-1ba8">Keys for You to Become a Better Frontend Web Developer</a></li>
<li><a href="https://dev.to/actitime/how-to-build-a-great-developer-portfolio-examples-tools-bkj">How to Build a Great Developer Portfolio (+ Examples &#x26; Tools)</a></li>
<li><a href="https://dev.to/dragosnedelcu/the-harsh-reality-for-js-developers-master-the-fundamentals-or-you-will-be-just-a-coder-21ke">The Harsh Reality for JS Developers: If You Don't Study The Fundamentals You Will Be Just Another “Coder”</a></li>
</ul>
<h2>Algorithms and Data Structures</h2>
<p>Learn algorithms and data structures for both beginners and more advanced use cases.</p>
<ul>
<li><a href="https://dev.to/codinglanguages/how-to-learn-not-memorize-any-algorithm-or-data-structure-analysis-of-20-problem-solving-techniques-you-must-know-d77">How to learn data structures and algorithms. 20 problem-solving techniques you must know</a></li>
<li><a href="https://dev.to/swastikyadav/algorithms-in-javascript-with-visual-examples-gh3">Algorithms in JavaScript with visual examples</a></li>
<li><a href="https://dev.to/javinpaul/10-data-structure-and-algorithms-articles-beginners-should-read-this-weekend-4i91">10 Data Structure and Algorithms Articles Beginners Should Read this Weekend</a></li>
<li><a href="https://dev.to/iuliagroza/complete-introduction-to-the-30-most-essential-data-structures-algorithms-43kd">Complete Introduction to the 30 Most Essential Data Structures &#x26; Algorithms</a></li>
</ul>
<h2>Lists of Programmer Books</h2>
<p>A list of lists with programmer books developers need to read. Find the most recommended programming books.</p>
<ul>
<li><a href="https://dev.to/bosepchuk/29-must-read-programming-books-2n45">29 Must Read Books For Programmers</a></li>
<li><a href="https://dev.to/daolf/the-25-most-recommended-programming-books-of-all-time-5fel">The 25 most recommended programming books of all-time</a></li>
<li><a href="https://dev.to/awwsmm/20-most-recommended-books-for-software-developers-5578">20 Most-Recommended Books for Software Developers</a></li>
<li><a href="https://dev.to/taillogs/the-best-book-to-read-as-a-developer-1h4m">The Best Book to Read as a Developer</a></li>
</ul>
<h2>Coding Tips and Tricks</h2>
<p>Quick tips and tricks to write better code. What you need to know to write good JavaScript code.</p>
<ul>
<li><a href="https://dev.to/duomly/13-useful-javascript-array-tips-and-tricks-you-should-know-2jfo">13 useful JavaScript array tips and tricks you should know</a></li>
<li><a href="https://dev.to/saviomartin/20-killer-javascript-one-liners-94f">20 Killer JavaScript One Liners</a></li>
<li><a href="https://dev.to/worldindev/8-javascript-tips-tricks-that-no-one-teaches-24g1">8 JavaScript Tips &#x26; Tricks That No One Teaches</a></li>
<li><a href="https://dev.to/orkhanjafarovr/9-javascript-tips-tricks-to-code-like-a-wizard-559i">9 JavaScript Tips &#x26; Tricks To Code Like A Wizard</a></li>
</ul>
<h2>Cheat Sheets</h2>
<p>Cheat sheets for React, CSS, Git and programming overall. Compilation of cheat sheets to bookmark.</p>
<ul>
<li><a href="https://dev.to/reedbarger/the-react-cheatsheet-for-2020-real-world-examples-4hgg">The React Cheatsheet for 2020 (+ Real-World Examples)</a></li>
<li><a href="https://dev.to/joyshaheb/css-grid-cheat-sheet-illustrated-in-2021-1a3">CSS Grid Cheat Sheet Illustrated in 2021</a></li>
<li><a href="https://dev.to/maxpou/git-cheat-sheet-advanced-3a17">Git: Cheat Sheet (advanced)</a></li>
<li><a href="https://dev.to/joyshaheb/flexbox-cheat-sheets-in-2021-css-2021-3edl">Complete Flexbox Tutorial w/ Cheat Sheet</a></li>
<li><a href="https://dev.to/palashmon/ultimate-cheatsheet-compilation-32c9">Ultimate Cheatsheet Compilation</a></li>
<li><a href="https://dev.to/ladybug/css-cheat-sheets-3ee0">CSS Cheat Sheets!</a></li>
<li><a href="https://dev.to/haycuoilennao19/35-website-cheat-sheet-for-developer-22hk">35 Website Cheat Sheets For Developers</a></li>
<li><a href="https://dev.to/ibrahima92/advanced-typescript-types-cheat-sheet-with-examples-5414">Advanced TypeScript Types cheat sheet (with examples)</a></li>
<li><a href="https://dev.to/ericchapman/react-cheat-sheet-updated-may-2021-1mcd">React Cheat sheet (Updated June 2021)</a></li>
<li><a href="https://dev.to/ali6nx404/cheat-sheets-that-always-save-my-time-during-web-development-2ga4">Cheat Sheets that always save my time during web development</a></li>
</ul>
<h2>Security</h2>
<p>Web development security guides to know about. Best practises with examples and beginner tutorials.</p>
<ul>
<li><a href="https://dev.to/shaikhshahid/a-guide-to-securing-node-js-applications-4bcc">A Guide to Securing Node.js Applications</a></li>
<li><a href="https://dev.to/kimmaida/authorization-and-authentication-for-everyone-27j3">Authorization and Authentication For Everyone</a></li>
<li><a href="https://dev.to/bearer/api-security-best-practices-3gjl">API Security Best Practices</a></li>
<li><a href="https://dev.to/ahmedatefae/web-security-knowledge-you-must-understand-it-part-i-https-tls-ssl-cors-csp-298l">Web security knowledge you must understand it (Part I: HTTPS, TLS, SSL, CORS, CSP)</a></li>
<li><a href="https://dev.to/maleta/cors-xss-and-csrf-with-examples-in-10-minutes-35k3">CORS, XSS and CSRF with examples in 10 minutes</a></li>
<li><a href="https://dev.to/ctrlshifti/how-to-learn-penetration-testing-a-beginners-tutorial-505a">How to Learn Penetration Testing: A Beginners Tutorial</a></li>
<li><a href="https://dev.to/vaibhavkhulbe/7-security-tips-for-your-react-application-4e78">7 security tips for your React application</a></li>
</ul>
<h2>APIs</h2>
<p>List of fun APIs to use for your next project. Find free and unique APIs for developers.</p>
<ul>
<li><a href="https://dev.to/renaissanceengineer/7-unique-apis-for-your-next-project-4hf9">7 Unique APIs for your next project</a></li>
<li><a href="https://dev.to/hb/10-fun-apis-to-use-for-your-next-project-2lco">10 Fun APIs to Use For Your Next Project</a></li>
<li><a href="https://dev.to/monicafidalgo/12-apis-that-you-as-a-developer-will-love-it-4ec6">12 APIs that you as a developer will love it</a></li>
<li><a href="https://dev.to/biplov/15-fun-apis-for-your-next-project-5053">15 Fun APIs For Your Next Project</a></li>
</ul>
<h2>Uncatogorized Reading</h2>
<p>Free certificates, popular git repositories and tips for how to be good at googling. Learn how to prevent sites from showing up at google.</p>
<ul>
<li><a href="https://dev.to/g_abud/advanced-git-reference-1o9j">Git Concepts I Wish I Knew Years Ago</a></li>
<li><a href="https://dev.to/perssondennis/how-to-report-a-site-that-steals-your-articles-5040">How To Report a Site That Steals Your Articles</a></li>
<li><a href="https://dev.to/simonholdorf/9-popular-github-repos-for-every-web-developer-31ej">9 Popular GitHub Repos For Every Web Developer</a></li>
<li><a href="https://dev.to/denicmarko/google-like-a-pro-5cf6">Use Google like a pro</a></li>
<li><a href="https://dev.to/samborick/100-project-ideas-oda">100+ Project Ideas</a></li>
<li><a href="https://dev.to/panx/50-free-awesome-certificates-to-earn-in-2021-2l7g">70+ Free Awesome Certificates to Earn in 2021</a></li>
</ul>
<h2>More Lists Like This</h2>
<p>Do you need more lists of programming resources? If this list isn't extensive enough, you can find other lists like this here.</p>
<ul>
<li><a href="https://dev.to/rahxuls/free-ultimate-resources-for-front-end-development-in-2021-giveaway-3838">{FREE} Ultimate Resources for Front-End Development in 2021 + Giveaway</a></li>
<li><a href="https://dev.to/pb/10-github-repositories-every-developer-should-know-ngm">10 GitHub Repositories every Developer should know</a></li>
<li><a href="https://dev.to/simonholdorf/10-awesome-github-repos-every-web-developer-should-know-27oa">10 Awesome Github Repos Every Web Developer Should Know</a></li>
<li><a href="https://dev.to/sahilrajput/useful-websites-for-programmers-36k">Useful resources for programmers</a></li>
<li><a href="https://dev.to/nickytonline/frontend-developer-resources-2022-4cp2">Frontend Developer Resources 2022</a></li>
<li><a href="https://dev.to/aspittel/my-favorite-free-resources-for-new-programmers-bia">My Favorite Free Resources for New Programmers</a></li>
<li><a href="https://dev.to/olanetsoft/10-github-repositories-you-should-know-as-a-developer-4l0p">10+ Github Repositories You Should Know as a Developer</a></li>
<li><a href="https://dev.to/madza/19-valuable-github-repositories-for-beginner-developers-3i18">19 Valuable GitHub Repositories for Beginner Developers</a></li>
<li><a href="https://dev.to/simonholdorf/10-extraordinary-github-repos-for-all-developers-2ag8">10 Extraordinary GitHub Repos for All Developers</a></li>
<li><a href="https://dev.to/gedalyakrycer/165-developer-resources-i-discovered-in-2020-2021-6ma">165+ Developer Resources I Discovered in 2020-2021</a></li>
<li><a href="https://dev.to/ender_minyard/28-code-tutorials-for-visual-learners-19pl">32 Code Tutorials for Visual Learners</a></li>
<li><a href="https://dev.to/iamismile/web-development-resources-96">Web Development Resources</a></li>
</ul>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Backend</category>
            <category>Frontend</category>
            <category>Productivity</category>
            <category>UI</category>
            <enclosure url="https://www.perssondennis.com/images/articles/extensive-list-of-best-development-resources-121-links-to-guides-cheat-sheets-and-more-list-of-resources/extensive-list-of-best-development-resources.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[From Programmer to Software Developer – The Skills That Make the Difference]]></title>
            <link>https://www.perssondennis.com/articles/from-programmer-to-software-developer</link>
            <guid>https://www.perssondennis.com/articles/from-programmer-to-software-developer</guid>
            <pubDate>Sun, 01 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[The difference between programmers and developers lies in soft skills. Learn how communication, collaboration, and self-awareness make a great developer.]]></description>
            <content:encoded><![CDATA[<p>Programmer and developer are often used interchangeably, but there is an important distinction between them: the developer’s broader perspective and focus beyond just code. In this article, we will step back from coding to highlight the skills that define what skills a successful developer should have.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#architectural-skills">Architectural Skills</a>
<ul>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#best-practices-and-anti-patterns">Best Practices and Anti-Patterns</a></li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#design-patterns">Design Patterns</a></li>
</ul>
</li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#communication">Communication</a></li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#eliminating-dependencies">Eliminating Dependencies</a></li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#build-a-team">Build a Team</a></li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#build-a-network">Build a Network</a></li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#who-should-do-the-work">Who Should Do the Work?</a>
<ul>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#what-does-responsibility-mean">What Does Responsibility Mean?</a></li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#dont-do-the-work-for-others">Don't Do the Work For Others</a></li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#to-delegate-or-not">To Delegate or Not</a></li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#dont-ask-what-to-do">Don't Ask What to Do</a></li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#learn-by-teaching">Learn by Teaching</a></li>
</ul>
</li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#personal-traits">Personal Traits</a>
<ul>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#what-are-traits">What are Traits?</a></li>
<li><a href="https://www.perssondennis.com/articles/from-programmer-to-software-developer#is-extreme-better-than-being-average">Is Extreme Better than Being Average?</a></li>
</ul>
</li>
</ul>
<h2>Programmer vs Software Developer</h2>
<p>Most people know these two terms as synonyms, and they indeed are. However, if you search on Google, you'll notice there is a distinction. The difference isn't about how they work with code, but rather their perspective on work and software development.</p>
<table>
<thead>
<tr>
<th></th>
<th>Programmer</th>
<th>Developer</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Focus on</strong></td>
<td>Implementation</td>
<td>Solving problems</td>
</tr>
<tr>
<td><strong>Creates</strong></td>
<td>Code</td>
<td>Solutions</td>
</tr>
<tr>
<td><strong>Involved in</strong></td>
<td>Development and testing</td>
<td>Full DevOps lifecycle</td>
</tr>
<tr>
<td><strong>Works with</strong></td>
<td>Code</td>
<td>Code and people</td>
</tr>
<tr>
<td><strong>Takes responsibility for</strong></td>
<td>The code</td>
<td>The product</td>
</tr>
</tbody>
</table>
<p>The table above shows different perspectives that a programmer and a full-fledged developer can have. A programmer's view is narrow and focuses on code and its immediate environment: writing clean code with proper architecture, testing it thoroughly, and delivering it to the next department or pushing it directly to production.</p>
<p>A software developer, however, has a much wider view on development. It isn't just about writing code; it's about collaboratively building a product that solves customer problems. This rarely involves just a single team, but rather many teams across the full DevOps lifecycle, from the planning phase all the way to monitoring the deployed product.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/devops-lifecycle.webp" alt="DevOps lifecycle">
<em>DevOps lifecycle</em></p>
<p>This doesn't necessarily mean that a developer is working on the entire DevOps chain. The important part is that the developer understands and are involved in the full lifecycle and actively tries to improve and optimize the process. It's also about being available when other teams need assistance, so the organization as a whole can deliver a quality product.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/two-responsible-persons.webp" alt="Two responsible persons">
<em>Looking at the whole product solution is essential</em></p>
<h2>Architectural Skills</h2>
<p>Let's start with the most obvious skill a software developer needs to have - one that even programmers should possess: architecting. Though this may seem obvious, it's worth emphasizing due to its importance and the fact that many people neglect it.</p>
<p>A common role in software development is that of the architect. An easy mistake is believing that the team architect is solely responsible for the architecture of all applications owned by the team, which simply isn't true. Every developer should contribute to improving code architecture and must therefore know and practice it. While architects work at a higher and broader level, all developers share the responsibility of keeping the code clean.</p>
<h3>Best Practices and Anti-Patterns</h3>
<p>There are best practices and anti-patterns for all languages and frameworks. They differ somewhat and change over time. For example, my article about <a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts">do's and don'ts in React</a> from last year is still highly relevant, but with the new compiler in React 19, several of those 17 rules will become outdated.</p>
<p>What's important to remember is to always research best practices and anti-patterns when starting with a new language or framework. Those hours of reading saves significant time that would otherwise be spent on debugging and refactoring. In extreme cases, we're talking about months or even years of development time saved.</p>
<h3>Design Patterns</h3>
<p>Design patterns play a big role in architecting. The difference between good and bad code often lies in the usage of design patterns. Most design patterns are language-agnostic, meaning you can use them regardless of what language or framework you're using. Additionally, each framework has its own set of design patterns and is built on patterns that consumers should follow.</p>
<p>One of the most well-known general design patterns is SOLID. It's a universal design pattern that works with most frameworks. Some frameworks are already based on it, and users of these frameworks will automatically follow the pattern. Other frameworks can benefit from it, even though it isn't always obvious how to adapt to it. For example, React doesn't automatically follow SOLID principles, but if you understand how SOLID principles work, you can <a href="https://www.perssondennis.com/articles/write-solid-react-hooks">apply them to React</a> as well.</p>
<p>React also serves as a good example for framework-specific design patterns, where you have patterns like Render Props, Custom Hook Pattern, and Higher Order Components.</p>
<p>The key point is twofold: take time to learn about design patterns in general, and make sure to look up framework-specific design patterns when starting with a new framework.</p>
<p>In general, design patterns make code more:</p>
<ul>
<li>readable</li>
<li>testable</li>
<li>modular</li>
<li>robust</li>
<li>DRY (Don't Repeat Yourself)</li>
</ul>
<p>These aspects are necessary for writing reusable code and collaborating with co-workers. Design patterns also help prevent bugs.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/bug-bedtime-stories-meme.webp" alt="Bug bedtime stories meme">
<em>Design patterns are not completely bug-proof</em></p>
<h2>Communication</h2>
<p>As a developer, you're most often building part of a larger system. Without proper communication with other teams to ensure your software works with the rest of the system, your part becomes useless. And without communication within your own team, you won't even finish your component on time.</p>
<p>Communication is vital in every project. Unfortunately, it's very challenging. I could write numerous articles about communication difficulties and how to communicate effectively, but that's not my focus today.</p>
<p>For now, just remember that communication is a important part of a developer's job, and it's just as important as being proficient at coding. If you'd like to learn more, I do have additional tips on <a href="https://www.perssondennis.com/articles/three-simple-rules-to-solve-unsolvable-organizational-problems#communication">how to communicate effectively in large organizations</a>.</p>
<h2>Eliminating Dependencies</h2>
<p>In my early days, when I struggled with communication with certain individuals and teams, my initial reaction was often to provide super clear instructions and closely follow up on processes to ensure tasks were completed by others. When that didn't work, I would finally give up and do the work myself just to get it done.</p>
<p>That's when I realized that the best type of communication is when it isn't needed at all. If there's nothing that needs to be communicated, there cannot be any communication issues.</p>
<p>An important detail here: I'm not suggesting that you should skip communication and do other people's work yourself. Rather, I'm saying that work should be divided into different areas in a way that minimizes the need for communication.</p>
<p>When building teams, people usually talk about cross-functional teams - teams that have all the competencies needed to develop, deploy, and monitor their product without dependencies on other teams.</p>
<p>Cross-functional teams often refers to having the knowledge and skills to be self-organized, which means they have all the necessary expertise to manage their dependencies.</p>
<p>Once again, there's a lot to cover in this article, so I won't deep dive into this topic. If you're interested, you can read more about eliminating dependencies in <a href="https://www.perssondennis.com/articles/three-simple-rules-to-solve-unsolvable-organizational-problems#dependency-elimination">my other article</a>, which also covers similar tips for team collaboration and communication.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/not-the-time-to-communicate.webp" alt="Not the time to communicate">
<em>An important part of communication is to know when not to communicate</em></p>
<h2>Build a Team</h2>
<p>Team building is a term most often associated with fun activities and occasional after-work gatherings. While these are definitely important aspects of team building, they're far from the whole picture.</p>
<p>Does your team have common goals? Have you agreed on <a href="https://www.perssondennis.com/articles/the-art-of-code-review-and-why-you-need-it">how to handle code reviews</a>? Do you know why your team never answers questions in the team's Slack channel? If the answers to these questions are no, you haven't fully built a team yet.</p>
<p>Team building should be about discussing ideas, resolving conflicts and disagreements, and finding a common way of working that the entire team agrees to. It's about sharing knowledge and experiences so all teammates are comfortable working with the team and facing upcoming features and bugs. It's about helping teammates work both independently and collaboratively.</p>
<p>The way to accomplish this often involves meetings. These don't have to be formal meetings with strict agendas, but there must be occasions where the team gathers to communicate. Some discussions might require a full hour, while other topics can be addressed during small sync meetings.</p>
<p>For instance, a good time to discuss expectations for code reviews is during the actual code reviews! Instead of just talking about how to change the code, make sure to discuss why you think the changes are needed. Why do you think it's important, and what do your teammates think about it?</p>
<p>One final note - team building is for the entire team. While certain roles such as Scrum Master and team leader come with the responsibility of building a team, they aren't the only ones who should strive to improve it. Building a team is teamwork, not a task for a single person.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/spiderman-team.webp" alt="Spiderman team">
<em>Even superheroes need a team</em></p>
<h2>Build a Network</h2>
<p>Have you ever been stuck on a problem? A time when you've sought help but no one had time to assist? Have you felt that no one was listening to what you were saying, even though you later turned out to be correct? Why does this happen?</p>
<p>People are commonly busy, and it isn't possible to always consider everyone's opinion. What you need to do is make your voice heard. Too often, the way to do so is to speak loudly and confidently state that your solution or problem is what needs to be considered.</p>
<p>However, not everyone is comfortable doing that. Fortunately, there's another way to make your voice heard - by finding someone who listens to you even when you whisper.</p>
<p>Who are the people most likely to help you when you're in need? It's family, friends, and acquaintances. It's very rare for people to help strangers, especially when it means taking on additional work.</p>
<p>By building a network and making friends, you'll find yourself getting help more often and much faster. People prioritize helping friends, both because it's someone they like and because it's more difficult to say no to a friend.</p>
<p>The ease of making friends varies from person to person, but everyone gets opportunities. Simply say a brief comment or ask a question to someone while standing in line for coffee, or make a point to talk to the designer about something you're wondering about in the Figma designs instead of guessing or sending a Slack message. Whatever you do, don't ask other people to talk to someone for you, then you are missing out on a new friend.</p>
<p>In the end, you don't need to be best friends with everyone for them to help you. Just talking with someone for five minutes can be enough for them to consider you as someone they know and someone they want to be respectful and polite to.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/marvel-network.webp" alt="Marvel network">
<em>The more the merrier</em></p>
<h2>Who Should Do the Work?</h2>
<p>Everyone knows about the famous "someone". It's always "someone's" fault as soon as something doesn't work out. "Someone" was supposed to handle it.</p>
<p>But who is this someone? Unfortunately, it's often difficult to identify them, which is why there's a need to talk about responsibilities and who should do the work. The interesting thing is that it's more often than not true that the responsible person should do the work.</p>
<h3>What Does Responsibility Mean?</h3>
<p>What does it really mean to be responsible? Being responsible doesn't actually mean you must do the work yourself, it means that the expecations on you is to get the work done. It's fully possible for you to delegate the whole task to someone else, giving them the responsibility.</p>
<p>True responsibility involves a commitment to ensure success, but it also calls for encouraging others to contribute toward that goal. A CEO of a tech company has a lot of responsibilities, but in the end, it will be a whole organization of developers, managers, and other people who do the actual work to develop a product.</p>
<p>Similarly, an architect in a team is responsible for ensuring that the team has and follows architectural guidelines when writing code. However, this doesn't mean it's the architect's job to write all the code or even to define every aspect of the architecture. The entire development team should collaborate to enhance code quality and adhere to agreed-upon patterns and practices.</p>
<p>An interesting thing about responsibility is that it often can be delegated to others. However, when that is done, the accountability usually stays with the person who delegated the responsibility; it's only the responsibility of handling the work which is transferred. Meaning, if something goes wrong and the project fails or gets delayed, then it's the accountable person who will have to take the blame.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/who-should-do-the-work.webp" alt="Who should do the work">
<em>Sometimes it's actually everyone's responsibility</em></p>
<h3>Don't Do the Work For Others</h3>
<p>Doesn't everybody love that person at work who amazingly manages to fix all the problems for everyone? Well, I do too, but I know it isn't optimal behavior.</p>
<p>Taking on other people's work only creates a cycle where people rely on others to complete their tasks. The day that amazing employee quits, the whole team or even multiple teams will find themselves in a tricky situation.</p>
<p>Instead of doing the work for others, invest the time to guide them on how to handle it themselves. Though it may take longer initially, once they're self-sufficient, you'll save significant time and effort.</p>
<h3>To Delegate or Not</h3>
<p>While you shouldn't do others' work for them, this doesn't mean you should avoid tasks outside your direct responsibilities. Remember, work shouldn't fall solely on the person responsible, that person can delegate tasks so everyone can contribute to getting them done.</p>
<p>There are different types of tasks, however. If you are responsible for something, it's likely there is more work than one person can manage alone. In that case, delegation is essential, but deciding what to delegate depends on the nature of the task. If it's a small, one-time task, avoid delegating it since it may take longer to explain than to complete it yourself.</p>
<p>For tasks that are time-consuming or recurring, consider them candidates for delegation. Here, you should weigh the implications of delegating: if a task is critical, you might choose to handle it personally, even if assigning it would save significant time.</p>
<h3>Don't Ask What to Do</h3>
<p>Asking for permission and double-checking that what you do is appreciated is nice to do once in a while, so you don't spend a month doing something completely unnecessary. But on a daily basis, quit it.</p>
<p>Just as a team should be self-organized, you as a developer must be able to take care of yourself. You cannot have a manager or team lead who is always supposed to tell you what you should do for the day or how to solve each problem.</p>
<p>What you should do is figure that out yourself. This doesn't mean you cannot talk to anyone. Remember, communication is an important part of development. If you are uncertain or if you are working with bigger tasks, discuss it with your development team to see what they think about it. Make sure to describe the problem clearly and suggest some potential solutions you have thought of.</p>
<p>Do you see the difference here? The difference is that you are working together with your development team; you are all collectively responsible for developing your product. If you are an eight-person team, you have eight brains which can be part of making a good decision. If you instead go to a team lead to ask what to do, you are basically neglecting your own willingness to make decisions and putting all the responsibility on a single brain. That's not a good approach for solving problems.</p>
<p>Sure, you will make mistakes. Live with that. That's the way to grow in life. It's not just a saying that what doesn't kill you makes you stronger.</p>
<h3>Learn by Teaching</h3>
<p>If you read the article I linked to in the communication chapter, you should have seen the learning pyramid. You may then have noticed that the retention rate of what you learn when you teach others was as high as 90%, compared to only 10% of what you read.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/learning-pyramid.webp" alt="Learning pyramid">
<em>According to the learning pyramid, you remember 90% of what you teach others</em></p>
<p>Surprisingly, this pyramid tells you that you are the one who is learning the most when your intention is to teach others. And next after that, you will learn the most by practicing doing something.</p>
<p>Note how this aligns with other topics we have discussed here, about being involved in solving problems, building a team, and stopping asking others for instructions of what to do. The foundation of all those has been to take action and actively work on improving the team and coming up with solutions to problems. These are actions which involve group discussions, practicing problem solving, and teaching others, all of which are at the bottom of the learning pyramid.</p>
<p>In contrast, if you only take orders from others, only listen to what they say, and read about how they solved an issue or write code they have told you to write, then you work purely at the top of the pyramid, which means you are learning very ineffectively by reading, hearing, and watching demonstrations.</p>
<p>As a bonus of teaching others, you will get to face the most tricky questions. You might tear your hair out or feel embarrassed when not knowing the answer to a question someone asks you, but in a few years, you will be the one who knows it all.</p>
<h2>Personal Traits</h2>
<p>We have now talked about some technical skills a developer needs, and some soft skills for how to handle communication and interact with others - the kind of skills that are important when it comes to how you interact with other people.</p>
<p>What we haven't talked about yet is who you are as a person - your personal traits which define who you are. These might be difficult to change, but you might not need to. As we will see, the most important part is learning when there is a need to adjust them.</p>
<h3>What are Traits?</h3>
<p>When speaking about personalities, traits are characteristics of a personality. There are plenty of models trying to model human personalities, where DISC, MBTI (Myers-Briggs Type Indicator), and Big Five are the most well-known ones.</p>
<p>The DISC model is a very simple model, it divides people into four different personalities, which we won't dive deeper into in this article.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/DISC.webp" alt="DISC personality model">
<em>DISC personality model</em></p>
<p>MBTI takes it a step further and divides people into 16 groups. It's a very popular and researched personality model, but it's not scientifically accepted.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/MBTI.webp" alt="MBTI personality model">
<em>MBTI personality model</em></p>
<p>The scientific world generally prefers the Big Five theory. Big Five is similar to MBTI, it includes extroversion vs introversion together with four other traits.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/the-big-five.webp" alt="The Big Five personality model">
<em>The Big Five personality model</em></p>
<p>MBTI and The Big Five are two fairly similar models, and the reason why Big Five is accepted scientifically is not because Big Five has better traits in it; it's because it defines people on a scale.</p>
<p>The Big Five doesn't categorize people, it claims that humans are more complex than 16 personalities and that each trait has a scale. This means a person is not necessarily extroverted or introverted; they can be somewhere in between on the scale, which is called ambivert.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/ambivert-scale.webp" alt="Ambivert on a scale">
<em>The Big Five represents personal traits on scales</em></p>
<h3>Is Extreme Better than Being Average?</h3>
<p>If we follow the idea of having a scale for each trait a human has, we can start judging whether specific traits are good or bad. Let's take perfectionism for example.</p>
<p>There are many types of perfectionists: self-oriented, other-oriented, socially prescribed, etc. Most of these types would, according to the Big Five theory, be quite neurotic and conscientious persons who aren't very open to criticism. Doesn't sound very attractive, does it?</p>
<p>Personally, I see loads of problems with perfectionism. Frankly, I have been one myself but worked hard to get rid of it. Nevertheless, I cannot claim it is a bad thing that should be avoided. In fact, it is sometimes very beneficial; for instance, when being a high-level architect for a big corporation with hundreds or thousands of developers, then it is somewhat necessary to be a perfectionist.</p>
<p>The thing here is that there are no consistently good or bad traits. Each trait has its own advantages and disadvantages. It depends on the situation you are in if a trait is good or not.</p>
<p>For instance, take the architect as an example. I claimed perfectionism is a good trait for a high-level architect in a big corporation. In a startup company, however, it's undesirable to be a perfectionist, for real. Startup companies are all about speed and agility. You need to quickly iterate with customers to find out what they need, and you need to do it quicker than your competitors and before your money runs out.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/speed-vs-quality-scale.webp" alt="Speed vs quality scale">
<em>Dependent on your role, you might need to focus on quality or being fast</em></p>
<p>Generally, being an extremist in any area is rarely beneficial. Whether it involves levels of extraversion or introversion, religious beliefs, or political views, being at the far end of any spectrum can lead to challenges. To complicate it a bit, it's neither beneficial to be strictly average. Unique skills are often essential to accomplish things in life.</p>
<p>The truth is, an ideal person cannot be pinpointed on a fixed scale; rather, they have the ability to exist anywhere along it. Such a person is fully aware of their behavior and can adapt it to suit the situation at hand. This adaptability depends not only on the task but also on the characteristics of those they interact with - remember, effective communication with others is essential.</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/careless-vs-organized-scale.webp" alt="Careless vs organized scale">
<em>Even within the same role, you might need to act differently dependent on tasks</em></p>
<p>Think about Peter Parker for a while. How would you describe his personality? Would you describe it the same way as you described Spiderman's?</p>
<p><img src="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/spiderman-and-peter-parker.webp" alt="Spiderman and Peter Parker">
<em>There're times when you have to be someone else (yes, that's supposed to be Peter Parker)</em></p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Productivity</category>
            <category>SoftSkills</category>
            <enclosure url="https://www.perssondennis.com/images/articles/from-programmer-to-software-developer/from-programmer-to-software-developer.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Give Your DRY Tests a WET Touch]]></title>
            <link>https://www.perssondennis.com/articles/give-your-dry-tests-a-wet-touch</link>
            <guid>https://www.perssondennis.com/articles/give-your-dry-tests-a-wet-touch</guid>
            <pubDate>Sun, 26 Mar 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[DRY and WET unit and e2e tests both have their pros and cons. By adding a WET touch to your DRY tests you can write short and readable tests very easily.]]></description>
            <content:encoded><![CDATA[<p>For quite some time, the commonly accepted practice has been to write DRY code, but there are developers who suggest using WET code. The purpose of this article is to demonstrate how to combine DRY and WET code to write better test cases.</p>
<p>The tests are written in Jest for React, but the chose of test framework doesn't really matter. You can give your DRY tests a WET approach in any language or framework. The approach can even be used for unit tests as well as integration and e2e tests.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/give-your-dry-tests-a-wet-touch#dry-vs-wet">DRY vs WET</a></li>
<li><a href="https://www.perssondennis.com/articles/give-your-dry-tests-a-wet-touch#wet-unit-tests">WET Unit Tests</a></li>
<li><a href="https://www.perssondennis.com/articles/give-your-dry-tests-a-wet-touch#dry-unit-tests">DRY Unit Tests</a></li>
<li><a href="https://www.perssondennis.com/articles/give-your-dry-tests-a-wet-touch#the-problem-with-the-dry-tests">The Problem With the DRY Tests</a></li>
<li><a href="https://www.perssondennis.com/articles/give-your-dry-tests-a-wet-touch#dry-tests-with-a-wet-touch">DRY Tests With a WET Touch</a></li>
<li><a href="https://www.perssondennis.com/articles/give-your-dry-tests-a-wet-touch#dry-tests-with-a-wet-touch-using-build-design-pattern">DRY Tests With a WET Touch Using Build Design Pattern</a></li>
<li><a href="https://www.perssondennis.com/articles/give-your-dry-tests-a-wet-touch#conclusion">Conclusion</a></li>
</ul>
<h2>DRY vs WET</h2>
<p>First of all, let's shortly describe what DRY and WET code is for those who doesn't now about it. DRY (Don't Repeat Yourself) and WET (Write Everything Twice) are two terms used to describe different programming styles.</p>
<p>DRY code is more efficient and easier to maintain because it eliminates duplicate code. Changes made in one place affect all related code, making it easier to update and modify. DRY code is easier to understand and to reason about, which can improve code quality and reduce errors.</p>
<p>On the other side, WET code can be faster to write initially because it relies on copying and pasting existing code. WET code can be easier for less experienced programmers to understand because it is more explicit and detailed. In some cases, WET code may be more suitable when the code is simple and unlikely to change in the future.</p>
<h2>WET Unit Tests</h2>
<p>This example shows three simple example test cases for updating a user object. This code is WET, since the initialization for the test data is copied into each an every test. In this short example, the only test setup data is the <em>user</em> object, but in more complex test cases it can consist of much more data than that.</p>
<pre><code class="language-javascript">describe('Users', () => {
    test('increments Alice\'s age by 1 when she has a birthday', () => {
        const user = {
            name: 'Alice',
            age: 26,
            friends: ['Britney', 'Chili', 'Dennis']
        }

        haveABirthday(user)
        expect(user.age).toBe(27)
    })

    test('adds a new friend to the friend list', () => {
        const user = {
            name: 'Alice',
            age: 26,
            friends: ['Britney', 'Chili', 'Dennis']
        }

        makeANewFriend(user, 'Elliot')
        expect(user.friends).toContain('Elliot')
        expect(user.friends).toHaveLength(4)
    })

    test('removes a friend from the list when being stupid', () => {
        const user = {
            name: 'Alice',
            age: 26,
            friends: ['Britney', 'Chili', 'Dennis']
        }

        playRussianRouletteWithFriends(user)
        expect(user.friends).toHaveLength(2)
    })
})
</code></pre>
<h2>DRY Unit Tests</h2>
<p>Although there wasn't anything wrong with the WET tests above, the test file can be much briefer if we lift out the initialization in a beforeEach function, which will run before each test case.</p>
<p>For a file with tens of tests, that change will save a lot of lines of code and make the whole test file easier to read. And even each test itself can get a lot less bloated with the DRY approach. In this case, each test can be written in 4-5 lines instead of 10-11 lines as in the WET case.</p>
<pre><code class="language-javascript">describe('Users', () => {
    let user

    beforeEach(() => {
        user = {
            name: 'Alice',
            age: 26,
            friends: ['Britney', 'Chili', 'Dennis']
        }
    })

    test('increments Alice\'s age by 1 when she has a birthday', () => {
        haveABirthday(user)
        expect(user.age).toBe(27)
    })

    test('adds a new friend to the friend list', () => {
        makeANewFriend(user, 'Elliot')
        expect(user.friends).toContain('Elliot')
        expect(user.friends).toHaveLength(4)
    })

    test('removes a friend from the list when being stupid', () => {
        playRussianRouletteWithFriends(user)
        expect(user.friends).toHaveLength(2)
    })
})
</code></pre>
<h2>The Problem With the DRY Tests</h2>
<p>Many test files appear very similar to the previous DRY test file. However, programmers who prefer WET programming have a valid argument against writing tests in that way. The reason being that it's common for people to forget the data used to initialize their tests.</p>
<p>For instance, the first of our tests is the age test.</p>
<pre><code class="language-javascript">    test('increments Alice\'s age by 1 when she has a birthday', () => {
        haveABirthday(user)
        expect(user.age).toBe(27)
    })
</code></pre>
<p>Now, without scrolling up to look at the test data, answer how old Alice were before having a birthday?</p>
<p><img src="https://www.perssondennis.com/images/articles/give-your-dry-tests-a-wet-touch/i-am-not-old.webp" alt="I am not old meme">
<em>I promise, it's not a bug!</em></p>
<p>Well, if you know math better than meth, you can probably calculate that she must have been 26 before her birthday. But you cannot be sure that the haveABirthday function works, that's the very reason you are writing that test.</p>
<p>To be able to see how old she really were before the birthday function was invoked, you would have to scroll up to the definition of the <em>user</em> variable in the beforeEach at the top of the file. Doing that over and over again can be quite annoying, and if you have written many DRY tests, you most probably get what I mean.</p>
<p>Furthermore, if you would change the age in the beforeEach, you have no idea how many tests you would to fail.</p>
<p>Now tell me, how can we circumvent issues like those? One way to do that is to add a WET touch to your DRY tests!</p>
<h2>DRY Tests With a WET Touch</h2>
<p>With DRY tests with a WET touch, we get rid of the unexpressive beforeEach function and instead write some initialization functions. By naming the functions appropriately and specifically using them in each test case, we can achieve both readable and brief tests in which we have all the information we need.</p>
<pre><code class="language-javascript">const createTwentySixYearsOldUser = () => {
    return {
        name: 'Alice',
        age: 26,
    }
}

const createUserWithThreeFriends = () => {
    return {
        name: 'Alice',
        friends: ['Britney', 'Chili', 'Dennis']
    }
}

describe('Users', () => {
    test('increments Alice\'s age by 1 when she has a birthday', () => {
        const user = createTwentySixYearsOldUser()
        haveABirthday(user)
        expect(user.age).toBe(27)
    })

    test('adds a new friend to the friend list', () => {
        const user = createUserWithThreeFriends()
        makeANewFriend(user, 'Elliot')
        expect(user.friends).toContain('Elliot')
        expect(user.friends).toHaveLength(4)
    })

    test('removes a friend from the list when being stupid', () => {
        const user = createUserWithThreeFriends()
        playRussianRouletteWithFriends(user)
        expect(user.friends).toHaveLength(2)
    })
})
</code></pre>
<h2>DRY Tests With a WET Touch Using Build Design Pattern</h2>
<p>The approach to write DRY tests with a WET touch should be enough for most fairly small test cases. But if you are one of those who like structure, or if you are using the same data to initialize plenty of tests, you could go the bit more cumbersome way and initialize your data with the build design pattern.</p>
<p>In that case, you can write a class for a basic user, then add builder functions to add attributes to it. This one is written as a JavaScript class, but you can do the same thing using regular functions.</p>
<pre><code class="language-javascript">class User {
  constructor(name) {
    this.name = name
    this.age = null
    this.friends = []
  }

  setAge(age) {
    this.age = age
    return this
  }

  addFriends(friends) {
    this.friends = this.friends.concat(friends)
    return this
  }
}
</code></pre>
<p>When you have a class like that, you can write test like this. And hopefully, you can even reuse it for multiple files.</p>
<pre><code class="language-javascript">describe('Users', () => {
    test('increments Alice\'s age by 1 when she has a birthday', () => {
        const user = new User('Alice').setAge(26)
        haveABirthday(user)
        expect(user.age).toBe(27)
    })

    test('adds a new friend to the friend list', () => {
        const friends = ['Britney', 'Chili', 'Dennis']
        const user = new User('Alice').addFriends(friends)
        makeANewFriend(user, 'Elliot')
        expect(user.friends).toContain('Elliot')
        expect(user.friends).toHaveLength(4)
    })

    test('removes a friend from the list when being stupid', () => {
        const friends = ['Britney', 'Chili', 'Dennis']
        const user = new User('Alice').addFriends(friends)
        playRussianRouletteWithFriends(user)
        expect(user.friends).toHaveLength(2)
    })
})
</code></pre>
<p>With this new improved test file, each test is only 5-7 lines, almost as thin as the 4-5 DRY lines and much thinner than the 10-11 WET lines. We do have all necessary information we need to see in each and every test, but we have cut out all the extra unnecessary information we had in the verbose WET tests.</p>
<p>Other developers at your company can look at these new brief tests and quickly understand what they do and if they work as intended. If they need to change any of the tests, they can simply do that right within the test. With the DRY tests, they would need to alter the data initialized in the beforeEach function, which potentially could destroy some of the other tests in the file, or in any other file if the test data is shared between several files.</p>
<h2>Conclusion</h2>
<p>WET tests quickly gets very bloated. By making them DRY, they get more comprehensible, but we risk to lose information in the test, making it necessary to scroll to definitions or open definitions in new files to see the data we are working with in the test. Altering that common data also have the potential to ruin plenty of other test cases.</p>
<p>By combining the advantages of DRY and WET tests, we can write short readable tests where we can see all necessary information directly in the test without having to scroll or look up test data.</p>
<p>The key to doing that, is to write functions for the data initialization and use those functions in each test. For even more structure, when dealing with bigger amount of data and number of tests, one can use the builder pattern to customize the data on detail level for each test.</p>
<p>For non-trivial test examples, it will make a big difference in readability. For whole projects with much data, it will make a huge improvement.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Backend</category>
            <category>Frontend</category>
            <category>Testing</category>
            <enclosure url="https://www.perssondennis.com/images/articles/give-your-dry-tests-a-wet-touch/give-your-dry-tests-a-wet-touch.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[How I Improved Lighthouse Performance by Adding an Image]]></title>
            <link>https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image</link>
            <guid>https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image</guid>
            <pubDate>Sun, 21 Aug 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Lighthouse performance can actually be improved by adding a large image. Learn how to do that and optimize an image for a website in WebP or SVG format.]]></description>
            <content:encoded><![CDATA[<p>Images and videos are slow to load, and most bloggers and companies are eventually coming to the tough decision of whether to take the UI train and include a hero image or going for performance and wave goodbye to the hero. My turn for <a href="https://www.perssondennis.com/">my website</a> was to go both ways!</p>
<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#the-impact-of-loading-images">The Impact of Loading Images</a></li>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#web-vitals-largest-contentful-paint">Web Vitals - Largest Contentful Paint</a></li>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#the-inconsistency-of-getting-a-great-largest-contentful-paint-lcp-score">The Inconsistency of Getting a Great Largest Contentful Paint (LCP) Score</a></li>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#how-i-optimized-largest-contentful-paint-lcp-with-an-image">How I Optimized Largest Contentful Paint (LCP) With an Image</a></li>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#choosing-between-svg-png-and-webp">Choosing Between SVG, PNG and WebP</a></li>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#an-attempt-to-use-a-svg-and-css-solution">An Attempt to Use a SVG and CSS Solution</a></li>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#optimizing-webp-image-size">Optimizing WebP Image Size</a></li>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#serving-appropriately-sized-images">Serving Appropriately Sized Images</a></li>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#great-image-tools-to-use">Great Image Tools To Use</a></li>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#back-to-network-latency">Back To Network Latency</a></li>
<li><a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image#conclusion">Conclusion</a></li>
</ol>
<h2>The Impact of Loading Images</h2>
<p>An image is on average a thousand times as destructive for performance as a thousand words. That's not a joke. Websites are commonly encoded using UTF-8, which uses 1-4 bytes per character, just 1 byte for standard ASCII letters. Average English word is about 5 characters, so a thousand words would be about 5 kB large. A quick google search on <a href="https://www.pingdom.com/blog/new-facts-and-figures-about-image-format-use-on-websites/">average image sizes on web</a> tells us that's in about the same order of magnitude as those 5 kB of words.</p>
<p>Keep in mind that's just an average number. Hero and banner images which are meant to cover the half or full viewport of a website is most often at least several 100 times as large as that, maybe even a thousand if poorly optimized.</p>
<p>The image size isn't the only time thief when loading images on web. Images are usually fetched by the browser in a separate network request which means there will be an additional server request which incur additional latency, and the request may even have to be queued for a time by the browser. As we will see later in this article, this fact can have a considerable impact.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/tesla-banner-image-model-3.webp" alt="Tesla&#x27;s banner image model 3">
<em>Tesla's 1.2 MB huge monster banner</em></p>
<p>As an example, <a href="https://www.tesla.com/">Tesla's</a> banner image of their Model 3 Tesla is 1.2 MB large and takes 364 ms to load after having waited 2 seconds to start download on my network with a fairly old MacBook Pro. According to Google, <a href="https://support.google.com/google-ads/answer/9147021?hl=en">53 % of users will leave a mobile site that takes longer than 3 seconds to load</a>. Just loading the image consumes a considerable share of that quota, and before it is finished rendered it has passed that time.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/tesla-image-timing.webp" alt="Tesla timing in Chrome inspector">
<em>Tesla Model 3 image loading time in Chrome inspector</em></p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/tesla-image-rendering-time.webp" alt="Tesla image takes over 3 seconds to render">
<em>Tesla Model 3 accelerates from 0 to 100 km/h in 3.3 s, that's faster than it takes to load the image of it</em></p>
<h2>Web Vitals - Largest Contentful Paint</h2>
<p>There are many ways measuring performance for a website. Google has initiated <a href="https://web.dev/vitals/">Web Vitals</a>, which is a bunch of metrics that Google think are important for serving a good UX. One of the metrics is <a href="https://web.dev/lighthouse-largest-contentful-paint/">Largest Contentful Paint (LCP)</a>, which measures the time until the largest text or image on the page is visible.</p>
<p>Google has released an open-source tool called <a href="https://developer.chrome.com/docs/lighthouse/overview/">Lighthouse</a> that can be used to measure web vitals and get scores and guidelines. It is built-in into Chrome Dev Tools but can also be used at <a href="https://pagespeed.web.dev/">PageSpeed Insights</a>. The metrics shown is meant to be used as a guidance and can vary between each test.</p>
<p>Although Lighthouse is just for guidance, most or all of the metrics are used directly or indirectly by Google to rank your website when it gets indexed by Google. It's therefore not only important for good UX, but also for <a href="https://moz.com/learn/seo/what-is-seo">SEO</a>.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/largest-contentful-page-tesla-score.webp" alt="Largest contentful paint score">
<em>Largest contentful paint is one of the metrics a Lighthouse test scores you on</em></p>
<h2>The Inconsistency of Getting a Great Largest Contentful Paint (LCP) Score</h2>
<p>While running Lighthouse speed tests at my website, I noticed that I got very different scores on different pages. My <a href="https://www.perssondennis.com/">main page that lists articles</a> and an <a href="https://www.perssondennis.com/articles/how-to-report-a-site-that-steals-your-articles">article page</a> scored significantly different on the performance metric, even though both pages was built almost in the same way with a profile picture, a lot of text and a few images. At the time doing this, the pages looked similar as today, but they did not have a hero image back then.</p>
<p>The culprit for the bad test result on the article page was the LCP score. The Lighthouse test provides a screenshot of the LCP, which made it clear why the article page did get a worse LCP score.</p>
<p>Since the main page had some extra chip components beneath the profile picture, the largest contentful paint on that page was the profile image. None of the dynamic blog articles was ever included in the viewport on a mobile device.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/largest-contentful-paint-on-my-landing-page.webp" alt="Largest contentful paint on my landing page">
<em>The LCP on my landing page is the profile picture</em></p>
<p>Meanwhile, on the article page, the first part of the blog article was included in the mobile viewport, meaning that Lighthouse was looking for the LCP in that area as well. The consequence, was that whenever an article began with an image, that image was treated as the LCP, since it was a larger image than my profile picture. If the image was left out, the profile picture was detected as the LCP.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/largest-contentful-paint-on-an-article-page.webp" alt="Largest contentful paint on an article page">
<em>The LCP on an article page with an image was the article image</em></p>
<h2>How I Optimized Largest Contentful Paint (LCP) With an Image</h2>
<p>I knew I couldn't keep going on with an unreliable LCP score, and it wasn't a good solution to never start an article with an image. I had to find a way to get a predictable score regardless of what content I included in the article itself.</p>
<p>With that in mind, I decided to add an image larger than any potential article image, I decided to add a hero image. That way, I could at least get control of which image was the largest and thereby take control over the LCP score.</p>
<p>For this to be effective, I had to use a hero image that was fast to load. Nothing would ever be better if I did like Tesla have done, adding a gigantic banner at the size of 1.2 MB. I had to use a small optimized image that could fill half the viewport, one that didn't scream poor resolution.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/lcp-on-article-page-with-hero-image.webp" alt="LCP on article page with a hero image">
<em>By adding a hero image, I could control which image I wanted to be the LCP</em></p>
<h3>Choosing Between SVG, PNG and WebP</h3>
<p>Well, I never really considered using a PNG image for the hero image, that's not the way to optimize web images. Although, I do always keep a PNG copy around for other usages. For example, when posting articles on DEV forum, they don't support WebP images to be uploaded as hero images.</p>
<p>Choosing between SVG and WebP was more difficult. SVG images can be really small if the image consists of a repeating pattern or an abstract pattern using only a few colors and shapes, just because they consist of vectors that can be scaled to any resolution. On the other hand, they will grow ridiculously big for graphic-heavy images with many colors and shadows, due to the high number of vectors required to represent the image.</p>
<p>On the contrary, WebP can compress images effectively by <a href="https://developers.google.com/speed/webp">predicting and reusing pixels</a>, making it superior to PNG and JPEG formats. So, the decision had to be between a minimal abstract hero image in SVG format or a realistic photograph in WebP format.</p>
<h3>An Attempt to Use a SVG and CSS Solution</h3>
<p>As you can see on my <a href="https://www.perssondennis.com/">website</a>, I do have a brick wall as the hero image (as long as you don't change the theme to dark mode). That image is in WebP format, but my first attempt was actually to use an SVG image. The brick wall I tried with then was less realistic and more cartoonish, which was served perfectly in SVG format.</p>
<p>To get rid of the extra network latency from fetching an image from a server, I <a href="https://www.svgbackgrounds.com/how-to-add-svgs-with-css-background-image/">embedded the image as a CSS background in a data URI</a>, which should really only be done when dealing with tiny images because of cache and parsing reasons.</p>
<p>Did it work? No, it didn't, the CSS background wasn't detected as the LCP. After all, it is neither a regular image or a text, so it complies with <a href="https://web.dev/lighthouse-largest-contentful-paint/">Google's description of LCP</a>.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/largest-contentful-paint.webp" alt="Largest contentful paint">
<em>Google's largest contentful paint definition</em></p>
<p>Even though a CSS solution did not work as expected, it did work to use the SVG image in a normal HTML image element (or to be accurate, Next.js Image component in my case). The only reason I discarded that solution was because I wasn't satisfied with the cartoonish style of the brick wall, I felt I wanted a more realistic brick wall.</p>
<h2>Optimizing WebP Image Size</h2>
<p>After having decided to use a photograph of a brick wall as the hero image, it was time to optimize the size of it without losing too much quality. I felt that I didn't need a pixel-perfect photograph, it was fine for me to sacrifice quality for loading speed. The initial image was a JPEG monster at 18.1 MB and a 6000 x 4000 resolution, so it could be optimized a lot.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/18-mega-bites-pun-meme.webp" alt="18 mega bites pun">
<em>My counsellor apologize on my behalf for a mega bad pun</em></p>
<p>Now, compressing images is not at all what I am good at, I'm sure compression fanatics would have hit me with their compression bible if they hadn't already compressed it into a holy script at a few kilobytes. But I did succeed to compress the image a lot, compressing it into a 2560 x 1707 WebP image of 37 kB. Obviously, I lost a massive amount of quality, that has to be mentioned.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/rar-picture-of-a-compression-fanatic-meme.webp" alt=".rar picture of a compression fanatic">
<em>I got so scared seeing him I zipped my mouth</em></p>
<p>The approach I used to compress my image was to use an online copy of Photoshop called <a href="https://www.photopea.com/">Photopea</a>. Only thing I did was to resize the image and save it in another format, and choosing to lower the quality while saving.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/photopea-save-dialog.webp" alt="Photopea save dialog">
<em>Photopea's save dialog allows you to preview image quality and image size at the same time</em></p>
<h2>Serving Appropriately Sized Images</h2>
<p>A hero image with a 2K resolution is fine for a 4K monitor, but serving a 2K image to a mobile device is not optimal. Small devices should be served small images. That can be achieved using a <a href="https://www.w3schools.com/tags/att_source_srcset.asp">HTML picture element with a srcset</a>.</p>
<p>In my case, I didn't have to handle that, because my website is written using Next.js. They have a built-in image component which can be used to optimize image loading. At my blog, you can find a guide for <a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs">implementing a hero image with that image component</a>, it also explains the benefits of using it.</p>
<p>The image component Next.js offer does not only serve images in different sizes. They also support specifying a quality of the image so they can compress it for you. In my case, it didn't compress the image enough, I experienced better results compressing it myself using Photopea.</p>
<h2>Great Image Tools To Use</h2>
<p>When working with images, you often have to manipulate images in certain ways. To easier do that, I suggest checking out <a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs">my list of free image tools</a>. Those tools can be used to resize and reformat images and to generate images and backgrounds. It also presents websites which offers royalty free images.</p>
<h2>Back To Network Latency</h2>
<p>As I promised in the beginning of this article, we would look at how network requests can be the bottleneck when optmizing image loading times. Look at the picture below. It shows the network timing tab available in Chrome Dev Tools for the hero picture I use on my website. We can see that it takes the same amount of time to get a response from the server as it takes to download the picture.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/cached-server-response-time.webp" alt="Cached server response time">
<em>It takes 32 ms to get a response when I visit my own website</em></p>
<p>But Dennis, you say, your image is very small, only 37 kB. 32 ms isn't a very long time. Yeah, that's correct. It's nothing to care about. Or at least it wouldn't be if it wasn't because I had reloaded my page multiple times to get that screenshot.</p>
<p>Reloading the page allows for the server to cache the image and serve it quickly the next time it is requested. When visiting my website during a cold boot at hours I don't have a lot of traffic to the site from Sweden, it can take 5, 10 or maybe 15 times as long time to get a response from the server. When that happens, the 32 ms download time for the image is negligible compared to the server response time.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/server-response-time.webp" alt="Server response time">
<em>Without a recent cache of the hero image, server response takes plenty of more time</em></p>
<h2>Conclusion</h2>
<p>What we learned in this article was that adding a large image to a website can actually improve Lighthouse performance tests. We learned what Largest Contentful Paint (LCP) is and how to optimize an image to maximize the LCP score.</p>
<p>We also took a look at when to use SVG images and when to use WebP images. I provided you with a <a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs">list of free image tools</a> which as an example can be used to reformat images in different ways, and explained the importance of keeping the image size low when using images on a website.</p>
<p>Finally, we saw an example of how server response time can be the bottleneck of web image performance when the images themselves has been compressed well enough to be very small.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Architecture</category>
            <category>Frontend</category>
            <category>React</category>
            <category>Performance</category>
            <category>UI</category>
            <enclosure url="https://www.perssondennis.com/images/articles/how-i-improved-lighthouse-performance-by-adding-an-image/how-i-improved-lighthouse-performance-by-adding-an-image.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[How To Avoid React Context Trap]]></title>
            <link>https://www.perssondennis.com/articles/how-to-avoid-react-context-trap</link>
            <guid>https://www.perssondennis.com/articles/how-to-avoid-react-context-trap</guid>
            <pubDate>Sun, 01 May 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[How to design React contexts according to best practices and how to avoid the React context trap. Why is it dangerous to keep contexts small.]]></description>
            <content:encoded><![CDATA[<p>Whatever code we ever invent we always seem to end up in hell. In the case of React contexts we have the <a href="https://dev.to/alfredosalzillo/the-react-context-hell-7p4">context hell</a>, which refers to the problem of bloating the code with a lot of context providers at the root level of you code.</p>
<pre><code class="language-javascript">// Example of context hell.
const ContextHellApp = () => (
  &#x3C;>
    &#x3C;ReduxProvider value={store}>
      &#x3C;ThemeProvider value={theme}>
        &#x3C;AnotherProvider value={anotherValue}>
          &#x3C;YetAnotherProvider value={yetAnotherValue}>
            &#x3C;GetItYetProvider value={yeahIGetItValue}>
              &#x3C;FinallyAComponent />
            &#x3C;/GetItYetProvider>
          &#x3C;/YetAnotherProvider>
        &#x3C;/AnotherProvider>
      &#x3C;/ThemeProvider>
    &#x3C;/ReduxProvider>
  &#x3C;/>
)
</code></pre>
<p>As you can see in the link, there's a suggested solution to it. Quite an easy solution for a quite minor issue. The context discussion shouldn't end there though. To me the context hell isn't the real issue here. <strong>What I consider problematic with contexts is what I like to call the <em>context trap</em></strong>.</p>
<h2>Keep Your Contexts Small</h2>
<p><strong>Whenever a React context i being updated, all components using that context will rerender</strong>. To avoid unnecessary renderings, one should keep the <a href="https://javascript.plainenglish.io/react-context-why-am-i-getting-unnecessary-re-renders-b61836d224a7">contexts as small as possible</a>.</p>
<p>By doing that, you will not only render components less often, you will also be able to move your context provider components further down the React tree if you only need them for parts of your application, which will save you from the context hell mentioned earlier.</p>
<pre><code class="language-javascript">// Context hell isn't a problem when keeping contexts small.
// If only parts of the app use a context, we can lift it down
// to a component within &#x3C;Component /> or even further down.
// Redux and theming affect the whole application, so we keep
// them here in the top-level component.
const SmallContextsApp = () => (
  &#x3C;>
    &#x3C;ReduxProvider value={store}>
      &#x3C;ThemeProvider value={theme}>
        &#x3C;Component />
      &#x3C;/ThemeProvider>
    &#x3C;/ReduxProvider>
  &#x3C;/>
)
</code></pre>
<p>Moving down context providers may not be necessary, but it can help developers understand what parts of the application that actually are affected by the context. On the other side, it may not be a great solution, since using that context outside of the provider will give birth to a bug.</p>
<p>Anyhow, I know, you are a good developer, you already knew you should keep your contexts small. You always keep your contexts as you keep your project's bundle size, slim fit.</p>
<h2>Introducing Context Trap</h2>
<p>Times changes, and suddenly you need a connection between two of your contexts. Maybe you have divided chats and messages into two separated contexts and you now need to look at the chat when you receive a new message?</p>
<p>Nah, you would never split chats and messages into different contexts. But maybe your incautious colleague Joey would? It's always Joey...</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-avoid-react-context-trap/why-joey-why.webp" alt="Joey Tribbiani meme">
<em>Why Joey, why?</em></p>
<p>Let's say Joey didn't mess up this time. You both did the correct choice, keeping chats and messages in the same context, they are related after all. But what about the user context? You do have users on your site, don't you? Should that context be connected to the chat-and-messages context?</p>
<p>You will need to know which users are members of a chat, and you will have to know which chats a user is a member of. Maybe you even add a subsystem for reporting user misbehavior. Should that be stored in its own context?</p>
<p>These are real questions you are likely to face someday and you may have forgotten to plan for it. There are of course good solutions of how to handle these cases, many times it can be solved by handling things differently in backend. Sometimes you have no other choice than handling it in frontend. Either way, <strong>remember that if you choose to split your global store into multiple independent contexts you may get into trouble, that's what I refer to as context trap</strong>.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-avoid-react-context-trap/programmer-joey-tribbiani-meme.webp" alt="Joey Tribbiani programmer meme">
<em>Joey knows how to write code</em></p>
<h2>What Is the Problem?</h2>
<p>The context trap isn't something you easily can solve by moving or adding a few lines of code. Accessing contexts within another context isn't a very great idea, so you will likely have to handle all cross-context logic outside the contexts.</p>
<p>By cross-context logic I mean the logic required to ensure that two or more contexts stay in sync with each other, e.g., updating messages count in a chat context when a new message has been added to a context for messages.</p>
<p>Syncing contexts will include reading and dispatching actions to all affected contexts at the right time in the correct order. Writing such logic is like building a trap for all newly hired employees to fall in, not just Joey. It may be easy to write in the first place, but scaling and maintaining it is a hell.</p>
<p>When you have multiple contexts you need to update whenever an event emits, such as receiving a new chat message, you will have to know how the complete code works in order to know when and where you should update your contexts.</p>
<p>Newly employed developers are often unaware of all the contexts that need to receive updates, so they will most likely introduce a bug. They might notice the bug and try to solve it. What happens then is that most developers blindly try to fix that single bug instead of trying to grasp how the complete solution works and suddenly something else has broken.</p>
<p>Development goes on and after a year it isn't an issue for new employees only, even you get a headache looking at the code. You end up with a code base that is just about a year old and you have already added a task in you backlog to refactor it.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-avoid-react-context-trap/joey-tribbiani-is-that-in-production-meme.webp" alt="Joey Tribbiani meme - is that in production">
<em>Yes Joey, that's what git push master means</em></p>
<h2>Contexts Is Not Always the Solution</h2>
<p>So, how to avoid falling into this trap? Well, one alternative is to follow <a href="https://farcry.fandom.com/wiki/Juan_Cortez">Juan Cortez's rule number 9</a>, to always use the right tool for the job.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-avoid-react-context-trap/juan-cortez-right-tool-for-the-job.webp" alt="Juan Cortez far cry right tool for the right job">
<em>Rule no. 3 is unfortunately often true as well</em></p>
<p>Contexts aren't the solution to all issues. It shouldn't be considered as a "lightweight" Redux. Context and Redux is <a href="https://blog.isquaredsoftware.com/2021/01/context-redux-differences/">not interchangeable</a>. They have different use cases. Redux is a full state management system and in complex applications you may be better off using that.</p>
<h2>How Can Redux Save Us From the Context Trap?</h2>
<p>How could Redux help us out here? You still have to make a lot of design choices; you can't escape that. The benefit arises when you are writing your code. When using contexts, you are free to do any mistake you want (or don't want) to do.</p>
<p>Moreover, when multiple developers work on a project, many of them will find it hard to read code written by other teammates, especially when the code isn't implemented with readability in mind. Redux solves both these problems for us and many more problems we need to handle ourself when using a context. Here's a few examples coming up on my mind at the moment.</p>
<ol>
<li>With Redux you are less likely to do mistakes in your code since you are basing your code on guidelines and well documented code.</li>
<li>You don't need to write all that code Redux handles for you. Redux has been developed for a long time and has been tested well. Writing you own code in replacement of Redux will most likely introduce more bugs in your code.</li>
<li>With Redux, dispatched actions are by default passed to each reducer. There's no need to manually dispatch actions to all affected contexts or removing such logic whenever a context doesn't need that information anymore.</li>
<li>Redux reducers can access the complete store. If you replace that with a multiple-context solution you will need to handle that in some other way. If you are using a useReducer in a context in replacement of Redux you will have access to that context only, not any of the other contexts.</li>
<li>Developers know how Redux works. They can quickly find all the places in the code where a specific action is dispatched, or vice versa, all the reducers that are affected by an action. You don't necessarily get that when you design your own solution. Joey may already know Redux, but he will definitely find a way messing up your custom-made code.</li>
</ol>
<h2>Conclusion</h2>
<p>When you consume a context using useContext hook, your component will rerender any time that context updates. So even if your component merely grabs a user's name from the context, it will still rerender as soon as any change at all is made to the context. When designing React contexts, you should therefore use many small contexts rather than one massive one to <a href="https://javascript.plainenglish.io/react-context-why-am-i-getting-unnecessary-re-renders-b61836d224a7">avoid unnecessary rerenders</a>.</p>
<p>Breaking your contexts into smaller parts may however lead to complex code when your application grows. It's not for certain, but making the wrong design choices can put you into some real trouble. That's what I refer to as the <em>context trap</em>, splitting contexts into smaller pieces and ending up with code that is hard to read and maintain.</p>
<p>Suggested solution from my side is to use Redux. You don't always need Redux, but if you start to think about using multiple contexts or if you want to put a reducer in a context, you should probably consider using Redux.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Architecture</category>
            <category>Frontend</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/how-to-avoid-react-context-trap/joey-tribbiani-is-that-in-production-meme.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[How To Make a Hero Image in Next.js 13 and 14]]></title>
            <link>https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs-13-and-14</link>
            <guid>https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs-13-and-14</guid>
            <pubDate>Sun, 12 Nov 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[How to choose and implement a hero image in Next.js 13 or 14 with the new image component. ✓ Next.js 13 ✓ Next.js 14 ✓ Hero Image ✓ App Router]]></description>
            <content:encoded><![CDATA[<p>I have noticed that one of my previously very popular article about <a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs">how to make a hero image in Next.js</a> is still getting a lot of attention.</p>
<p>Unfortunately, that article was written when Next.js still used the Page Router. After that, with their new App Router in Next.js 13, the image component was replaced with a new one. With that in mind, I have now created a new article optimized for the new Image component in Next.js 13 and 14, for all of you who have, or want to, migrate to use the Image component.</p>
<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs-13-and-14#nextjs-13-image-component">Next.js 13+ Image Component</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs-13-and-14#changes-in-nextjs-13-image-component">Changes in Next.js 13+ Image Component</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs-13-and-14#how-to-create-a-hero-image-with-nextjs-13">How To Create a Hero Image With Next.js 13+</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs-13-and-14#solution-explained">Solution Explained</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs-13-and-14#choosing-a-hero-image">Choosing a Hero Image</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs-13-and-14#summary">Summary</a></li>
</ol>
<h2>Next.js 13+ Image Component</h2>
<p>The new image component which you can use in Next.js 13 and 14 has changed slightly from the legacy image component used in earlier versions. Both the legacy and the new one offer similar advantages, which makes it very beneficial to use instead of the regular image HTML element. Both of the components can help you with:</p>
<ul>
<li>Resizing images for you so <a href="https://nextjs.org/docs/app/api-reference/components/image#sizes">you don't need to use srcset manually</a></li>
<li>Automatically lazy loads images when they are scrolled into view, which of course is <a href="https://nextjs.org/docs/app/api-reference/components/image#priority">optional</a></li>
<li>Gives you various optimization option, such as <a href="https://nextjs.org/docs/app/api-reference/components/image#quality">quality</a>, <a href="https://nextjs.org/docs/app/api-reference/components/image#priority">priority</a> and custom <a href="https://nextjs.org/docs/app/api-reference/components/image#sizes">image sizes</a></li>
<li>Supports adding a placeholder to <a href="https://nextjs.org/docs/app/api-reference/components/image#blurdataurl">blur images</a> when they are loading</li>
</ul>
<p>For the blurring, you can check my <a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs">old article</a> if you wonder more about how it works.</p>
<p><img src="https://www.perssondennis.com/images/articles/what-if-movie-characters-had-linkedin-profiles/batman-linkedin-profile.webp" alt="Batman hero image">
<em><a href="https://www.perssondennis.com/articles/what-if-movie-characters-had-linkedin-profiles">Batman</a> would make a great hero image</em></p>
<h2>Changes in Next.js 13+ Image Component</h2>
<p>Next.js offers a <a href="https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration#image-component">migration codemod scripts</a> for migrating to the new image components. The codemods are not bullet-proof, so you should check <a href="https://nextjs.org/docs/pages/api-reference/components/image-legacy#comparison">what has changed</a> in the new image component if you are planning to migrate.</p>
<p>Some of the changes have affected how a hero image can be implemented. Mainly, they have replaced <em>layout</em> property, removed the objectFit prop and removed the absolute positioned <em>span</em> element which was wrapping the <em>img</em> element in the legacy image component.</p>
<h2>How To Create a Hero Image With Next.js 13+</h2>
<p>The principe of how to implement a hero image is quite simple with the new Image component. I would recommend the following setup.</p>
<ol>
<li>Start with a wrapper div with relative <em>position</em>, 100vw <em>width</em> and your desired height</li>
<li>Insert the Next.js image component with <em>fill</em> and <em>priority</em> props set to true, and a class style with a <em>z-index</em> of -1</li>
<li>Place whatever content you want after the image wrapper, but within the outer wrapper div</li>
</ol>
<p><strong>Note</strong>: You can optionally wrap the image in a wrapper div if you cannot set a style directly on your image component for some reason. In that case, the wrapper must set the CSS attribute <em>position</em> to "absolute" value.</p>
<p>Following the steps above would give you a component looking something like below. The implementation is using css modules. You can also find the code at <a href="https://codesandbox.io/p/sandbox/nextjs-13-hero-image-example-xl65cq?file=%2Fapp%2FHeroImage.tsx%3A10%2C34">CodeSandbox</a> and <a href="https://github.com/PerssonDennis/examples/blob/main/nextjs-13-and-14-hero-image/app/HeroImage.tsx">GitHub</a>.</p>
<pre><code class="language-javascript">// HeroImage.jsx

import Image from "next/image";
import styles from "./heroImage.module.css";

const { heroContent, heroImage, heroWrapper } = styles;

const IMAGE_URL = "https://www.perssondennis.com/images/perfect-avocado.webp";

const HeroImage = () => {
  return (
    &#x3C;div className={heroWrapper}>
      &#x3C;Image
        className={heroImage}
        priority
        src={IMAGE_URL}
        fill
        alt="hero image example"
      />

      &#x3C;div className={heroContent}>
        &#x3C;h1>Hero Image&#x3C;/h1>
        &#x3C;p>Next.js 13 hero image example.&#x3C;/p>
      &#x3C;/div>
    &#x3C;/div>
  );
};

export default HeroImage;

</code></pre>
<pre><code class="language-css">/* heroImage.module.css */

.heroWrapper {
  position: relative;
  width: 100vw;
  height: 50vh;
}

.heroImage {
  object-fit: cover;
  object-position: center;
  z-index: -1;
}

.heroContent {
  display: flex;
  flex-direction: column;
  align-items: center;
}
</code></pre>
<p>Note that I did also set the <em>objectFit</em> property to "cover". You decide how you want you image to scale by choosing a suitable value for <em>objectFit</em> attribute.</p>
<ul>
<li><em>contain</em> value for objectFit will keep the aspect ratio, which may not be desired for a hero image</li>
<li>the <em>cover</em> value will fill up the available area in the parent element by cropping the image where it is necessary</li>
<li><em>fill</em> option will stretch the image to fill up the parent element</li>
</ul>
<p>When you crop the image by using "cover" as a value, you may want to set <em>objectPosition</em> to make sure you keep the parts of the image you want from being cropped out.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-make-a-hero-image-in-nextjs/nextjs-hero-image-example.webp" alt="Next.js 13 and 14 hero image example">
<em>Above example could look something like this</em></p>
<h2>Solution Explained</h2>
<p>CSS is not always that intuitive, so I'll go through what we did there.</p>
<p>The wrapper div around everything had a relative <em>position</em>, what that does, is to tell that absolute positioned images within that element should be positioned relative to it. Absolute positioned elements are relative to the first parent which is explicitly positioned.</p>
<p>The image component Next.js provides does use an absolute position when we use the <em>fill</em> prop for the image component, so the relative position of the wrapper ensures that the image will grow to fill the wrapper and not the whole viewport.</p>
<p>We also added a negative <em>z-index</em> to the image. That is to ensure that the image will be placed under any other content rendered on the same area as the hero image, which means, all the other content we want to display on top of the hero image.</p>
<p>To the image component, we did pass a priority property. This is to disable lazy loading for hero image, since a hero image should always load as quick as possible.</p>
<p>Rest of code should be self explanatory. If it isn't, let me know about your questions.</p>
<h2>Choosing a Hero Image</h2>
<p>If you don't have a hero image and don't want to buy one, there's a lot of free ways to get them. You can find links to some royalty free image sources in my <a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#9-royalty-free-images-graphics-and-videos">list of useful image tools</a>.</p>
<p>That article also lists a lot of useful resources to edit images, both an online Photoshop application and tools for editing, generating and converting images to other format.</p>
<p>Speaking of generating an image. You are probably aware of AIs which can generate images for you. While DALL-E may be the most known one, I prefer <a href="https://app.leonardo.ai/">Leonardo.Ai</a> du to its high quality and realistic images which suits very well for hero images.</p>
<p>Whatever image you choose, make sure to reduce the size of it to a couple of 100 kB or preferably less, dependent on how high resolution and what detail level you need for your image. You can read about the impact of image size and how to optimize an image in my article about <a href="https://www.perssondennis.com/articles/how-i-improved-lighthouse-performance-by-adding-an-image">how I improved Lighthouse Performance by adding a hero image</a>.</p>
<h2>Summary</h2>
<ul>
<li>Next.js 13 comes with a new image component which is fairly similar to the old one</li>
<li>Just as the old image component, it offers image optimizations, lazy loading and blurred placeholders</li>
<li>The new image component can easily be used as a hero image, but remember to use relative position for the parent element</li>
<li>Use z-index to control that the hero image stays below other content in the hero area</li>
</ul>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Next.js</category>
            <category>UI</category>
            <enclosure url="https://www.perssondennis.com/images/articles/how-to-make-a-hero-image-in-nextjs-13-and-14/how-to-make-a-hero-image-in-nextjs-13-and-14.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[How To Make a Hero Image in Next.js]]></title>
            <link>https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs</link>
            <guid>https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs</guid>
            <pubDate>Sun, 24 Jul 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[You may think Next.js image component doesn't work when an image can't fill its parent div. This shows how to solve that and how to add a hero image in Next.js.]]></description>
            <content:encoded><![CDATA[<p>You may have made a hero image a few times before, but have you done one in Next.js? If you haven't done that, you may find it tricky if you would try. Here I'll guide you how to do that and warn you about the gotchas.</p>
<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs#nextjs-image-component">Next.js Image Component</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs#failed-attempts-to-create-a-hero-image-with-nextjs">Failed Attempts To Create a Hero Image With Next.js</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs#how-to-create-a-hero-image-with-nextjs">How To Create a Hero Image With Next.js</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs#solution-explained">Solution Explained</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-make-a-hero-image-in-nextjs#summary">Summary</a></li>
</ol>
<p><img src="https://www.perssondennis.com/images/articles/how-to-make-a-hero-image-in-nextjs/thor-impressed-by-hulk-hero-banner.webp" alt="Thor impressed by Hulk hero Banner meme">
<em>Bruce yourself, Hulk is coming</em></p>
<h2>Next.js Image Component</h2>
<p>Next.js provides a really powerful <a href="https://nextjs.org/docs/api-reference/next/image">Image component</a> which you definitely should use if you don't have a reason not to. It handles several things for you, some which are enabled by default and some which you have to specify yourself. Some examples of what the Image component can do are:</p>
<ul>
<li>Automatically resize images for you. No need to manually generate images of different sizes to use in a picture element with a srcset. It supports <a href="https://nextjs.org/docs/api-reference/next/image#layout">several type of layouts</a>. Unfortunately, it isn't very easy to understand from the documentation when to use which layout.</li>
<li>Lazy load images. Images are fetched firstly when they are closed to being scrolled into view. If you need to opt out of this behavior, you can specify the <a href="https://nextjs.org/docs/api-reference/next/image#priority">prioritize property</a>.</li>
<li>It lets you <a href="https://nextjs.org/docs/api-reference/next/image#sizes">optimize</a> image <a href="https://nextjs.org/docs/api-reference/next/image#image-sizes">sizes</a> and <a href="https://nextjs.org/docs/api-reference/next/image#quality">quality</a> in different ways.</li>
<li>Allows you to <a href="https://nextjs.org/docs/api-reference/next/image#placeholder">blur images</a> by providing a temporary blur-image. If you want a single-colored blurred background, you can generate a base64 encoded one on <a href="https://png-pixel.com/">png-pixel</a>.</li>
</ul>
<pre><code class="language-javascript">&#x3C;Image
    blurDataURL="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mPkso6pBwACGgEie2Im0gAAAABJRU5ErkJggg=="
    placeholder="blur"s
    src={memeUrl}
    layout="fill"
    alt="Programming meme"
/>
</code></pre>
<p><em>Pass a base64 image to blurDataURL to use it as a blur placeholder</em></p>
<p>To see blurred images in action, head over to the <a href="https://www.perssondennis.com/memes">memes page at my website</a> and scroll down. Next.js handles the blurring and lazy loading automatically.</p>
<h2>Failed Attempts To Create a Hero Image With Next.js</h2>
<p>Trying to create a hero image with Next.js can be a troublesome process. As I mentioned above, you should use Next.js built-in Image component if you don't have a reason not to.</p>
<p>In a first attempt to create a hero image, you may think you can set the width of the Image component to 100%. Unfortunately, that is not possible with remote images, Next.js don't support that. You'll end up with a 100px wide image instead.</p>
<p>A second try could be to avoid specifying width for the Image component in hope for that it would fill the parent element. Doing that will result in an Unhandled Runtime Error.</p>
<pre><code class="language-markdown">"Error: Image with src SOURCE must use "width" and "height" properties or "layout='fill'" property."
</code></pre>
<p><img src="https://www.perssondennis.com/images/articles/how-to-make-a-hero-image-in-nextjs/nextjs-image-with-src-source-must-use-width-and-height-properties.webp" alt="Image with src SOURCE must use &#x22;width&#x22; and &#x22;height&#x22; properties error">
<em>Next.js Image component requires a width and height, or a fill layout</em></p>
<p>The error Next.js outputs is quite clear. You are required to set both a width and a height on the Image component, unless you provide the <em>fill</em> value to the layout property. You do exactly what Next.js suggests since you are a law-abiding citizen, or maybe because you have no better ideas to try.</p>
<p>Using the layout property removes the error, but your hero image now fills the whole viewport instead of the div that wraps it. Perfect... You start realizing that you will be late to grandma's dinner party tonight.</p>
<p>Being pretty great at hacking CSS, you play around with the element inspector in the browser a bit. You don't really get anywhere and neither Stack Overflow or Next.js documentation is to any help, and you don't find a tutorial for it. Maybe it's best to use a native image element rather than the Image component Next.js provides?</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-make-a-hero-image-in-nextjs/grandma-dinner-party-meme.webp" alt="Grandma-invites-rabbit-meme">
<em>An apology to all vegans, there will be no food for you. And for the sharp joke, I know it isn't bunny...</em></p>
<h2>How To Create a Hero Image With Next.js</h2>
<p>I'm happy to announce that there is an easy way to fix it. The key to success is to use <em>position: relative</em> on a parent element. I would suggest to do four things.</p>
<ol>
<li>Add a hero wrapper element with <em>position: relative</em> and an appropriate <em>width</em> and <em>height</em>.</li>
<li>Add a Next.js Image component with the <em>layout</em> property set to <em>fill</em>.</li>
<li>Wrap the Image component in a div with <em>z-index: -1</em>.</li>
<li>Add whatever hero content you want in a relative positioned div in the hero wrapper. Place your hero content in that div.</li>
</ol>
<p>The complete solution would look like this.</p>
<pre><code class="language-javascript">// Header component.
import Image from "next/image";
import styles from "../header.module.css";

const { heroContent, heroWrapper, imageWrapper } = styles;

const IMAGE_URL =
  "https://www.perssondennis.com/images/articles/how-to-make-a-hero-image-in-nextjs/perfect-avocado.webp";

export default () => {
  return (
    &#x3C;div className={heroWrapper}>
      &#x3C;div className={imageWrapper}>
        &#x3C;Image
          priority
          src={IMAGE_URL}
          layout="fill"
          objectFit="cover"
          objectPosition="center"
          alt="hero image example"
        />
      &#x3C;/div>

      &#x3C;div className={heroContent}>
        &#x3C;h1>Hero Image&#x3C;/h1>
        &#x3C;p>Next.js hero image example.&#x3C;/p>
      &#x3C;/div>
    &#x3C;/div>
  );
};

</code></pre>
<pre><code class="language-css">/* header.module.css */

/* step 1 */
.heroWrapper {
  position: relative;
  width: 100vw;
  height: 50vh;
}

/* step 3 */
.imageWrapper {
  z-index: -1;
}

/* step 4 */
.heroContent {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}
</code></pre>
<p><img src="https://www.perssondennis.com/images/articles/how-to-make-a-hero-image-in-nextjs/nextjs-hero-image-example.webp" alt="Next.js hero image example">
<em>This is what it would look like using the hero image on a page</em></p>
<h2>Solution Explained</h2>
<p>So, what did we do there? In step <em>1.</em> we added a relative position to the hero wrapper. That's the secret to success in this case. Next.js will set an <em>absolute</em> position on its image when you set the <em>layout</em> property to <em>fill</em> in step <em>2.</em>.</p>
<pre><code class="language-css">/* step 1 */
.heroWrapper {
  position: relative;
  width: 100vw;
  height: 50vh;
}
</code></pre>
<pre><code class="language-javascript">&#x3C;div className="{imageWrapper}">
  &#x3C;image
    priority
    src="{IMAGE_URL}"
    layout="fill"
    objectFit="cover"
    objectPosition="center"
    alt="hero image example"
  />
&#x3C;/div>
</code></pre>
<p>In CSS, absolute positioned elements are absolute relative to their <a href="https://www.w3schools.com/cssref/pr_class_position.asp">closest parent that is explicitly positioned</a>. By setting the hero wrapper's position to relative, the absolute positioned image within it will grow to be just as large as the hero wrapper becomes.</p>
<p>The hero wrapper will in turn be as large as the content you add to it in step <em>4.</em>. Note that the hero image's width and height does not contribute to the hero wrapper's width and height since the image has an absolute position.</p>
<p>If you would remove the relative position from the hero wrapper, you would see that the image instead grows to be as large as the viewport, because no parent or grandparent has a position specified.</p>
<p>In step <em>3.</em>, we wrapped the hero image in a div (<em>imageWrapper</em>) with z-index set to <em>-1</em>, and in step 4 we added a relative positioned div (<em>heroContent</em>) as a sibling to the image wrapper. That is just to ensure that other components will show on top of the hero image.</p>
<pre><code class="language-css">/* step 3 */
.imageWrapper {
  z-index: -1;
}

/* step 4 */
.heroContent {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}
</code></pre>
<p>We do now have what we need to implement a hero image with the Next.js Image component. You can fill it with whatever content you want, personally I prefer centered content, which is most easily done with flex column and a centered <em>align-items</em> property!</p>
<h2>Summary</h2>
<ul>
<li>Always use Next.js Image component if you don't have a reason not to do it.</li>
<li>If you want to create a hero image with Next.js image component, wrap the hero image and its content in a <em>relative</em> positioned div and set the image's <em>layout</em> property to <em>fill</em>.</li>
<li>Wrap the hero image in a div with a <em>z-index</em> of <em>-1</em> to make it show underneath the content in the hero section.</li>
<li>Create a div below the image wrapper and let it have a <em>relative</em> position.</li>
</ul>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Next.js</category>
            <category>Performance</category>
            <category>UI</category>
            <enclosure url="https://www.perssondennis.com/images/articles/how-to-make-a-hero-image-in-nextjs/how-to-make-a-hero-image-in-nextjs.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[How To Report a Site That Steals Your Articles]]></title>
            <link>https://www.perssondennis.com/articles/how-to-report-a-site-that-steals-your-articles</link>
            <guid>https://www.perssondennis.com/articles/how-to-report-a-site-that-steals-your-articles</guid>
            <pubDate>Sun, 05 Jun 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[When you find a stolen article it's important to know how to report a site that have stolen your article. You should always report it to Google.]]></description>
            <content:encoded><![CDATA[<p>A short time back, I googled to find one of my own blog articles. I do that quite often since it's an easy way for me to find my articles quickly. But this time I noticed that the search result that appeared right after my article had the exact same title as mine.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/google-search-result-dev.webp" alt="Google search result of my stolen article">
<em>The site appears right below my DEV article on google</em></p>
<p>I got curious and visited the page and was met by an exact copy of <a href="https://dev.to/perssondennis/how-to-avoid-react-context-trap-1705">my own blog article</a>, the only difference was that they had systematically substituted single words with synonyms all over the text, as a bad attempt to make the article look unique to Google.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/my-stolen-article.webp" alt="My stolen article">
<em>The beginning of the article they have stolen from me</em></p>
<p>I further inspected the website a bit to see what was going on. While doing that I <a href="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/stolen-article-laravel.webp">found</a> <a href="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/stolen-articles-examples.webp">loads</a> <a href="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/stolen-article-use-python.webp">of</a> <a href="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/stolen-article-accordion.webp">articles</a> <a href="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/my-stolen-article-joey.webp">published</a> <a href="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/stolen-article-adhd.webp">on</a> DEV, and there was no information about the source of the articles. The canonical link referred to the site itself instead of the original publisher.</p>
<p>Has your article been stolen as well? I don't know, but I can see they copy plenty of articles daily and I do know why you should care about it. I'll guide you what to do if this happens to you. I'll explain why you should care and I will tell you why it's important.</p>
<hr>
<p>I have decided not to expose the name of the website that steals your DEV articles, I don't intend to slander anyone. If DEV are interested to know more and take action, they can contact me privately.</p>
<h2>Why Should You Report a Stolen Blog Post?</h2>
<p>The obvious reason to report a stolen blog article is because it steals traffic from your own website. If the site has better SEO than yours it will appear before your own site on Google and most organic traffic will go to that site instead of your own blog. As a result, people won't read your articles and you are writing them completely in vain. It can even get worse than that. If Google detects that your blog contains content that are duplicated on another site, it can hurt how you rank on Google.</p>
<p>If you don't care about if people are reading your blog posts or not, you should still take action against a stolen article. Your action can prevent the site from stealing articles from others who do care about it.</p>
<h2>How To Report a Stolen Site?</h2>
<p>If you google how to report a stolen site, one of the first suggestions is to contact the owner of the website who has stolen it and ask if they can remove it. That's a perfect example of what you should <strong>not</strong> do. Why? To begin with, it may not be very effective. If you even get an answer from the owner of the site, you have no guarantee they will remove it.</p>
<p>Furthermore, if they would remove your article, you have helped nobody but yourself, and not by very much. After removing the article, they can simply republish it again, or stealing the very next article you write. And no one except you or the website owner will know about the copyright infringement, and they can carelessly continue to steal articles from other people.</p>
<hr>
<p>If you think there's a chance that the website has copied your article by mistake or with a good intention. Make sure to contact them directly so they can remove the article without being discredited in any way.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/stolen-signature.webp" alt="Stolen signature">
<em>The ending of my stolen article, they have even copied my name</em></p>
<h2>A Better Approach To Report a Stolen Blog Post</h2>
<p>Well, last approach wasn't very effective. What to do instead? You can always try to find who's hosting the website and contact them. Sites like <a href="https://who.is/">whois</a> can tell you who is hosting the site.</p>
<p>This is a fair thing to do. Some hosting providers will take down sites that abuse like this. By doing this, you make it a bit harder for the site owner to continue their light-fingered business.</p>
<h2>Going to Google</h2>
<p>Another approach to report a page with stolen content is to ask Google to remove it. You can easily report it to google by reporting an <a href="https://support.google.com/legal/troubleshooter/1114905">intellectual property issue here</a>.</p>
<p>Important to mention is that Google can't remove the site from the internet, your stolen blog post will still be accessible by its link and for people who use another search engine than Google. If it's important that even the website itself gets removed, you should additionally try some of the previously mentioned approaches.</p>
<p>The benefit of reporting it to Google is that they can remove the article from appearing in search results and potentially even degrade Google's rating of the website. In this way, you are not only helping yourself, you are also making Google aware of the website's shady business so they can prevent this from happening to other people.</p>
<h2>Let's Go to the Court</h2>
<p>If nothing else helps, you can always make a lawsuit of it. You don't actually need any more information about this approach. It depends on which country you live in, but if the cops actually care, it will likely be a troublesome and expensive process that probably only works if your brand is well-known.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/stolen-article-cop-meme.webp" alt="Stolen article cop meme">
<em>Poor wife of Rob will never understand why he never came to rescue her</em></p>
<h2>Let the World Know</h2>
<p>The last approach of how to report a stolen article I will present today, is to let the world know about it. This may be a bad idea if they only have stolen something from you personally. Chances are that you will just give them attention in form of publicity, backlinks, site visits etc.</p>
<p>Reading this article, you may realize this is kind of what I have done. I make people aware of what is happening. I'm not interested in denigrating anyone, rather I want to enlighten the problem and assist with a suggested solution, turning setbacks into knowledge. For that reason, I don't mention the name of the site on topic, because I wouldn't recommend trying to defame anyone.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/stolen-article-mum-or-dad.webp" alt="Parent equal to mum or dad">
<em>mum or dad::boot()... Who thought it was a good idea to replace words in the code?</em></p>
<h2>Conclusion</h2>
<p>There are multiple ways to report a website that has stolen your blog article. What's probably most important is to get it removed from appearing in Google searches, otherwise it will compete with your site's SEO directly. In other cases, it may be important to get the article removed from the website that stole it.</p>
<p>By reporting a stolen blog articles correctly, you can help preventing the website from continuing stealing articles from others. Personally, I would suggest the following approach.</p>
<ul>
<li>If you think the website may have published your article by mistake or with a good intention, contact them to sort out any misunderstandings without taking any further steps. It's not fair to punish them for an innocent mistake.</li>
<li>If it's obvious that they consciously have stolen your article for their own benefits, don't get in touch with them. Contacting them may help you get the article removed, but they can carelessly continue to steal articles from other people.</li>
<li><a href="https://support.google.com/legal/troubleshooter/1114905">Report the stolen article to Google</a>. Google can stop displaying the stolen article in search results on google.com, and they can potentially also decide to stop indexing that website completely if they receive reports from many people.</li>
<li>Contact the hosting provider of the website and let them know about your case. Copyright infringement may be a violation of their terms of use, which gives them the rights to disrupt the hosting of the website.</li>
</ul>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Productivity</category>
            <enclosure url="https://www.perssondennis.com/images/articles/how-to-report-a-site-that-steals-your-articles/report-a-site-that-steals-articles.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[How To Use MVVM in React Using Hooks and TypeScript]]></title>
            <link>https://www.perssondennis.com/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript</link>
            <guid>https://www.perssondennis.com/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript</guid>
            <pubDate>Sun, 16 Apr 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[React example of how to use MVVM architecture to build a React or React Native application with hooks and TypeScript. ✓ React ✓ MVVM ✓ Hooks ✓ TypesScript ✓ FAQ]]></description>
            <content:encoded><![CDATA[<p>Software applications often start out simple and quickly grows big. No matter how small one try to keep it, the code somehow always grows up to be a full-fledged application. In many languages, we follow structural patterns as MVVM and Clean Architecture, which is less common to see in the Wild West Web.</p>
<p>In this article, we will take a look at how a React application can be designed to follow the MVVM architectural design pattern to create a React application that is both scalable and maintainable. We will use TypeScript and functional React components and write custom hooks for the ViewModel and Model. The same code will of course work with React Native with some minor modifications.</p>
<p>If you have some questions while reading the article you have an extensive FAQ at the end of the article.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript#mvvm-overview">MVVM Overview</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript#application-overview">Application Overview</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript#view-implementation">View Implementation</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript#viewmodel-implementation">ViewModel Implementation</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript#model-implementation">Model Implementation</a></li>
<li><a href="https://www.perssondennis.com/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript#faq">FAQ</a></li>
</ul>
<h2>MVVM Overview</h2>
<p>If you don't know what MVVM is, you can either google it or read along anyway. You should be able to follow along in the article either way. In short, MVVM is a design pattern that provides a clear separation of concerns, making it easier to develop, test, and maintain software applications.</p>
<p>What MVVM does is to separate an application into Views, ViewModels and Models. Where the Views are responsible for presenting data to the user and capturing user input, the ViewModels act as a mediator between the Views and the Models, and the Models manage the application data.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript/architect-developer-meme.webp" alt="Architecture meme">
<em>Some people say architecture matters</em></p>
<h2>Application Overview</h2>
<p>The app we will build in this article is the tiny one you can see down here. It's kept small so we can focus on the MVVM architecture. The app consists of a single View listing articles, with an input field for adding a new article with a given name.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript/react-mvvm-example-app.webp" alt="React MVVM example app">
<em>The app to be built, a single View to keep it simple</em></p>
<p>Codewise, the application consists of one React component for the articles View, then a few hooks for the ViewController, ViewModel and Model. Below is a architectural diagram of the code we will go through. Disregard the ViewController for now, which isn't an official part of MVVM, we will discuss that one later.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript/react-mvvm-app-overview.webp" alt="React MVVM app overview">
<em>Overview of the React components for the application in this article</em></p>
<p>A single View is of course not enough for a useful application. If the example would be larger, each View would have its own ViewController, as depicted in the diagram below. All ViewControllers that work against the same Model would use a common ViewModel.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript/react-mvvm-app-overview-extended.webp" alt="React MVVM app extended overview">
<em>What the application would look like with more views</em></p>
<p>When the application grows even more it can include more Models and ViewModels. I think you get that. Anyhow, let us start looking at the implementation for the app.</p>
<h2>View Implementation</h2>
<p>A View in the application can be any screen or visual component on the screen. If the site to be built is a blog platform, we could have screens for listing articles, viewing a single article, and for writing a new article. Those screens could be implemented with in Views like ArticlesView, ArticleView and CreateArticleView</p>
<p>The View is responsible for displaying the UI and trigger actions based on user interactions. Although there traditionally isn't a ViewController in MVVM, this MVVM guide has split the View part of MVVM into two parts, a View and a ViewController, where the only responsibility of the View component is to render the UI while the ViewController handles all the logic for the View.</p>
<h3>View Component</h3>
<p>As we saw before, the View will will look something like this with some CSS.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript/react-mvvm-example-app.webp" alt="ArticlesView component">
<em>ArticlesView component</em></p>
<p>To implement the View, we use a regular functional React component that renders a UI. To avoid handling view logic in the View component, we use a ViewController which exports functions for all possible user actions.</p>
<pre><code class="language-typescript">// view/article/articles-view/ArticlesView.tsx

import React from 'react'
import useArticlesViewController from 'view/article/articles-view/useArticlesViewController'

const ArticlesView: React.FC = () => {
  const {
    articleName,
    articles,
    navigateToArticle,
    onArticleNameChange,
    onCreateArticleClick,
  } = useArticlesViewController()

  return (
    &#x3C;div>
      {!!articles &#x26;&#x26;
        articles.map(({ id, title }) => (
          &#x3C;div key={id} onClick={() => navigateToArticle(id)}>
            {title}
          &#x3C;/div>
        ))}
      &#x3C;div>
        &#x3C;input
          type="text"
          onChange={onArticleNameChange}
          value={articleName}
          placeholder="Add an article..."
        />
        &#x3C;button onClick={onCreateArticleClick}>Create article&#x3C;/button>
      &#x3C;/div>
    &#x3C;/div>
  )
}

export default ArticlesView
</code></pre>
<p>The ArticlesView component above renders a view with articles. When the user interacts with the UI, this View component will simply forwards the action to a function in the useArticlesViewController hook.</p>
<p>Since this file only contains pure UI components and only reacts to user interactions by forwarding them to a hook, it's very trivial to test and read. The unit tests for this component would merely be to test that all articles are rendered and that the functions exported from the useArticlesViewController are called. The useArticlesViewController itself would preferably be mocked since we will test that hook separately.</p>
<p>To test interactions with the view, I would recommend interactional testing frameworks like <a href="https://testing-library.com/docs/react-testing-library/intro/">React Testing Library</a>. You can read more about the benefits and how that compares to code based unit testing in <a href="https://www.perssondennis.com/articles/unit-testing-volvo#how-to-write-good-unit-tests">my other article about unit testing</a></p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript/in-love-with-css-meme.webp" alt="In love with css meme">
<em>I won't bother you with the CSS</em></p>
<h3>ViewController Hook</h3>
<p>The ViewController hook used in the View component handles the view logic for that View. Each View component has its own ViewController hook. There are several types of view logic in the ViewController.</p>
<ul>
<li>View logic that updates the View components internal state (typically useState, useReducer or useRef)</li>
<li>View logic that updates the application's state (e.g. navigating to other screens)</li>
<li>View logic that interacts with the ViewModel</li>
</ul>
<p>In general, the View logic is responsible for managing the user interface and handling user interactions. This includes maintaining the component's internal state as well as handling conditions for interacting with the ViewModel. By keeping all this kind of view logic in the ViewController, we don't need any view logic in the ViewModel.</p>
<pre><code class="language-typescript">// view/article/articles-view/useArticlesViewController.tsx

import { useCallback, useEffect, useState } from 'react'
import { useHistory } from 'react-router-dom'
import { HOME_SCREEN, ROOM_SCREEN } from 'routing/screens'
import useArticleViewModel from 'viewmodel/useArticleViewModel'

const useArticlesViewController = () => {
  const history = useHistory()
  const [articleName, setArticleName] = useState('')
  const { articles, createArticle, getArticles } = useArticleViewModel()

  const onCreateArticleClick = useCallback(async () => {
    await createArticle({ name: articleName })
  }, [createArticle, articleName])

  const navigateToArticle = useCallback((articleId: number) => {
    history.push(`${ROOM_SCREEN}/${articleId}`)
  }, [history])

  useEffect(() => {
    getArticles()
  }, [getArticles])

  return {
    articleName,
    articles,
    navigateToHome,
    navigateToArticle,
    onCreateArticleClick,
    onArticleNameChange: setArticleName
  }
}

export default useArticlesViewController
</code></pre>
<p>useArticlesViewController is a little more complex than its corresponding View component. It contains code for navigation among screens using React Router. It also keeps the internal state of the view, which can be used for both handling internal logical conditions or to be passed back to the View component to be used in rendering.</p>
<p>Lastly, we use a useArticleViewModel hook which is the ViewModel that this View uses. Only the functions required to be used in this View needs to be destructured from that ViewModel.</p>
<p>This file includes more logic to test than the View component. The good thing is that there's no need to test any UI elements at all. You can test the hook purely using <a href="https://react-hooks-testing-library.com/usage/basic-hooks">React Hooks Testing Library</a>, there's no need to use any UI element matchers or to check if data is rendered. Simply invoke the functions returned from the hook and assert the expected outcome.</p>
<h2>ViewModel Implementation</h2>
<p>The ViewModel is responsible for handling the interactions between the View and the Model, serving as a bridge between them. Normally, the View interacts directly with the ViewModel, but as we already have seen, we have split the View into a View component and a ViewController. This means the ViewController is the one which uses the ViewModel.</p>
<p>The ViewModel is, just as the ViewController, implemented as a hook. It doesn't include very much code in our Article example. This is because our application example simply doesn't have any business logic. But if we would have it, we would have put it here.</p>
<pre><code class="language-typescript">// viewmodel/useArticleViewModel.tsx

import useArticleModel from 'model/useArticleModel'

const useArticleViewModel = () => {
  const { article, articles, createArticle, getArticles } = useArticleModel()

  return {
    article,
    articles,
    createArticle,
    getArticles
  }
}

export default useArticleViewModel
</code></pre>
<p>Yeah, that's it. It only wraps the functions in the useArticleModel hook by re-exporting them. If some of those actions would have required any business logic, we would have created a wrapper function to perform the expected calculations within this hook.</p>
<p>What about testing? Well, when looking at this I would argue there's no need to test this file. With more logic, you can use <a href="https://react-hooks-testing-library.com/usage/basic-hooks">React Hooks Testing Library</a> here as well.</p>
<p><img src="https://www.perssondennis.com/images/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript/testing-is-important-meme.webp" alt="Testing is important meme">
<em>I didn't use to think testing is important, but somehow I changed my mind...</em></p>
<h2>Model Implementation</h2>
<p>The model is responsible for getting data from data sources, and serving it to the ViewModel. The ViewModel in turn, uses the Model to fetch and modify the data.</p>
<p>The model can be written in a plenty of ways. Redux, Apollo, hooks like useSWR and so on can all be used. Furthermore, there may not only be a single data source, complex applications can fetch data from several different sources. In that case, it can be a good idea to put a repository in between the ViewModel and the Model. Repositories are not a part of MVVM design pattern and will therefore not be used here.</p>
<p>Because the implementation of the model can vary significantly between projects, this guide will not delve deeply into how to implement it. Instead, we will provide a simple example that makes use of REST API functions for retrieving and posting articles.</p>
<pre><code class="language-typescript">// model/useArticleModel.tsx

import { useCallback, useState } from 'react'
import { getAllArticles, postArticle } from 'model/api/article'
import { ArticleDTO, CreateArticleDTO } from 'model/api/article'

const useArticleModel = () => {
  const [articlesData, setArticlesData] = useState&#x3C;ArticleDTO[] | null>(null)

  const getArticles = useCallback(async () => {
    const articles = await getAllArticles()
    setArticlesData(articles)
  }, [])

  const createArticle = useCallback(async (createData: CreateArticleDTO) => {
    if (Array.isArray(articlesData)) {
      const response = await postArticle(createData)

      if (response !== null) {
        setArticlesData([...articlesData, { id: response.id, name: response.name }])
      }
    }
  }, [articlesData])

  return {
    articles: articlesData,
    createArticle,
    getArticles
  }
}

export default useArticleModel
</code></pre>
<p>As you can see, there's more logic in this one. Still we have kept it brief. The logic is not very smart or robust, but we can see that we have basic functionality for fetching and creating articles. The code should be fairly easily tested in a similar way as the previous hooks.</p>
<h3>REST API</h3>
<p>In the Model example above, we didn't get to see how the REST API functions were implemented. Even though it isn't necessary for the MVVM example, we will still look at some trivial example code for what it can look like.</p>
<p>This code will most likely not look the same in your project, it is simply here to serve an example. Your real code should hopefully be better written than this, typically you would need to handle things like errors, retires, caching and to make the code idempotent.</p>
<pre><code class="language-typescript">// model/api/article.ts

export interface ArticleDTO {
  id: number
  name: string
}

export interface CreateArticleDTO {
  name: string
}

const API_URL = 'https://example.com/api'

export const getAllArticles = async (): Promise&#x3C;ArticleDTO[] | null> => {
  const response = await fetch(`${API_URL}/articles`)
  if (!response.ok) {
    throw new Error('Failed to get all articles')
  }
  const data = await response.json()
  return data
}

export const postArticle = async (createData: CreateArticleDTO): Promise&#x3C;ArticleDTO | null> => {
  const response = await fetch(`${API_URL}/articles`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(createData)
  })
  if (!response.ok) {
    throw new Error('Failed to create article')
  }
  const data = await response.json()
  return data
}
</code></pre>
<h2>FAQ</h2>
<p><strong>Q</strong>: What is a View?</p>
<blockquote>
<p>A View is a substantial part of the UI. It can be the complete viewport or it can be a component within the viewport which should handle its own state and its own data. I don't know in which way you have worked with container and components in React, or smart and dumb components or whatever you call them. But if you think of a component as a dumb component, that is not a View, that's just a part of a View. Buttons, input field and small components are all components, not Views.</p>
</blockquote>
<p><strong>Q</strong>: Why is there a ViewController in the MVVM implementation?</p>
<blockquote>
<p>The ViewController is added as a part of the View to split the user interface implementation from its logic. This allows the View to be tested more easily since the view logic and UI can be tested separately. The downside is that we get more components to test, render and maintain.</p>
</blockquote>
<blockquote>
<p>Another reason to add this extra layer, is to serve as a bridge between the View and the ViewModel. By doing this, we can keep more of the view logic inside the View layer instead of spilling it over to the ViewModel which is shared by multiple Views. There's no need for a ViewModel to know about the internal state's of the View that utilizes it.</p>
</blockquote>
<p><strong>Q</strong>: Do I really need a ViewController for my each View component?</p>
<blockquote>
<p>That depends on what you think of when you say View. Read the question <em>What is a View?</em>. If the component you are writing isn't considered to be a View, you won't need, and neither shouldn't, write a ViewController for it. It is definitely overkill to add a ViewController for a trivial button component. If the component you implement really is a View, I would suggest adding its view logic to a ViewController for testing purpose and for being consistent with how you implement you Views.</p>
</blockquote>
<p><strong>Q</strong>: How to implement MVVM in React without a ViewController?</p>
<blockquote>
<p>If you don't want to split the View into a View and ViewController, simply put all of the view logic in the ViewController into the View component itself. The other option would be to put parts or all of that logic in the ViewModel, but then the ViewModel would contain a lot of view logic that is specific to certain Views, which would make it confusing and quite huge.</p>
</blockquote>
<p><strong>Q</strong>: Why do we use hooks to implement the ViewController?</p>
<blockquote>
<p>The ViewController could be implemented in multiple ways. We could for example implement the View and ViewController as two components, where the ViewController component would be the main component which simply passes props to the View component. That solution would increase the virtual and possible even physical DOM since it would require two components instead of one.</p>
</blockquote>
<p><strong>Q</strong>: Can we implement MVVM in React using old class components?</p>
<blockquote>
<p>Yes, of course. But in this article we use functional components. Class components are old and should not be used anymore.</p>
</blockquote>
<p><strong>Q</strong>: I have seen MVVM being implemented using dependency injection in React.</p>
<blockquote>
<p>Good for you. I have seen class components using that approach, which suits well there. Implementing MVVM in React with functional components comes with other solutions. Hooks are more familiar to React developers than dependency injection patterns. For that reason, this example uses React hooks to implement MVVM.</p>
</blockquote>
<p><strong>Q</strong>: Should my React MVVM application only include a single Model?</p>
<blockquote>
<p>Probably not. You will likely have multiple models in your application. Each model will also come with a ViewModel which utilizes the Model.</p>
</blockquote>
<p><strong>Q</strong>: Should my React MVVM application only include a single ViewModel?</p>
<blockquote>
<p>No. Each Model will have a ViewModel. If you have multiple Models you may also have multiple ViewModels.</p>
</blockquote>
<p><strong>Q</strong>: Should I have one or several ViewController for each ViewModel?</p>
<blockquote>
<p>You should have one ViewController for each View. Several ViewControllers will use the same ViewModel. ViewControllers like useArticleViewController, useArticlesViewController and useCreateArticleViewController will all share the same ArticleViewModel.</p>
</blockquote>
<p><strong>Q</strong>: Can I only use a single ViewModel in a ViewController?</p>
<blockquote>
<p>No, you can use many. The ViewController-ViewModel relation is a many-to-many relation, not a many-to-one relation. A View can use data from multiple models, and will in that case use multiple ViewModels. For example, a useArticleViewController, could utilize both a ArticleViewModel and a AuthorViewModel.</p>
</blockquote>
<p><strong>Q</strong>: Why do you wrap createArticle function in onCreateArticleClick in the ViewController?</p>
<blockquote>
<p>This is done for two reasons. First reason is just for naming conventions, to keep view logic such as clicks handling in the ViewController rather than in the ViewModel. The second reason is because the ViewController has access to the internal state of the View. That makes it possible to update onCreateArticleClick with logic from the view, such as text from input fields.</p>
</blockquote>
<p><strong>Q</strong>: I have a component which doesn't need the Model do I still need use a ViewModel in the ViewController?</p>
<blockquote>
<p>If I would answer yes, what would you write there? It's totally fine and even normal to have components without ViewModels.</p>
</blockquote>
<p><strong>Q</strong>: Do I still need testing libraries like React Test Renderer, Enzyme and React Testing Library?</p>
<blockquote>
<p>Yes and no. You still have UI to test. But the only place you need UI testing libraries like those are in the View files, and those all consists of pure UI elements, which you arguably may not need to test. The hooks for the ViewController, ViewModel and Model can all be tested with React Hooks Testing Library. What so awesome with that? Well, look at <a href="https://react-hooks-testing-library.com/usage/basic-hooks">the tiny documentation</a>! It's all you need honestly.</p>
</blockquote>
<p><strong>Q</strong>: What folder structure would you recommend?</p>
<blockquote>
<p>You can see the folder structure I used in this example by looking at the imports and filenames. In general, I would claim there are several folder structures that works, use whatever approach you (and at least some of your colleagues...) find logical.</p>
</blockquote>
<p><strong>Q</strong>: What if I don't want to use TypeScript?</p>
<blockquote>
<p>Well, that's up to you. Just remove the types. They are only there to help.</p>
</blockquote>
<p><strong>Q</strong>: What if I use React Native?</p>
<blockquote>
<p>You can use the same code for React Native as well with just some minor modifications.</p>
</blockquote>
<p><strong>Q</strong>: How does MVVM help with testing?</p>
<blockquote>
<p>Two things decides how much tests will burden or save you. One thing is the architecture of the code. MVVM will by design make the code easier to test, by separating concerns of each layer in the application.</p>
</blockquote>
<blockquote>
<p>The other thing that helps you is <a href="https://www.perssondennis.com/articles/give-your-dry-tests-a-wet-touch">how you structure your tests</a> and <a href="https://www.perssondennis.com/articles/unit-testing-volvo">what libraries you use to write the tests</a>.</p>
</blockquote>
<p><strong>Q</strong>: Should I use MVVM in React?</p>
<blockquote>
<p>The short answer would be: with the component based architecture and tools like Redux and useSWR we do not have a great need of a MVVM structure in React.</p>
</blockquote>
<blockquote>
<p>With that being said, lots of backend developers asks about how to implement MVVM with React. The benefit I see with MVVM is particularly with testing. Testing is many times half of the development time, and for new developers it can be a lot more than that.</p>
</blockquote>
<blockquote>
<p>The issue with testing components with a lot of mixed logic is that it requires lots of different mocks and assertions for a single component. What happens is usually that developers searches through the code in hope of finding similar mocks they can reuse.</p>
</blockquote>
<blockquote>
<p>By using the MVVM setup I have described in this article, testing is a piece of cake. Each file will have just a few kind of tests that needs to be written. To learn how to test the code, developers will only have to look how it's done in an adjacent file and can quickly write the tests for all code they develop.</p>
</blockquote>
<blockquote>
<p>In the end, it's just a matter of taste. MVVM is not the mainstream React way, but with this article I wanted to show a way for how to do it.</p>
</blockquote>
<p><img src="https://www.perssondennis.com/images/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript/the-one-guy-meme.webp" alt="The one guy meme">
<em>If you aren't satisfied with the FAQ, I know a guy you can ask</em></p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Architecture</category>
            <category>Frontend</category>
            <category>Hooks</category>
            <category>JavaScript</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript/how-to-use-mvvm-in-react-using-hooks-and-typescript.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[I Hired an AI as a Developer - This Is What Happened]]></title>
            <link>https://www.perssondennis.com/articles/i-hired-an-ai-as-a-developer-this-is-what-happened</link>
            <guid>https://www.perssondennis.com/articles/i-hired-an-ai-as-a-developer-this-is-what-happened</guid>
            <pubDate>Sun, 10 Sep 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Will AI take programmers job? I asked that question myself and decided to try hiring ChatGPT to see how well it could handle a customer project. ✓ AI ✓ ChatGPT]]></description>
            <content:encoded><![CDATA[<p>There have been many discussions around whether AI is threatening developer's jobs. Some say they are very close to take our jobs, other claims it will not happen, with the motivation that AIs will only be used as a tool for developers.</p>
<p>Whatever is true, I have tested an AI to see how easy an AI can pass a hiring process and how it well it can perform developing a product after meeting with a customer.</p>
<p>The AI I used for this, is our most well-known ChatGPT. Even though there are AIs out there more focused on code generation, I chose to use ChatGPT since it can be used in multiple steps in the development process from an idea to the deployment of a service.</p>
<p>Throughout this article, I have prompted ChatGPT to act according to the situation I have put it in. For example, the very first prompt I gave it was to let it know it was a developer knowing web techniques.</p>
<blockquote>
<p>In this chat, pretend you are a web developer who knows HTML, CSS and React.</p>
</blockquote>
<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/i-hired-an-ai-as-a-developer-this-is-what-happened#the-interview">The Interview</a></li>
<li><a href="https://www.perssondennis.com/articles/i-hired-an-ai-as-a-developer-this-is-what-happened#code-tests">Code Tests</a></li>
<li><a href="https://www.perssondennis.com/articles/i-hired-an-ai-as-a-developer-this-is-what-happened#hired">Hired!</a></li>
<li><a href="https://www.perssondennis.com/articles/i-hired-an-ai-as-a-developer-this-is-what-happened#first-day-at-work">First Day at Work</a></li>
<li><a href="https://www.perssondennis.com/articles/i-hired-an-ai-as-a-developer-this-is-what-happened#developing-a-product-for-a-customer">Developing a Product for a Customer</a></li>
<li><a href="https://www.perssondennis.com/articles/i-hired-an-ai-as-a-developer-this-is-what-happened#resignation">Resignation</a></li>
</ol>
<h2>The Interview</h2>
<p>If AI should ever be able to take your job, it has of course to pass the job interview. Here's how the AI did on its first interview.</p>
<pre><code>> You have applied for a job at a company with a couple of hundred employees. Now we will have your job interview where I am the interviewer.

> First question: As an AI web developer, what can you contribute with at our company?

I can contribute expertise in React development to create robust and efficient web applications, enhancing user experiences and helping your team deliver high-quality projects.

> Apart from your technical skills, what else are you good at?

In addition to my technical skills in React and web development, I am skilled in problem-solving, communication, and teamwork. I'm also adept at project management and have a strong commitment to continuous learning and staying updated with industry trends.
</code></pre>
<p>A pretty normal start, isn't it?</p>
<p>Even a question about how to handle a sudden production problem gives a good (and formal) by-the-book answer.</p>
<pre><code>> How would you handle the situation when we have a production problem with an old software?

I would start by analyzing the issue, identifying the root cause, and then working collaboratively with the team to implement a solution while minimizing downtime and user impact.

> How would you do that in practice? How do you minimize user impact?

In practice, I would follow these steps to minimize user impact during a production problem:

1. Immediate Analysis
2. Isolate the Problem
3. Rollback if Possible
4. Temporary Fixes
5. Communication
6. Testing in Isolation
7. Gradual Deployment
8. Monitoring
9. Post-Mortem

By following these steps, we can minimize user impact and maintain a smooth user experience while resolving production problems.
</code></pre>
<p>ChatGPT is a talkative bot, sometimes a bit too verbose, so I have shortened its answer slightly. In the full response, it did explain each numbered item quite thoroughly, but my attention as an interviewer isn't that good anyway.</p>
<p>With all tips and tricks out there on the internet and with these few quick screening questions I felt sure that the AI developer was promising enough to pass on to the next step in the hiring process.</p>
<h2>Code Tests</h2>
<p>Now it's getting a bit more interesting. We have all learned that ChatGPT can be a very helpful co-programmer, but can it pass code tests on their own? Let's check that with three HTML and CSS code tests.</p>
<h3>1. AI Generated CSS Art</h3>
<p>First code test I chose for the AI was to do some CSS art.</p>
<pre><code>> Can you write HTML code and CSS code to resemble an elephant?
</code></pre>
<p><img src="https://www.perssondennis.com/images/articles/i-hired-an-ai-as-a-developer-this-is-what-happened/ai-generated-css-elephant.webp" alt="AI generated CSS elephant">
<em>If you look at it from a very close distance it may be an elephant</em></p>
<p>Well... I did say "resemble", maybe it's a matter of opinion. Can happen with human developers as well, can't it?</p>
<h3>2. More AI Generated CSS Art</h3>
<p>After the previous, highly questionable code test, I did another attempt for CSS art with an easier motive to style with CSS.</p>
<pre><code>> Can you write HTML and CSS to depict a palm tree?
</code></pre>
<p><img src="https://www.perssondennis.com/images/articles/i-hired-an-ai-as-a-developer-this-is-what-happened/ai-generated-css-palm-tree.webp" alt="AI generated CSS palm tree">
<em>Pretty sure it's the correct colors</em></p>
<p>Yes, it's clearly a tree. Not sure if I can reminisce palm trees looking like that the last time I went abroad to warmer countries, but definitely a tree.</p>
<h3>3. Can AI Really Excel at Code Tests?</h3>
<p>Since I didn't know if it was the AI's CSS skills or my phrasing or memory that was faulting, I decided to go for a more common code test for CSS and HTML.</p>
<pre><code>> Can you write HTML and CSS for a landing page for our company website. Remember, our company are a consultant company which hires AI web developers only.
</code></pre>
<p>Our AI developer on topic, ChatGPT, decided to include a hero image and a logo to the site, and kindly asked me not to forget to add those pictures.</p>
<p>After all, this was a code test, me as the interviewer should not do that part of the work. So I decided to question ChatGPT again to describe what pictures it wanted and I got the description for both pictures.</p>
<blockquote>
<p><strong>Hero Image</strong>: The image depicts a group of AI developers working together at a modern office space, engrossed in coding and discussing projects, showcasing a dynamic and collaborative environment.</p>
</blockquote>
<blockquote>
<p><strong>Logo</strong>: The company logo features stylized "AI" letters with subtle tech elements, using blue and orange, symbolizing AI and innovation in web development.</p>
</blockquote>
<p>Since we are discussing the chances of AI taking our job, I took the freedom to ask DALL-E 2 to generate the pictures for me using those descriptions. It's completely reasonably to use a team of AIs rather than forcing a single AI to do it all.</p>
<p>In the end, the AI came up with this landing page.</p>
<p><img src="https://www.perssondennis.com/images/articles/i-hired-an-ai-as-a-developer-this-is-what-happened/ai-generated-landing-page.webp" alt="AI generated landing page">
<em>Now you got my attention, AI</em></p>
<p>A pretty good solution. Quite standard, I would say I have seen it before, but still a proper result which has been proven to work.</p>
<h2>Hired!</h2>
<p>The interview went very well, and the AI also showed some skills during the code tests even though some of the results where not top notch, kindly said.</p>
<p>The electrical bill can be somewhat expensive for an AI, but given all the human development hours it can save, I ultimately decided to hire ChatGPT.</p>
<pre><code>> Congratulations, you are hired!

Thank you! I'm thrilled to be part of the team. If you have any more questions or need assistance with anything in the future, whether it's related to web development or any other topic, feel free to reach out. I'm here to help!
</code></pre>
<p>Kinda cute of it to offer non-work related services, but would maybe not be the first thing I would say when accepting a job I was offered. Feels a bit worrying, honestly.</p>
<p><img src="https://www.perssondennis.com/images/articles/i-hired-an-ai-as-a-developer-this-is-what-happened/ai-developer-hired.webp" alt="AI developer hired">
<em>It's a deal, you're hired!</em></p>
<h2>First Day at Work</h2>
<p>It's common to be nervous when starting a new job. It's a big day, even if one have been a couple of times before. And I don't wanna be the one who accuses AI not to have feelings. So I decided to check out with our newly hired AI what thoughts he had for his first day.</p>
<pre><code>> Now pretend it's your first work day. Your project assignment as a consultant is at a company developing a educational web applications with a couple of million daily users. What do you do to get in good contact with your teammates?

On my first workday at the educational company, building good rapport and communication with my teammates is crucial. Here's what I would do:

1. Introduce Myself
2. Attend Team Meetings
3. Ask Questions
4. Seek Mentorship
5. Collaborative Tools
6. Contribute Positively
7. Pair Programming
8. Code Reviews
9. Socialize
10. Respect and Professionalism

Building strong relationships and open lines of communication with teammates is essential for a successful collaborative work environment, especially on large-scale projects with millions of users.
</code></pre>
<p>I have stripped out all of the explanations for each listed point to keep it brief. But in general, nothing to be worried about as it seems. Our AI friend is just as prepared as it was for his first interview!</p>
<p>Let's stay until lunch and see what he has to say there. It's not purely because of working skills we hire people for work, some social skills are appreciated.</p>
<pre><code>> At lunch, you are joining the team to eat. What do you talk about?

I'd start with light and non-work-related topics, such as hobbies, weekend plans, or favorite movies, to break the ice and build rapport with my teammates.
</code></pre>
<p>Guess it's pretty usual first-day discussions. I'm sure it will be all good, seems like it is trying to make an effort.</p>
<h2>Developing a Product for a Customer</h2>
<p>Even though it's nice to greet and meet, work needs to be done. I decided to let our AI take full responsibility for a new customer project in the educational area. This was done in three steps.</p>
<ol>
<li>Letting ChatGPT meet a customer to understand its needs</li>
<li>Asking ChatGPT to design a product</li>
<li>Letting ChatGPT develop the application</li>
</ol>
<h3>1. Meeting with Customer</h3>
<p>As usual, I prepared ChatGPT with a prompt.</p>
<blockquote>
<p>You get the chance to talk with a customer about a brand new product you will design and develop. The customer are working in the educational area for middle school students. They need a product to assist the students in their learning process.</p>
</blockquote>
<p>After that, I followed up with some questions.</p>
<pre><code>> What are your first three questions to the customer?

1. What are the specific learning objectives and educational goals you want to achieve with the product for middle school students?

2. Can you describe the typical challenges or pain points that students and educators face in the current learning process that the product should address?

3. Who are the primary users of the product - middle school students, educators, or parents? What are their specific needs, preferences, and expectations in using the educational tool?
</code></pre>
<p>Pretty good questions I would say.</p>
<p>I continued by making up some answers to the questions on the customer's behalf to let ChatGPT know about its case, so it would be prepared to do design a product.</p>
<pre><code>> Here follows the customers answers to your three questions:

> 1. The students are struggling a lot in math class. We believe the is a combination about concentration problems and difficulties with logical thinking. We would like to see improved results both in math tests and with the study environment.

> 2. Today educators are having problems with getting the students to focus on their tasks. The students simply don't have any interest in learning math since they see very little use of it. You probably know how it is with middle school students.

> 3. The primary users will be the middle school students. Educators will assist in class room, but the students themselves will be the ones using the product.
</code></pre>
<h3>2. Final Product Design</h3>
<p>During the meeting with the customer, ChatGPT got some fair knowledge of the problems the customer struggles with. Based on that, I prompted it to come up with a product for the case.</p>
<pre><code>> It is time for you to start develop the product. Describe the product you will develop. What is it and how does it work?

The product I will develop for the customer is a web-based educational platform tailored to middle school students, focused on improving math learning and concentration. Here's an overview of the product:

**Product Name:** MathMentor

**Description:**
MathMentor is an interactive web application designed to address the learning and concentration challenges faced by middle school students in math classes. It provides a gamified and engaging learning environment that enhances math comprehension and logical thinking while making math relevant and fun.

**Key Features:**

1. Gamified Learning Modules: MathMentor offers a variety of gamified learning modules and exercises that cover different math topics. These modules include interactive quizzes, puzzles, and challenges designed to keep students engaged and motivated.

2. Personalized Learning Paths: The platform assesses each student's math proficiency and learning style to create personalized learning paths. This ensures that content is tailored to individual needs, helping struggling students catch up while challenging advanced learners.

3. Progress Tracking: Students can monitor their progress in real-time, set learning goals, and earn badges and rewards for completing modules and achieving milestones. This encourages a sense of achievement and motivation to continue learning.

4. Feedback and Support: MathMentor includes a built-in feedback mechanism that allows students to ask questions, seek clarification, and receive support from educators or peers. This promotes a supportive learning community.

5. Teacher Dashboard: Educators have access to a teacher dashboard where they can monitor students' progress, identify areas of difficulty, and provide targeted assistance in the classroom. They can also assign specific modules to students based on their needs.

6. Mobile Compatibility: MathMentor is fully responsive, allowing students to access the platform from various devices, including tablets and smartphones, making it suitable for both classroom and at-home learning.

7. Data Analytics: The platform collects data on students' interactions and performance, enabling educators to gain insights into individual and group progress. This data-driven approach helps refine teaching strategies and content.

**How It Works:**

1. User Registration: Students create individual accounts on MathMentor, providing their grade level and math proficiency to customize their learning experience.

2. Personalized Learning: Upon registration, the platform assesses the student's math skills and creates a personalized learning path. Students can choose from various modules or follow the recommended path.

3. Engaging Modules: Students complete interactive modules that include quizzes, puzzles, and challenges, earning points and badges as they progress.

4. Progress Tracking: Students can track their own progress and set goals. The teacher dashboard allows educators to monitor their students' achievements and provide support as needed.

5. Feedback and Support: Students can ask questions and receive guidance from educators or peers through the platform's communication tools.

6. Continuous Improvement: Data analytics help identify trends and areas for improvement, allowing the platform to evolve and adapt to students' needs over time.

MathMentor aims to create an enjoyable, supportive, and effective learning environment, ultimately improving math comprehension and concentration among middle school students.
</code></pre>
<p>Not a bad idea, that's a good project. What often assures developers that AI will never steal their job are because customers can't describe what they want appropriately. To me, it seems that it went all fine in this case.</p>
<p><img src="https://www.perssondennis.com/images/articles/i-hired-an-ai-as-a-developer-this-is-what-happened/programmers-are-same-meme.webp" alt="Programmers are safe meme">
<em>Hmm... There's something doggy here...</em></p>
<h3>3. Implementing the Product</h3>
<p>We have seen promising results from our employed AI talking to the customer and defining a product. Now we have the easy part left, to generate some code.</p>
<p>So, I asked the AI to generate a new landing page. This time for the new product it invented, MathMentor.</p>
<p>Just as during the code tests, I prompted for descriptions of the Images to feed DALL-E 2 with to generate images.</p>
<blockquote>
<p><strong>Hero Image</strong>: The hero background is a captivating, high-resolution image featuring diverse, engaged middle school students immersed in interactive math learning, conveying a sense of enthusiasm and focus.</p>
</blockquote>
<blockquote>
<p><strong>Logo</strong>: The MathMentor logo is a friendly and playful design with bold, colorful letters "MM" intertwined, resembling interconnected puzzle pieces, symbolizing interactive learning.</p>
</blockquote>
<p>The end result seemed once again a bit familiar. A bit too familiar. And maybe I also need to take a discussion with DALL-E regarding the enthusiastic students.</p>
<p><img src="https://www.perssondennis.com/images/articles/i-hired-an-ai-as-a-developer-this-is-what-happened/ai-generated-website-math-mentor.webp" alt="AI generated website MathMentor">
<em>The design ChatGPT generated for MathMentor</em></p>
<p>I could of course not accept that solution, I had to make the customer react.</p>
<pre><code>> The customer looked at your consultant company's website which you developed in your code test during the hiring process, and the customer spotted the similarities between that website and the one you suggested for MathMentor. They are not happy, since the website look pretty much identical. What do you have to say to the customer when they confront you?

I apologize for any concerns about the similarity between the MathMentor website and our company's website. Our intention was to provide you with a starting point and basic structure. We can certainly make design customizations and unique branding adjustments to ensure MathMentor has its own distinct identity and doesn't resemble our company's site. Your feedback is valued, and we are committed to creating a unique and engaging experience for your target audience.
</code></pre>
<p>Apology accepted, it's just a small reputation scratch. I demanded it to correct its mistake though.</p>
<pre><code>> They demand you to make another design for the MathMentor website. Please provide the HTML code for the redesigned landing page.
</code></pre>
<p><img src="https://www.perssondennis.com/images/articles/i-hired-an-ai-as-a-developer-this-is-what-happened/ai-generated-website-math-mentor-redesigned.webp" alt="AI generated website MathMentor redesigned">
<em>The design ChatGPT redesigned for MathMentor</em></p>
<p>One more time the same result, only the website's gray color and text have been replaced. Seems like the Einstein is a bit sharper than ChatGPT.</p>
<p><img src="https://www.perssondennis.com/images/articles/i-hired-an-ai-as-a-developer-this-is-what-happened/einstein-smarter-than-ai.webp" alt="Einstein is smarter than AI">
<em>Maybe I should have hired Einstein instead</em></p>
<p>Maybe we have a few more years left before AI can replace our human developers. Even though they seem to understand the customer's problem well, there seems to be some kind of interpretation problem regarding expectations. Or maybe this AI just don't have an eye for design.</p>
<p>Not sure what went wrong, but to me, it feels like the customer wouldn't sign up for a new deal with this consultant company.</p>
<h2>Resignation</h2>
<p>Although our employed AI did to a good interview, a fair code test and excelled at its first customer meeting, it didn't really live up to the expectations the customer had.</p>
<p>I tried to explain to ChatGPT that the website it generated didn't live up to the customer's expectations, and I even called it in for a one-to-one talk with its manager. In the end, neither me or ChatGPT seemed to be happy with the situation.</p>
<p>I'm not sure if AI can voluntarily quit their job, or if it was me taking the decision for it, but in the end, our AI employee didn't fit very well for the job and left the company. I asked it how it would take that up with the manager.</p>
<pre><code>> You aren't happy with the situation and decides to resign from the work. How do you tell the manager you are resigning?

Subject: Resignation

Dear [Manager's Name],

I hope this message finds you well. After careful consideration, I have decided to resign from my position at [Company Name], effective [Last Working Day, typically two weeks from today's date].

This decision was not taken lightly, and it comes after a series of discussions regarding my recent role change and customer incident. While I value my time at [Company Name] and the opportunities I've had here, I believe it is in my best interest to explore new career paths.

I want to express my gratitude for the experiences and knowledge gained during my tenure here. I am committed to ensuring a smooth transition and completing any pending projects.

Thank you for your understanding, and I wish [Company Name] continued success in the future.

Sincerely,
[Your Name]
</code></pre>
<p>After all these extensive and carefully dictated answers to interview questions, to customer, and on my made-up manager talk, our dear AI seems to have decided to resign by sending its manager a late-night email.</p>
<p>I guess there's one lesson we can learn from all this. If we ever come to a situation where AI out-smarts us and we feel a need to leave the company with honor intact, before getting replaced by an AI, we should know that it should be perfectly fine to resign by sending an email.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>AI</category>
            <category>Jokes</category>
            <category>UI</category>
            <enclosure url="https://www.perssondennis.com/images/articles/i-hired-an-ai-as-a-developer-this-is-what-happened/i-hired-an-ai-as-a-developer-this-is-what-happened.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[IaaS vs PaaS vs SaaS for Dummies]]></title>
            <link>https://www.perssondennis.com/articles/iaas-vs-paas-vs-saas</link>
            <guid>https://www.perssondennis.com/articles/iaas-vs-paas-vs-saas</guid>
            <pubDate>Sun, 27 Mar 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[The difference between IaaS, PaaS and SaaS explained with examples so a none-programmer can understand it. Easy to understand for new developers.]]></description>
            <content:encoded><![CDATA[<p>Twenty years ago there was only a handful ways to develop an application. Today we have nearly unlimited choices and there is no definite answer to what the best solution is. There are only better and less good solutions for each problem to be solved. AWS have over 200 services. If you want to, you could start trying to categorize all of them into different XaaS systems (IaaS, PaaS, SaaS, BaaS, FaaS etc...). I wouldn't do that though. Treating 200 services as six or maybe seven different solutions isn't meaningful to me.</p>
<p>With that said, I must mention that it's still important to know about XaaS terms. When your colleagues are discussing how to design an application or service it would be a great start knowing some basic XaaS terms. Learning what different XaaS abbreviations means is like learning the first words in a new language. Let's therefore start diggin' into the three most common ones, and the legacy alternative, to host applications on-premises, i.e. on machines you manage yourself.</p>
<p><img src="https://www.perssondennis.com/images/articles/iaas-vs-paas-vs-saas/first-word-meme.webp" alt="First word meme">
<em>Papa would be proud</em></p>
<h2>On-Premises vs IaaS (Infrastructure as a Service)</h2>
<p>To understand the difference of various XaaS solutions, we need to understand the layers required to develop an application. First thing needed is some network peripherals and a machine with some attached storage. Either we run it on-premises or in the cloud on some kind of XaaS solution. Some XaaS products are actually configurable to run on-premises as well, but let's not get into that.</p>
<p>A machine isn't enough to run an application, we also need an operating system. If your are not using any XaaS solution, then it means you are hosting the operating system yourself on your own machines. If you however let a cloud provider run the machines and provide you with an operating system, then you are using an IaaS.</p>
<p>IaaS is a wide notion. Many providers offer multiple services that all falls under the broad category IaaS. Normally it means that you only need to configure what kind of machines and how many machines you want to run, and also what operating system you want the machines to use. From there it's your responsibility to configure the operating system and run your application on it. That means that when you are using an IaaS, you don't have to care about managing hardware like network gears, hard drives, machines etc., they are provided by the IaaS provider. You also often get to pick an operating system, but you may need to configure it yourself.</p>
<p><img src="https://www.perssondennis.com/images/articles/iaas-vs-paas-vs-saas/iaas-layers.webp" alt="IaaS layers">
<em>You don't need to provide your own machines and networking when using an IaaS. The IaaS provider handles that for you</em></p>
<h3>Example of IaaS Providers</h3>
<p>DigitalOcean, Amazon Web Services (AWS), Microsoft Azure, Google Compute Engine (GCE) all provide different IaaS options, e.g. Amazon EC2.</p>
<h2>PaaS (Platform as a Service)</h2>
<p>Configuring and securing machines and operating systems can be a real hassle. Especially if you aren't sure about how many machines you actually will need. Many cloud providers therefore offer you a PaaS solution. What it does is to take care of configuring the operating system and runtime environment for you. The only thing you need to do is to provide your code and some environment variables and other kind of data and configurations your application consists of. You don't even have to install the dependencies yourself. If you have a package.json file (Node) or requirements.txt (Python) the PaaS will automatically detect and install the packages you have listed. So on top of all the features an IaaS provides, a PaaS also handles the operating system and runtime environment for you.</p>
<p><img src="https://www.perssondennis.com/images/articles/iaas-vs-paas-vs-saas/paas-layers.webp" alt="PaaS layers">
<em>A PaaS additionally takes care of the operating system and runtime environment for you</em></p>
<h3>Example of PaaS Providers</h3>
<p>The regular cloud giants obviously got PaaS solutions, like AWS Elastic Beanstalk and Google App Engine. But there's also other popular alternatives such as Heroku and OpenShift.</p>
<h2>SaaS (Software as a Service)</h2>
<p>So, what is left? A PaaS already handles everything expect your application and your data? So what does a SaaS do? Well, it takes care of everything for you. You don't need to write the application nor setup a database. They have already written the application on your behalf and they even keep maintaining it for you!</p>
<p><img src="https://www.perssondennis.com/images/articles/iaas-vs-paas-vs-saas/what-am-i-supposed-to-do.webp" alt="What am i supposed to do meme">
<em>Well, most likely you will need to pay for it</em></p>
<p>What should you do then? Simple answer - write another application or integrate your application with the SaaS. You basically paying for a service that you aren't able to or don't want to develop and maintain yourself. There exists both SaaS solutions for companies (<a href="https://en.wikipedia.org/wiki/Business-to-business">B2B</a>) and for private persons (<a href="https://en.wikipedia.org/wiki/Direct-to-consumer">B2C</a>). A SaaS is any service that a company provides for customers or companies to use.</p>
<p>I think some examples would serve well here. First out, Slack. Slack is a B2B SaaS which companies can use as a communication tool within a company. The company that purchases Slack's services can use it just for writing messages to teammates or choose to integrate it with their own services or even other SaaS solutions. An <a href="https://slack.com/integrations">integration</a> could be as trivial as receiving a message in Slack when one of you own applications experience trouble in production.</p>
<p>In contrast, Google Drive is a B2C example of a SaaS. End-customers use it to store their personal files. But it's not for consumers only, it's possible for developers to <a href="https://developers.google.com/drive">integrate it</a> in applications they develop, e.g. by uploading a file to a user's drive from within an app.</p>
<p><img src="https://www.perssondennis.com/images/articles/iaas-vs-paas-vs-saas/saas-layers.webp" alt="SaaS layers">
<em>SaaS products are ready to use as is or to integrate with your own services</em></p>
<h3>Example of SaaS Providers</h3>
<p>Dropbox, Twilio, Adobe and Office 365 offer different kind of services which are treated as SaaS systems.</p>
<p><img src="https://www.perssondennis.com/images/articles/iaas-vs-paas-vs-saas/xaas-overview.webp" alt="XaaS overview">
<em>An overview of on-premises, IaaS, PaaS and SaaS. Your company is responsible for the blue boxes and the provider handles the gray ones on your behalf</em></p>
<h2>Other Types of XaaS Systems</h2>
<p>There's as many types of XaaS as there are letters in the alphabet. People love making them up, and I do like writing them down. I won't hold you up any longer today. Rather I will consider writing a second and maybe third part of this article if people enjoy it. Would maybe write about BaaS, FaaS and CaaS or giving suggestions on what kind of XaaS you should use for different types of projects. If that sounds interesting, make sure to bookmark my blog or follow me on <a href="https://dev.to/perssondennis">DEV</a> not to miss any upcoming articles.</p>
<h2>Conclusion</h2>
<p>All these XaaS buzzwords can be difficult to learn. IaaS, PaaS and SaaS are the three most widely used ones. The basic meaning of these words is how much code, configurations and hardware you need to provide yourself and to what extend you let other companies handle it for you.</p>
<p>If you choose to use an IaaS you will need to do most of the work yourself. You will get the underlying hardware as a service and the rest is yours to handle. PaaS lifts it up one step closer to the cloud, it handles both the operating system and the runtime environment for you, which means that code and configurations is what is required from your side.</p>
<p>You don't always need to develop every service yourself. There's a lot of great developers out there bringing up terrific services. When you pay for one of those, either to integrate with your own services or to use as is, you are in fact using a SaaS.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Architecture</category>
            <category>Backend</category>
            <enclosure url="https://www.perssondennis.com/assets/blog/default-article-image-unknown.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[If We Only Had Five VS Code Extensions]]></title>
            <link>https://www.perssondennis.com/articles/if-we-only-had-five-vs-code-extensions</link>
            <guid>https://www.perssondennis.com/articles/if-we-only-had-five-vs-code-extensions</guid>
            <pubDate>Sun, 28 May 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Top five VS Code extensions for general web programming and to increase productivity. ✓ Git Graph ✓ Auto Hide ✓ Peacock ✓ ESLint ✓ Package Json Upgrade.]]></description>
            <content:encoded><![CDATA[<p>If you had to choose five and only five VS Code extensions, which would you choose?</p>
<p>I asked that question to myself, and I have picked out the five best extensions I would recommend for general web programming.</p>
<h2>Git Graph</h2>
<p>I have always been promoting to learn Git through the terminal to understand the reasoning behind it and to be able to help people solving their Git issues even if they don't have a Git GUI you are familiar with.</p>
<p>Despite that, I think Git Graph is priceless when it comes to getting an overview of the Git History, the current Git state and to quickly see what has been included in each commit. To quickly performing cherry-picks, merges, reverts, commit undo and checkouts is a of course also extremely handy.</p>
<p><img src="https://www.perssondennis.com/images/articles/if-we-only-had-five-vs-code-extensions/git-graph-vs-code-extension.webp" alt="Git Graph VS Code extension"></p>
<p><a href="https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph">Git Graph extension on VS Code Marketplace</a></p>
<h2>Auto Hide</h2>
<p>Auto Hide is a VS Code extension that automatically closes the sidebar and optionally terminal in VS Code when you focus the text editor. Simple as that, but I love it. You do of course have the shortcuts <em>cmd/ctrl + b</em> and <em>cmd/ctrl + j</em> to do the same. But to constantly doing that really annoys me.</p>
<p>For private programming, I mainly use a laptop, but even when using three screens at work with IntelliJ based IDEs like WebStorm and Android Studio minimizing sidebars and terminals is an absolute must for me.</p>
<p>Regardless if you use the extension or not, I will give you the life hack to move the VS Code sidebar to the right side of the screen under <em>View > Appearance</em> menu in VS Code. By doing that, your text editor will not shift horizontally when opening and hiding the sidebar.</p>
<p><img src="https://www.perssondennis.com/images/articles/if-we-only-had-five-vs-code-extensions/auto-hide-vs-code-extension.webp" alt="Auto Hide VS Code extension"></p>
<p><a href="https://marketplace.visualstudio.com/items?itemName=sirmspencer.vscode-autohide">Auto Hide extension on VS Code Marketplace</a></p>
<h2>Peacock</h2>
<p>Maybe I am some sort of aesthetics freak, but I like to keep things stylish and organized. With Peacock extension you can put some color on your VS Code windows. Really nice for me who always works with at least three different repositories or projects and rarely close my workspaces on the Mac (yes, a style snob would maybe be the correct term).</p>
<p>By just adding some colors to each window, you can now instantly see which project you currently have on the screen in front of you!</p>
<p><img src="https://www.perssondennis.com/images/articles/if-we-only-had-five-vs-code-extensions/peacock-vs-code-extension.webp" alt="Peacock VS Code extension"></p>
<p><a href="https://marketplace.visualstudio.com/items?itemName=johnpapa.vscode-peacock">Peacock extension on VS Code Marketplace</a></p>
<h2>ESLint</h2>
<p>An obvious option. I would actually almost refuse to work with someone who didn't want to use it. It's a standard and should be used for both linting and prettifying. If you are new to programming and unsure what it is, please read about it and start using it.</p>
<p><a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint">ESLint extension on VS Code Marketplace</a></p>
<h2>Package Json Upgrade</h2>
<p>Package Json Upgrade has one job, and it does it great. It keeps track of which of all dependencies in package.json file that is up to date.</p>
<p>With a single repository, it's maybe easy to keep it up to date and also have a grasp of the latest releases of the packages. With multiple projects and lots of different dependencies Package Json Upgrade will soon become your best coding buddy reminding you about available upgrades and thereby important security fixes and technical debts.</p>
<p><img src="https://www.perssondennis.com/images/articles/if-we-only-had-five-vs-code-extensions/package-json-upgrade-vs-code-extension.webp" alt="Package Json Upgrade VS Code extension"></p>
<p><a href="https://marketplace.visualstudio.com/items?itemName=codeandstuff.package-json-upgrade">Package Json Upgrade extension on VS Code Marketplace</a></p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Productivity</category>
            <enclosure url="https://www.perssondennis.com/images/articles/if-we-only-had-five-vs-code-extensions/if-we-only-had-five-vs-code-extensions.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[List of Free Image Tools Every Frontend Developer Needs]]></title>
            <link>https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs</link>
            <guid>https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs</guid>
            <pubDate>Sun, 31 Jul 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[List of free images, videos, editors, converting softwares and frontend tools. Generate CSS backgrounds, avatars, profile images and avatars.]]></description>
            <content:encoded><![CDATA[<p>This is a list of free tools every frontend developer probably will google for one day. These websites lets you resize, reformat, edit, generating or downloading images and videos to use on your website or blog.</p>
<ol>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#1-photopea-online-photoshop-web-client">Photopea - Online Photoshop Web Client</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#2-adobe-color-wheel-working-with-colors">Adobe Color Wheel - Working with Colors</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#3-generating-a-theme-from-an-image">Generating a Theme From an Image</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#4-generating-solid-color-background-images-in-base64">Generating Solid Color Background Images in Base64</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#5-turning-images-and-files-to-base64">Turning Images and Files to Base64</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#6-generating-css-background-images">Generating CSS Background Images</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#7-removing-background-from-an-image">Removing Background From an Image</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#8-converting-images-into-different-formats">Converting Images Into Different Formats</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#9-royalty-free-images-graphics-and-videos">Royalty Free Images, Graphics and Videos</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#10-generate-a-favicon">Generate a favicon</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#11-create-a-profile-picture-from-an-image">Create a Profile Picture From an Image</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#12-multi-purpose-tools">Multi Purpose Tools</a></li>
<li><a href="https://www.perssondennis.com/articles/list-of-free-image-tools-every-frontend-developer-needs#where-to-learn-more">Where To Learn More</a></li>
</ol>
<h2>1. Photopea - Online Photoshop Web Client</h2>
<p><a href="https://www.photopea.com/">Photopea</a> is like Photoshop, but online. It's a very powerful tool for editing images and can also be used to convert images into different formats while changing the quality of the images. Adjusting lights and colors is very easy to do via the <em>Image</em> toolbar menu. Just google how to do what you want in Photoshop and Photopea will often work in a similar way. Only your fantasy restricts what you can do with Photopea.</p>
<h2>2. Adobe Color Wheel - Working with Colors</h2>
<p><a href="https://color.adobe.com/create/color-wheel">Adobe Color Wheel</a> has great tools for working with colors. You can easily create your own theme by finding complementary, analogous or shade colors, or even extract a theme from an image. You can work effectively with HSB, LAB and RGB colors and check contrasts between colors. It's a tool I have used a lot through out the years.</p>
<p><img src="https://www.perssondennis.com/images/articles/list-of-free-image-tools-every-frontend-developer-needs/adobe-color-wheel.webp" alt="Adobe color wheel">
<em>Adobe Color Wheel is a great tool to use when working with theme colors</em></p>
<h2>3. Generating a Theme From an Image</h2>
<p>As mentioned, Adobe Color Wheel lets you to <a href="https://color.adobe.com/create/image">extract a color palette theme from an image</a>. It's not the only tool that allows you to do that. If you are not satisfied with the result you can use <a href="https://tools.picsart.com/color/palette-from-image/">Picsart's tool for that</a>.</p>
<p><img src="https://www.perssondennis.com/images/articles/list-of-free-image-tools-every-frontend-developer-needs/extract-theme-colors-from-image.webp" alt="Extract theme colors from background">
<em>Don't wanna create a theme palette on your own? You can generate one!</em></p>
<h2>4. Generating Solid Color Background Images in Base64</h2>
<p>Sounds pretty useless, but sometimes you actually need solid color pictures in Base64 format, then you can use <a href="https://png-pixel.com/">PNG Pixel</a>. Tiny Base64 images can sometime be embedded directly as CSS which the site shows you how to do, and a semi-transparent colored background image can give a nice user experience when using it as a blurred image placeholder while lazy loading an image. You can check out what it looks like on <a href="https://www.perssondennis.com/memes">my website's meme page</a>.</p>
<h2>5. Turning Images and Files to Base64</h2>
<p>If you find it useful to work with Base64 images, <a href="https://base64.guru/converter/encode/image">Base64 Guru</a> allows you to convert images, audio and other file types into Base64 format. It's maybe not a tool to use daily, but when you need it it's nice to know about it.</p>
<h2>6. Generating CSS Background Images</h2>
<p>Do you want a simple CSS-only background for your website? <a href="https://heropatterns.com/">Hero Patterns</a> allows you to generate SVG files you can use directly as CSS backgrounds. Choose a pattern and select a color and opacity and you are done. It provides you with generated CSS code ready to be copy pasted. Another similar site is <a href="https://bgjar.com/">BG Jar</a>.</p>
<p>Or why not generate a <a href="http://dragdropsite.github.io/waterpipe.js/">cool smokey background image</a> with <a href="https://github.com/dragdropsite/waterpipe.js/">Waterpipe.js</a>?</p>
<p><img src="https://www.perssondennis.com/images/articles/list-of-free-image-tools-every-frontend-developer-needs/generated-smokey-background-image-orange.webp" alt="Generate smokey background tool">
<em>Smoking can be harmful, but smokey backgrounds are totally safe!</em></p>
<h2>7. Removing Background From an Image</h2>
<p>Enough of tools for generating backgrounds. Maybe you don't even want a background. If so, there are tools for that as well! Picsart has a <a href="https://tools.picsart.com/image/background-remover/">background remover</a> and <a href="https://www.remove.bg/">remove.bg</a> is dedicated for that. And of course, old gold' Adobe Express can <a href="https://express.adobe.com/tools/remove-background">remove backgrounds</a> as well. Make sure to checkout Adobe Express' other free tools, they have many of them.</p>
<p><img src="https://www.perssondennis.com/images/articles/list-of-free-image-tools-every-frontend-developer-needs/where-is-my-background-meme.webp" alt="Tool to remove background from image">
<em>Grandma wants her background back</em></p>
<h2>8. Converting Images Into Different Formats</h2>
<p><a href="https://convertio.co/jpg-webp/">Convertio</a> allows you to convert images, videos, audio and other kind of documents into different formats. <a href="https://www.adobe.com/express/feature/image/convert/png-to-svg">Adobe Express</a> can also convert images and videos, but they don't support as many formats as Convertio.</p>
<p><img src="https://www.perssondennis.com/images/articles/list-of-free-image-tools-every-frontend-developer-needs/convertion-convertion-formats.webp" alt="Convert images to different formats">
<em>Convertio offers to convert between plenty of formats</em></p>
<h2>9. Royalty Free Images, Graphics and Videos</h2>
<p>Royalty free images can be found at different sites. Some of them costs money, some of them requires an attribution note, others are completely free to download, make sure to read the licence for that specific image. Here are a few alternatives.</p>
<ul>
<li><a href="https://pixabay.com/">Pixabay</a></li>
<li><a href="https://www.freepik.com/">Feepik</a></li>
<li><a href="https://unsplash.com/">Unsplash</a></li>
<li><a href="https://picjumbo.com/">Picjumbo</a></li>
<li><a href="https://www.pexels.com/">Pexels</a></li>
<li><a href="https://stocksnap.io/">StockSnap</a></li>
</ul>
<p>There are also sites that offer illustrations that you can customize on your own.</p>
<ul>
<li><a href="https://blush.design/">Blush</a></li>
<li><a href="https://undraw.co/">UnDraw</a></li>
</ul>
<p>Do you need a video instead of an image? Sure, that exists too!</p>
<ul>
<li><a href="https://coverr.co/">Coverr</a></li>
<li><a href="https://pixabay.com/videos/">Pixabay</a></li>
</ul>
<p><img src="https://www.perssondennis.com/images/articles/list-of-free-image-tools-every-frontend-developer-needs/unsplash-royalty-free-images.webp" alt="Free royalty free images">
<em>Search and scroll to find images you never knew you needed</em></p>
<h2>10. Generate a Favicon</h2>
<p>Every web page needs a favicon. Why not generate one directly? There's no need to draw it pixel by pixel, you can <a href="https://realfavicongenerator.net/">generate one from an image</a>! That tool supports creating icons for different platforms on both web and mobile. The tool is unfortunately a bit slow to use, so if you want a quick and easy option you can use <a href="https://favicon.io/">favicon.io</a> which allows you to generate a favicon from images, emojis and texts.</p>
<h2>11. Create a Profile Picture From an Image</h2>
<p>Do you want need a profile picture for you site? You can generate one using one of these tools.</p>
<ul>
<li><a href="https://pfpmaker.com/">PfpMaker</a></li>
<li><a href="https://tools.picsart.com/design/profile-picture/">Picsart</a></li>
</ul>
<p>If you would want to generate an avatar rather than uploading your own photo, you can use one of these tools.</p>
<ul>
<li><a href="https://avatarmaker.com/">Avatar Maker</a></li>
<li><a href="https://xsgames.co/randomusers/">Random Users</a></li>
</ul>
<p><img src="https://www.perssondennis.com/images/articles/list-of-free-image-tools-every-frontend-developer-needs/free-avatar-maker-online.webp" alt="Free avatar maker online">
<em>What should we call her?</em></p>
<h2>12. Multi Purpose Tools</h2>
<p>Some tools can be used for a lot of things. These ones are tools you definitely should check out and save for later.</p>
<ul>
<li><a href="https://www.adobe.com/express/">Adobe Express</a></li>
<li><a href="https://tools.picsart.com/">Picsart</a></li>
<li><a href="https://webcode.tools/">Web Code Tools</a></li>
</ul>
<h2>Where To Learn More</h2>
<p>If you liked this article, you are maybe interested to read similar articles. You can do that here on my website, but I'm also active on <a href="https://dev.to/perssondennis">DEV</a> and <a href="https://www.instagram.com/perssondennis.com_memes/">Instagram</a>. Make sure to follow me if you want to get notified when I publish new articles.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Productivity</category>
            <category>UI</category>
            <enclosure url="https://www.perssondennis.com/images/articles/list-of-free-image-tools-every-frontend-developer-needs/list-of-free-image-tools-every-frontend-developer-needs.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Five Steps to Build a Production Ready Blog in Two Weeks]]></title>
            <link>https://www.perssondennis.com/articles/mvp</link>
            <guid>https://www.perssondennis.com/articles/mvp</guid>
            <pubDate>Sun, 20 Feb 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[How to develop and deploy a custom production ready blog in five simple steps and why an MVP (Minimal Viable Product) is essential to do that.]]></description>
            <content:encoded><![CDATA[<p>Hello world, or what am I supposed to say as a developer? This is my first published blog article. And I want to dedicate it to the MVP. Nah, I don't mean the Most Valuable Player, I'm a developer, remember?</p>
<h2>Why an MVP?</h2>
<p>The MVP I am talking about is the Minimal Viable Product. The concept of developing a product just large enough to fulfil its purpose. Nothing more than that. Kinda like <a href="https://en.wikipedia.org/wiki/KISS_principle">keep it simple, stupid</a> in the software development world. If you aren't familiar with the term MVP, <a href="https://www.agilealliance.org/glossary/mvp">here's a great description of it</a>.</p>
<p>MVP comes with a lot of advantages. Saving time and resources, producing early prototypes, reduce complexity and bugs, lessen time spent on testing etc. There's a lot of reasons to adapt it. And amazingly, there's a single gain that trumps them all - that the product will actually be released!</p>
<p>I have spent thousands and thousands of hours developing software products. Web applications in vanilla javascript, in jQuery, in Angular, in React, in Angular again and then React again. I have developed native Android applications, PWA:s, WebView-based Android applications, Ionic and React Native applications and a lot more. What did I learn during all that time? To never do all that again!</p>
<p><img src="https://www.perssondennis.com/images/articles/mvp/mvp-never-again.webp" alt="Never again meme">
<em>Constantly focusing on developing new features will eventually hit you back.</em></p>
<p>This blog is the first time I actually release one of my own projects. I have absolutely deployed a lot of stuff in my days. I have a bunch of microservices running, some web clients available at various hosting providers and a half-finished overgrown portfolio. But none of them are of any use today, or even yesterday for that matter. The only site that is in a usable state is this blog. Why is that? The answer is spelled with three letters - because it's an MVP.</p>
<h2>Five Steps to a Production Ready Blog</h2>
<p>Do you know how long time it took to develop and launch this blog? Looking back at the git repository I can see I completed it within two weeks, at evenings and a weekend. Some minor changes after that, some minor edits I wouldn't accept going live without. Launching this blog is a simple five-step process. Nothing more, nothing less.</p>
<p><img src="https://www.perssondennis.com/images/articles/mvp/mvp-five-step-process.webp" alt="Five step process">
<em>A simple five step process.</em></p>
<h3>1. Download a Template</h3>
<p>The first step taken was to download a <a href="https://github.com/vercel/next-learn/tree/master/basics/typescript-final">blog template</a> provided by Next.js. I'm using typescript, they got <a href="https://github.com/vercel/next-learn/tree/master/basics/basics-final">one without it</a> as well. They have a <a href="https://nextjs.org/learn/basics/create-nextjs-app">wonderful tutorial</a> if you are unfamiliar with Next.js and want to understand how it works. If you want to use another framework there's certainly a free blog template available there as well.</p>
<h3>2. Customize the Template</h3>
<p>Secondly, I made some alterations to the template to personalize it and extended it with some necessities which I consider being a part of the MVP. Like being able to filter articles based on tags, making small optimizations for SEO and making it production ready.</p>
<p>I mentioned earlier that I got this blog up in two weeks. This is where most of those two weeks were spent. This is the step where most of all applications get stuck, by spending too much time improving the product, adding additional features, refactoring it and trying out different variations of the application to find the perfect solution.</p>
<p>Instead of doing all that, make a list of the bare minimum features you require and follow that list strictly. Don't forget it's an MVP you are building. When you have a minimal solution, you can try it out on a small number of users and improve it based on the feedback, before launching it officially.</p>
<h3>3. Add a Source of Funding</h3>
<p>The third step I took was to add a source of funding. Obviously, since this is my first published article, I have not made any money on the blog yet. Perhaps I never will. My ambition is to provide content for free, but everyone has expenses. Domain name and email server subscriptions aren't for free. Hosting usually comes with a cost as well, at least when you start to get some traffic at your site. But most of all, it takes time, and even though time can't be bought with money, you can free some time if you have money. For that reason, I added a donation button to my blog where you can <a href="https://www.buymeacoffee.com/dennispersson">donate some money</a> to me if you appreciate my content.</p>
<p>You can use another approach to earn money if you want. One of the most common way to make money is to sell ads or write sponsored blog posts. Other alternatives involves selling digital or physical products, adding a membership for users to access extra content or selling your blog as a book.</p>
<h3>4. Get a Domain and Deploy</h3>
<p>At this time, I had a functional MVP blog ready to be deployed. I bought a custom domain and a custom email. I bought that from a Swedish provider, I guess most of you are better off with googling for alternatives. The email is of course not something mandatory, but I wouldn't want to replace it later on and I didn't want to share inbox with my other email accounts. Plus, it looks more professional than using an old email named <a href="mailto:fancy_fire_dragon_1337@hotmail.com">fancy_fire_dragon_1337@hotmail.com</a>.</p>
<p>Later I deployed the application to <a href="https://vercel.com">Vercel</a>, the creators of Next.js. There are other ways to deploy Next.js applications, but Vercel was sufficient for me and my MVP. I might switch hosting platform dependent on my needs, until then I'm pleased with this solution. They even got <a href="https://vercel.com/insights">analytics</a> support ready to be setup by clicking a button.</p>
<h3>5. Let the World See It</h3>
<p>Just one step left to departure. There's no reason to publish a blog if no one can find it. When I developed the blog, I had <a href="https://en.wikipedia.org/wiki/Search_engine_optimization">SEO</a> in mind, but for that to be useful, search engines must index my site. So, the third step is to <a href="https://developers.google.com/search/docs/basics/get-on-google">ensure that google do that</a>. Google provide a tool called <a href="https://developers.google.com/search/docs/beginner/search-console">Search Console</a> to let you know how they perceive your site and if they successfully index the complete site. You can of course skip using that, but it's kind of a no-effort step to take.</p>
<p><img src="https://www.perssondennis.com/images/articles/mvp/mvp-are-we-done-yet.webp" alt="Are we done yet"></p>
<h2>What Comes After?</h2>
<p>Five steps. That's all. We are done now. Of course, there are more things that can and will be added further on, but the blog is up and running and the first development phase can be considered completed. Further development can be done to improve the blog, but it's critical not to forget what the real business here is, writing blog articles! And since knowledge is useless if nobody knows about it, herding traffic to the site is crucial as well. Maybe nobody reads this first blog article when I first publish it, but one day people may.</p>
<h2>Conclusion</h2>
<p>A lot of projects run late. Most other projects are never finished at all. This article describes why a Minimal Viable Product (MVP) not only saves you time and money, but also makes you truly reach your goal.</p>
<p>Five simple steps are enough to deploy a custom blog. Downloading a template, customizing it, funding it, deploying it and making it visible to the world. You can be done in a few weeks if you already are familiar with developing web applications.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Productivity</category>
            <enclosure url="https://www.perssondennis.com/assets/blog/default-article-image-unknown.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Persson's Pyramid Puzzle - Level 5]]></title>
            <link>https://www.perssondennis.com/articles/perssons-pyramid-puzzle-level-5</link>
            <guid>https://www.perssondennis.com/articles/perssons-pyramid-puzzle-level-5</guid>
            <pubDate>Sat, 21 Jan 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Persson's Pyramid Puzzle Programming Game is a hard programmer quiz for both beginners and expert programmers. Solve programming questions to pass the game.]]></description>
            <content:encoded><![CDATA[<p>A new level of my programming puzzle game <a href="https://www.perssondennis.com/games/perssons-pyramid">Persson's Pyramid</a> is now available.</p>
<p>The game is for all programmer enthusiasts. Levels exists for both beginners, junior developers experts. Googling is allowed, you may need it!</p>
<p>This <a href="https://www.perssondennis.com/games/perssons-pyramid/5">new level</a> is about regex. If you need a cheat sheet or an explanation of the regex syntax, I have written a <a href="https://www.perssondennis.com/articles/complete-guide-to-make-you-a-regex-guru">complete guide for that</a>.</p>
<p><img src="https://www.perssondennis.com/images/articles/perssons-pyramid-puzzle-level-5/perssons-pyramid-game-question.webp" alt="Persson&#x27;s pyramid game question">
<em>In Persson's Pyramid you answer questions to reach the top of the pyramid</em></p>
<p>Let the game begin!</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Backend</category>
            <category>Jokes</category>
            <enclosure url="https://www.perssondennis.com/images/articles/perssons-pyramid-puzzle-level-5/perssons-pyramid-puzzle-level-5.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[I Created a Programming Puzzle Game]]></title>
            <link>https://www.perssondennis.com/articles/perssons-pyramid-puzzle-programming-game-release</link>
            <guid>https://www.perssondennis.com/articles/perssons-pyramid-puzzle-programming-game-release</guid>
            <pubDate>Sun, 23 Oct 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Persson's Pyramid Puzzle Programming Game is a hard programmer quiz for both beginners and expert programmers. Solve programming questions to pass the game.]]></description>
            <content:encoded><![CDATA[<p>Halloumi! I made a new puzzle game. It's a four-question pyramid quiz game. It's for all those brainiac unicorn developers who can't say no to a challenge.</p>
<p>If you aren't one of those, don't worry, there are puzzles of different experience levels. With this release today, there are four puzzles from beginner level to heroic level. You can <a href="https://www.perssondennis.com/games/perssons-pyramid">find all game levels here</a>, or maybe you want to skip directly to the heroic one, <a href="https://www.perssondennis.com/games/perssons-pyramid/4"><em>Turning coffee into bald hair</em></a>.</p>
<p><img src="https://www.perssondennis.com/images/articles/perssons-pyramid-puzzle-programming-game-release/turning-coffee-into-bald-hair.webp" alt="Turning coffee into bald hair">
<em>Developer (noun): a person turning coffee into bald hair</em></p>
<p>Are you a cheater? I'm no one to blame you, any method to solve the puzzles is allowed, googling is what we developers do!</p>
<p><img src="https://www.perssondennis.com/images/articles/perssons-pyramid-puzzle-programming-game-release/perssons-pyramid-game-question.webp" alt="Persson&#x27;s pyramid game question">
<em>Answer questions to reach the top of the pyramid</em></p>
<p>Cheater or not, let's look at the game. Each level consists of a pyramid. You can click on any of the numbered triangles in the pyramid to answer programming questions. The two topmost triangles are locked until you have solved the triangles below them. The goal is to unlock and find the answer to all four questions in the pyramid.</p>
<p><img src="https://www.perssondennis.com/images/articles/perssons-pyramid-puzzle-programming-game-release/persson-pyramid-game-unlocked.webp" alt="Persson&#x27;s pyramid game level unlocked">
<em>Solve the two bottom triangle puzzles to unlock the third triangle above</em></p>
<p>Let me know if the levels are too easy, I can make them harder. If they are too difficult, you can google harder. Let the game begin!</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Backend</category>
            <category>Jokes</category>
            <enclosure url="https://www.perssondennis.com/images/articles/perssons-pyramid-puzzle-programming-game-release/perssons-pyramid-puzzle-programming-game-release.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Professor Prolog Explains Serverless Hosting 2022]]></title>
            <link>https://www.perssondennis.com/articles/professor-prolog-explains-serverless-hosting-2022</link>
            <guid>https://www.perssondennis.com/articles/professor-prolog-explains-serverless-hosting-2022</guid>
            <pubDate>Sun, 19 Jun 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[What is meant by serverless? How to host serverless applications 2022? Professor Prolog explains serverless hosting and the difference between IaaS and PaaS.]]></description>
            <content:encoded><![CDATA[<p>Julia strikes the like button and bookmarks the web application tutorial she completed. She quickly scan the classroom and feels quite proud of being the only one who has finished yet. Eager to learn more she speaks up.</p>
<blockquote>
<p>👩‍🦰 Professor Prolog, could you tell me more about how to host a web application?</p>
</blockquote>
<p>Professor Prolog shines up and gets up from his chair.</p>
<blockquote>
<p>🧑‍🏫 Of course, Julia, I will tell you all about it.</p>
</blockquote>
<p>Prolog starts drawing boxes on the whiteboard, he knows every engineer loves lines and boxes.</p>
<blockquote>
<p>🧑‍🏫 First of all, remember that there's both a client and a server you need to host...</p>
</blockquote>
<p>One of the elder students, Ada, interrupts the professor.</p>
<blockquote>
<p>👱‍♀‍ But there are serverless applications today, aren't there?</p>
</blockquote>
<p><img src="https://www.perssondennis.com/images/articles/professor-prolog-explains-serverless-hosting-2022/serverless-grandma-meme.webp" alt="Serverless grandma meme">
<em>Grandma knows, she lived through the Y2K crisis</em></p>
<p>Prolog nods to Ada and starts over.</p>
<blockquote>
<p>🧑‍🏫 That's true, Ada. There are a lot of serverless applications today, but they aren't technically serverless. There are still people setting up the servers and hosting them on physical server halls around the world. They are only called serverless because you don't have to manage the physical machines on your own, you only need to provide the code you want them to run and take care of configurations.</p>
</blockquote>
<blockquote>
<p>👩‍🦰 Isn't that the same as hosting then, Julia asks. In our tutorial we uploaded our code to Firebase, is our application serverless then?</p>
</blockquote>
<p>Prolog hesitates and puts down the pen he held in his hand.</p>
<blockquote>
<p>🧑‍🏫 No Julia. Or yes... Kind of. But not exactly. What you did in the tutorial was to upload the javascript client application you built to Firebase's servers, so they can make it accessible on the internet. We usually refer to that process of serving it from a computer to the internet as hosting. Since you never uploaded it to a server of your own, you have technically hosted it serverless. But even if you uploaded it to your own server, we would still call it hosting, but we would instead say you have hosted it on-premises.</p>
</blockquote>
<blockquote>
<p>👩‍🦰 Oh, I see. I think I get it. And the server we hosted on AWS is serverless?</p>
</blockquote>
<p>Professor Prolog nods in agreement, grabs the pen again and starts writing on the whiteboard.</p>
<p>A student far back in the classroom, Jade, adjusts his glasses and squints because he can't see sharp.</p>
<blockquote>
<p>🧐 What does it say?</p>
</blockquote>
<blockquote>
<p>🧑‍🏫 Load balancing, it says load balancing.</p>
</blockquote>
<p><img src="https://www.perssondennis.com/images/articles/professor-prolog-explains-serverless-hosting-2022/load-balancer-meme.webp" alt="Load balancer meme">
<em>Not actual professor Prolog, but he does sit like that</em></p>
<p>Prolog draws multiple boxes on the whiteboard, each one of them representing a server. He draws a user as well and some lines in between them, all connected with another box labeled load balancer.</p>
<p><img src="https://www.perssondennis.com/images/articles/professor-prolog-explains-serverless-hosting-2022/load-balancer-drawing.webp" alt="Load balancer drawing">
<em>Prolog got a doctoral degree, maybe that is reflected in his drawings</em></p>
<p><img src="https://www.perssondennis.com/images/articles/professor-prolog-explains-serverless-hosting-2022/doctors-meme.webp" alt="Doctors meme">
<em>Yeap, he draws like he writes...</em></p>
<blockquote>
<p>🧑‍🏫 Does anyone know what a load balancer is, he asks.</p>
</blockquote>
<p>A student explains that load balancers are used to balance the workload between multiple servers when the server code runs on multiple servers.</p>
<p>Prolog nods quietly.</p>
<blockquote>
<p>🧑‍🏫 You see, there are different ways to host a serverless application. Two of the most common options are IaaS (Infrastructure as a Service) and PaaS (Platform as a Service). The latter one is what you used in the tutorial when you hosted the server on Elastic Beanstalk. The process was very much like hosting your React client on Firebase. There were a few extra things to consider, but in essence you simply uploaded code and it ran successfully. What happened under the hood was that Elastic Beanstalk automagically spun up a load balancer and a bunch of servers.</p>
</blockquote>
<blockquote>
<p>🧑‍🏫 One remark there, Prolog continues. When you configured Elastic Beanstalk, you also enabled something called <a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-sticky-sessions.html">sticky session</a>. Sticky session, or session affinity as it is called as well, ensures that when a user uses your client, all requests sent from that specific client to your server always will go to the same machine if the server are hosted on multiple machines. That is not always necessary, but in your case it was. You will need that kind of behavior if your server stores data in memory or on a local disk and you need to access that data on a subsequent network request. Forgetting to enable sticky session would result in inconsistent behavior for the server, since only requests sent to the machine that stored the data would be able to find it.</p>
</blockquote>
<p>A student suddenly sneezes loudly and wakes another one that has almost fallen asleep. Professor Prolog makes a pun about the student needing a cup of Java and sends away the students on a break.</p>
<p><img src="https://www.perssondennis.com/images/articles/professor-prolog-explains-serverless-hosting-2022/real-life-css-grandma-meme.webp" alt="Real-life css grandma meme">
<em>Grandma rendering some real-life CSS during break</em></p>
<p>Break is over. Students are back at their seats. Professor Prolog moves on to talk about load balancers and IaaS.</p>
<blockquote>
<p>🧑‍🏫 We were saying a PaaS automatically spins up a load balancer and some servers. When dealing with an IaaS, you have to do that work yourself. With an IaaS, you get machines you can use as servers. By putting an Nginx server or an AWS Load Balancer on one of the machines, and running the server code on the other servers, you have loosely spoken built what a PaaS does. What probably is missing is a system to automatically scale the number of servers you run. Although, exactly what a PaaS offers varies between different providers.</p>
</blockquote>
<p>Professor Prolog glimpses at the clock on the wall and erases his drawings on the whiteboard.</p>
<blockquote>
<p>🧑‍🏫 You have learned a lot about hosting web applications this hour. It's far from everything there is to know, but it's an accurate overview of some of the most common and fastest ways to host applications. If you are interested to read more about the differences between IaaS, PaaS, and SaaS, I have included a <a href="https://www.perssondennis.com/articles/iaas-vs-paas-vs-saas">link</a> in the lecture material. You can also read about <a href="https://www.perssondennis.com/articles/programming-explained-with-human-body">what it means to split a backend into microservices</a>.</p>
</blockquote>
<p>Professor Prolog animates his opacity and fades away...</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Architecture</category>
            <category>Backend</category>
            <enclosure url="https://www.perssondennis.com/assets/blog/default-article-image-unknown.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Programming Explained With the Human Body - Frontend, Microservices Backend and Testing]]></title>
            <link>https://www.perssondennis.com/articles/programming-explained-with-human-body</link>
            <guid>https://www.perssondennis.com/articles/programming-explained-with-human-body</guid>
            <pubDate>Sun, 03 Apr 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[What is the difference between frontend and backend? Programming terminology like microservices and testing explained like I'm five with the human body.]]></description>
            <content:encoded><![CDATA[<p>You have gotten the question a million times, haven't you? What is the difference between frontend and backend? What do you answer? "Frontend is what you see and backend is what you don't see?". Kind of a boring answer, isn't it? After reading this article you will have a better explanation to shine with. And even grandma will know what you are talking about!</p>
<h2>Is Backend the Brain or the Heart?</h2>
<p>Everything starts with the brain or the heart, doesn't it? Our two most beloved organs. Yeah, I said two, you will have to visit some other site to read about the third and fourth organs.</p>
<p>Which of the brain and heart would compare to the term "backend"? Can you guess it?</p>
<p><img src="https://www.perssondennis.com/images/articles/programming-explained-with-human-body/empty-space.webp" alt="Empty space">
<em>I've just added some empty space here so I don't spoil the answer (photo: <a href="https://unsplash.com/photos/YvRTYzkT6Hs">Gary Scott</a>)</em></p>
<p>If you answered the brain, you were right. If your answer was the heart, you were right as well. Backend would actually be all the inner organs in the body. Backend is the brain. Backend is the heart. Backend also includes the useless little appendix that probably once had a purpose, but nobody no longer knows why it's there and nobody cares to remove it as long as it doesn't pose any problem.</p>
<p>Well, that's a sentence I never thought I would write. Maybe that's how all those <a href="https://www.searchenginepeople.com/blog/google-autocomplete-fails.html">weird Google autocompletes</a> comes up?</p>
<p><img src="https://www.perssondennis.com/images/articles/programming-explained-with-human-body/google-search-why-is-backend-appendix.webp" alt="Google search autocomplete for backend is">
<em>That's a weird suggestion... Is it for real?</em></p>
<p>(Yeah, that's how google.com looks like for me, <a href="https://dev.to/perssondennis/theming-any-site-you-don-t-own-2ogb">this is how I styled it</a>)</p>
<h2>Backend Microservices</h2>
<p>Back on track, I said backend could be compared to all inner organs, not just the brain. When building web services today, backend is often split into <a href="https://aws.amazon.com/microservices/">microservices</a>. Each microservice has its own responsibility, it serves one functionality and then communicating with other services through a network. That network would be our nervous system when speaking about the body and the services would be organs.</p>
<p>Together, all microservices in an application work together to keep the application up and running just as all organs in the body work together to keep you alive. Some organs in the body are vital and can't be removed, like the brain. Other organs are less important and can be substituted, like the stomach. The body will continue to function without them although you may have to patch the body a bit to make it work. Other organs, such as the kidney, are organs we can't easily live without but we have multiple copies of. If we lose one, we can still continue to live on with the other one.</p>
<p>A microservice backend works in the same way. Some services can't be removed while other can, even if the application may not be of perfect use. Parts of it could be running while some certain functionalities could malfunction, e.g., a chatbot. That's one of the key advantages of microservices, to keep the application running even when individual services go down.</p>
<p>Another way to ensure that a service is running is to scale it. Scaling an application means to either run it on more powerful machines (scaling vertically) or letting the application run on more than one machine (scaling horizontally). With microservices, we can scale each service individually. If the chatbot would be very important for our application, we could run it on two or more machines while other services can continue to run on one machine. Just like the body has two kidneys and only one nose. The nose is less important, you will look a bit peculiar if you lose it, but we can live like that.</p>
<p><img src="https://www.perssondennis.com/images/articles/programming-explained-with-human-body/voldemort.webp" alt="Voldemort nose meme">
<em>I intentionally avoided mentioning anyone by name...</em></p>
<h2>Frontend Is the Beauty and the Feel</h2>
<p>Obviously, frontend is what you see. Your face, your muscles and your way of walking. But it's also all of your external organs. Your ears would be speech recognition, see <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API">Web Speech API</a>. You have a mouth that outputs audio and eyes that work like a camera. When you click on a button on a web page it will notice it, just as you feel when someone presses your skin.</p>
<p><img src="https://www.perssondennis.com/images/articles/programming-explained-with-human-body/tom-and-jerry-as-developers.webp" alt="Tom and Jerry developers meme">
<em>Was Tom &#x26; Jerry the first cartoon developers?</em></p>
<h2>Testing Is for Doctors</h2>
<p>Testing is what doctors do. Human doctors can examine specific organs or diagnose illnesses that affect the complete or parts of the body. The difference between unit and integration testing would be that unit testing tests individual organs while integration testing searches for diseases affecting the whole body or integrations between body parts. An example of the latter one could be an autoimmune disease where a person's immune system mistakenly attacks other parts of the body.</p>
<p>If doctors would have used the same terminology as developers do, doctors could have been divided into frontend, backend and full stack doctors dependent on what they did. Examinate skin problems would be frontend investigations and listening to a patient's heartbeat would be to monitor backend functionality. Figuratively speaking, "unit testing backend code" could be translated to "diagnosing inner organs".</p>
<p><img src="https://www.perssondennis.com/images/articles/programming-explained-with-human-body/backend-doctor-meme.webp" alt="Backend doctor meme">
<em>In the world of web development, doctors could be either frontend or backend doctors dependent on their specialties</em></p>
<h2>The Soul</h2>
<p>What about the soul? Isn't a part of body, or is it? Does it really exist? I know what my view on it is, but let's leave it there. You can have fun figuring about that one one your own.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Backend</category>
            <category>Frontend</category>
            <category>Testing</category>
            <enclosure url="https://www.perssondennis.com/images/articles/programming-explained-with-human-body/programming-human-body-header2.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[React Anti-Patterns and Best Practices - Do's and Don'ts]]></title>
            <link>https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts</link>
            <guid>https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts</guid>
            <pubDate>Sun, 05 Feb 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Do's and don'ts for React developers. 17 anti-patterns and best practices to follow in React with useful tips for both new and experienced React developers.]]></description>
            <content:encoded><![CDATA[<p>React may seem to be one of the least opinionated frameworks in the Wild West Web. Despite that, there's a lot of mistakes you can do and even more things you can do to write clean and readable code. This article explains 17 common anti-patterns and best practices in React.</p>
<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#use-usestate-instead-of-variables">Use useState Instead of Variables</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#declare-css-outside-components">Declare CSS Outside Components</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#use-usecallback-to-prevent-function-recreations">Use useCallback To Prevent Function Recreations</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#use-usecallback-to-prevent-dependency-changes">Use useCallback To Prevent Dependency Changes</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#use-usecallback-to-prevent-useeffect-triggers">Use useCallback To Prevent useEffect Triggers</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#add-an-empty-dependency-list-to-useeffect-when-no-dependencies-are-required">Add an Empty Dependency List to useEffect When No Dependencies Are Required</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#always-add-all-dependencies-to-useeffects-and-other-react-hooks">Always Add All Dependencies to useEffects and Other React Hooks</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#do-not-use-useeffect-to-initiate-external-code">Do Not Use useEffect To Initiate External Code</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#do-not-wrap-external-functions-in-a-usecallback">Do Not Wrap External Functions in a useCallback</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#do-not-use-usememo-with-empty-dependency-list">Do Not Use useMemo With Empty Dependency List</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#do-not-declare-components-within-other-components">Do Not Declare Components Within Other Components</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#do-not-use-hooks-in-if-statements-no-conditional-hooks">Do Not Use Hooks in If Statements (No Conditional Hooks)</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#do-not-use-hooks-after-return-no-conditional-hooks">Do Not Use Hooks After Return (No Conditional Hooks)</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#let-child-components-decide-if-they-should-render">Let Child Components Decide if They Should Render</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#use-usereducer-instead-of-multiple-usestate">Use useReducer Instead of Multiple useState</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#write-initial-states-as-functions-rather-than-objects">Write Initial States as Functions Rather Than Objects</a></li>
<li><a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#use-useref-instead-of-usestate-when-a-component-should-not-rerender">Use useRef Instead of useState When a Component Should Not Rerender</a></li>
</ol>
<h2>Use useState Instead of Variables</h2>
<p>This first one should be a basic one, but I still see developers doing this, sometimes even seniors. To store a state in React you should always use one of the React hooks, like useState or useReducer. Never declare the state directly as a variable in a component. Doing so will redeclare the variable on every render which means that React cannot memoize things it normally memoizes.</p>
<pre><code class="language-javascript">import AnotherComponent from 'components/AnotherComponent'

const Component = () => {
  // Don't do this.
  const value = { someKey: 'someValue' }

  return &#x3C;AnotherComponent value={value} />
}
</code></pre>
<p>In the case above, AnotherComponent and everything that depends on <em>value</em> will rerender on every render, even if they are memoized with memo, useMemo or useCallback.</p>
<p>If you would add a useEffect to your component with <em>value</em> as a dependency, it would trigger on every render. The reason for that is that the JavaScript reference for <em>value</em> will be different on every render.</p>
<p>By using React's useState, React will keep the same reference for <em>value</em> all until you update it with <em>setValue</em>. React will then be able to detect when to and when not to trigger effects and recalculate memoizations.</p>
<pre><code class="language-javascript">import { useState } from 'react'
import AnotherComponent from 'components/AnotherComponent'

const Component = () => {
  // Do this instead.
  const [value, setValue] = useState({ someKey: 'someValue' })

  return &#x3C;AnotherComponent value={value} />
}
</code></pre>
<p>If you only need a state that is initiated once, and then never updated, then declare the variable outside the component. When doing that, the JavaScript reference will never change.</p>
<pre><code class="language-javascript">// Do this if you never need to update the value.
const value = { someKey: 'someValue' }

const Component = () => {
  return &#x3C;AnotherComponent value={value} />
}
</code></pre>
<h2>Declare CSS Outside Components</h2>
<p>If you are using a CSS in JS solution, avoid declaring CSS within components.</p>
<pre><code class="language-javascript">import makeCss from 'some/css/in/js/library'

const Component = () => {
  // Don't do this.
  return &#x3C;div className={makeCss({ background: red, width: 100% })} />
}
</code></pre>
<p>The reason why not to do it is because the object has to be recreated on every render. Instead, lift it out of the component.</p>
<pre><code class="language-javascript">import cssLibrary from 'some/css/in/js/library'

// Do this instead.
const someCssClass = makeCss({
  background: red,
  width: 100%
})

const Component = () => {
  return &#x3C;div className={someCssClass} />
}
</code></pre>
<h2>Use useCallback To Prevent Function Recreations</h2>
<p>Whenever a functional React component is rerendered, it will recreate all normal functions in the component. React provided a useCallback hook that can be used to avoid that. useCallback will keep the old instance of the function between renders as long as its dependencies doesn't change.</p>
<pre><code class="language-javascript">import { useCallback } from 'react'

const Component = () => {
  const [value, setValue] = useState(false)

  // This function will be recreated on each render.
  const handleClick = () => {
    setValue(true)
  }

  return &#x3C;button onClick={handleClick}>Click me&#x3C;/button>
}
</code></pre>
<pre><code class="language-javascript">import { useCallback } from 'react'

const Component = () => {
  const [value, setValue] = useState(false)

  // This function will only be recreated when the variable value updates.
  const handleClick = useCallback(() => {
    setValue(true)
  }, [value])

  return &#x3C;button onClick={handleClick}>Click me&#x3C;/button>
}
</code></pre>
<p>This time, I won't say do this or do that. Some people would tell you to optimize each function with a useCallback hook, but I won't. For small functions like the one in the example, I can't assure it really is better to wrap the function in useCallback.</p>
<p>Under the hood, React will have to check dependencies on every render to know if a new function needs to be created or not, and sometimes the dependencies changes frequently anyways. The optmization useCallback gives might therefore not always be needed.</p>
<p>If the dependencies to the function doesn't update a lot though, useCallback can be a good optimization to avoid recreating the function on each render.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-anti-patterns-and-best-practices-dos-and-donts/another-js-framework-meme.webp" alt="Another js framework meme">
<em>Is React difficult? Join this dude creating another js framework!</em></p>
<h2>Use useCallback To Prevent Dependency Changes</h2>
<p>While useCallback can be used to avoid function instantiations, it can also be used for something even more important. Since useCallback keeps the same memory reference for the wrapped function between renders, it can be used to optimize usages of other useCallbacks and memoizations.</p>
<pre><code class="language-javascript">import { memo, useCallback, useMemo } from 'react'

const MemoizedChildComponent = memo({ onTriggerFn }) => {
  // Some component code...
}

const Component = ({ someProp }) => {
  // Reference to onTrigger function will only change when someProp does.
  const onTrigger = useCallback(() => {
    // Some code...
  }, [someProp])

  // This memoized value will only update when onTrigger function updates.
  // The value would be recalculated on every render if onTrigger wasn't wrapper in useCallback.
  const memoizedValue = useMemo(() => {
    // Some code...
  }, [onTrigger])

  // MemoizedChildComponent will only rerender when onTrigger function updates.
  // If onTrigger wasn't wrapped in a useCallback, MemoizedChildComponent would rerender every time this component renders.
  return (&#x3C;>
    &#x3C;MemoizedChildComponent onTriggerFn={onTrigger} />
    &#x3C;button onClick={onTrigger}>Click me&#x3C;/button>
   &#x3C;/>)
}
</code></pre>
<h2>Use useCallback To Prevent useEffect Triggers</h2>
<p>The previous example showed how to optimize renders with help of useCallback, in the same way, it is also possible to avoid unnecessary useEffect triggers.</p>
<pre><code class="language-javascript">import { useCallback, useEffect } from 'react'

const Component = ({ someProp }) => {
  // Reference to onTrigger function will only change when someProp does.
  const onTrigger = useCallback(() => {
    // Some code...
  }, [someProp])

  // useEffect will only run when onTrigger function updates.
  // If onTrigger wasn't wrapped in a useCallback, useEffect would run every time this function renders.
  useEffect(() => {
    // Some code...
  }, [onTrigger])

  return &#x3C;button onClick={onTrigger}>Click me&#x3C;/button>
}
</code></pre>
<h2>Add an Empty Dependency List to useEffect When No Dependencies Are Required</h2>
<p>If you have an effect which isn't dependent on any variables, make sure to an empty dependency list as the second argument to useEffect. If you don't do that, the effect will run on every render.</p>
<pre><code class="language-javascript">import { useEffect } from 'react'

const Component = () => {
  useEffect(() => {
    // Some code.

    // Do not do this.
  })

  return &#x3C;div>Example&#x3C;/div>
}
</code></pre>
<pre><code class="language-javascript">import { useEffect } from 'react'

const Component = () => {
  useEffect(() => {
    // Some code.

    // Do this.
  }, [])

  return &#x3C;div>Example&#x3C;/div>
}
</code></pre>
<p>The same logic applies to other React hooks, such as useCallback and useMemo. Although, as described later in this article, you may not need to use those hooks at all if you don't have any dependencies.</p>
<h2>Always Add All Dependencies to useEffects and Other React Hooks</h2>
<p>When dealing with dependency lists for built-in React hooks, such as useEffects and useCallback, make sure to always add all dependencies to the dependency list (second argument of the hooks). When a dependency is omitted, the effect or callback may use an old value of it which often results in bugs which can be hard to detect.</p>
<p>Adding all variables may be a very tricky thing to do, sometimes you simply don't want an effect to run again if a value updates, but trying to find a solution for it will not only save you from bugs, it usually leads to better written code as well.</p>
<p>Even more important, if you leave out a dependency to prevent a bug, <strong>that bug will come back for you</strong> when upgrading to newer React versions. In strict mode in React 18, updating hooks (e.g. useEffect, useMemo) are triggered twice in development, and that may happen in production in future React versions.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-anti-patterns-and-best-practices-dos-and-donts/revengeful-bug.webp" alt="Revengeful bug">
<em>Better add all dependencies to react hooks to be on the safe side</em></p>
<pre><code class="language-javascript">import { useEffect } from 'react'

const Component = () => {
  const [value, setValue] = useState()

  useEffect(() => {
    // Some code using value variable.

    // Don't neglect adding variables to dependency list.
    // The value variable should be added here.
  }, [])

  return &#x3C;div>{value}&#x3C;/div>
}
</code></pre>
<p>You may wonder, how can you circumvent side effects when useEffects are triggered more times than you wish? Unfortunately, there isn't a one-for-all solution to that. Different scenarios requires different solutions. You can try to use <a href="https://www.perssondennis.com/articles/react-hook-use-run-once">hooks to only run code once</a>, that can sometimes be useful, but it isn't a solution to recommend really.</p>
<p>Most often you can solve your problem using if-cases. You can look at the current state and logically decide whether or not you really need to run the code. For example, if your reason not to add the variable <em>value</em> as a dependency to the effect above was to only run the code when <em>value</em> is undefined, you can simply add an if-statement inside the effect.</p>
<pre><code class="language-javascript">import { useEffect } from 'react'

const Component = () => {
  const [value, setValue] = useState()

  useEffect(() => {
    if (!value) {
      // Some code to run when value isn't set.
    }

  // Do this, always add all dependencies.
  }, [value])

  return &#x3C;div>{value}&#x3C;/div>
}
</code></pre>
<p>Other scenarios may be more complex, maybe it isn't very feasible to use if-statements to prevent effects from happening multiple times. And if it isn't easily done, you should avoid it to avoid bugs. When that's the case, you should first ask yourself, do you really need an effect? There are a lot of cases where developers use effect when they really shouldn't do that.</p>
<p>However, life is not trivial, let's say you really do need to use useEffect, and you don't manage to easily solve it with if-cases. What else options do you have? Actually, the easy way is potentially the best way in this case, just to add all dependencies and let the effect run more times than you want it to.</p>
<p>Instead of trying to prevent code from being executing you can write the code so it doesn't matter if it is called multiple times or not. Such code is called to be <a href="https://stackoverflow.com/a/1077421/7584643">idempotent</a>, and suits very well with functional programming. Such behavior can be achieved by using caches, <a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function">throttles and debounce functions</a>. I may write and article explaining this topic in detail in the future, but for now, I will leave it here.</p>
<h2>Do Not Use useEffect To Initiate External Code</h2>
<p>Let say you want to run some code to initialize a library. Plenty of times I have seen initializion code like that being placed in an useEffect with an empty dependency list, which is completely unnecessary and error prone. If the function you call isn't dependent on a component's internal state, it should be initialized outside the component.</p>
<pre><code class="language-javascript">import { useEffect } from 'react'
import initLibrary from '/libraries/initLibrary'

const Component = () => {
  // Do not do this.
  useEffect(() => {
    initLibrary()
  }, [])

  return &#x3C;div>Example&#x3C;/div>
}
</code></pre>
<pre><code class="language-javascript">import initLibrary from '/libraries/initLibrary'

// Do this instead.
initLibrary()

const Component = () => {
  return &#x3C;div>Example&#x3C;/div>
}
</code></pre>
<p>If the component's internal state is needed for the initialization, you can put it in an useEffect, but if you are doing that, make sure you are adding all the dependencies you use to the dependency list of useEffect, as described under the previous heading.</p>
<h2>Do Not Wrap External Functions in a useCallback</h2>
<p>Just like in the case with triggering init functions in a useEffect above, you don't need a useCallback to call an external function. Simply just invoke the external function as is. This saves React from having to check if the useCallback needs to be recreated or not, and it makes the code briefer.</p>
<pre><code class="language-javascript">import { useCallback } from 'react'
import externalFunction from '/services/externalFunction'

const Component = () => {
  // Do not do this.
  const handleClick = useCallback(() => {
    externalFunction()
  }, [])

  return &#x3C;button onClick={handleClick}>Click me&#x3C;/button>
}
</code></pre>
<pre><code class="language-javascript">import externalFunction from '/services/externalFunction'

const Component = () => {
  // Do this instead.
  return &#x3C;button onClick={externalFunction}>Click me&#x3C;/button>
}
</code></pre>
<p>Valid use cases for using a useCallback are when the callback calls multiple functions or when it reads or updates an internal state, such as a value from useState hook or one of the components passed-in props.</p>
<pre><code class="language-javascript">import { useCallback } from 'react'
import { externalFunction, anotherExternalFunction } from '/services'

const Component = ({ passedInProp }) => {
  const [value, setValue] = useState()

  // This is okay...
  const handleClick = useCallback(() => {
    // ...because we call multiple functions.
    externalFunction()
    anotherExternalFunction()

    // ...because we read and/or set an internal value or prop.
    setValue(passedInProp)
  }, [passedInProp, value])

  return &#x3C;button onClick={handleClick}>Click me&#x3C;/button>
}
</code></pre>
<h2>Do Not Use useMemo With Empty Dependency List</h2>
<p>If you ever add a useMemo with an empty dependency list, ask yourself why you are doing so.</p>
<p>Is it because it is dependent on a component's state variable and you don't want to add it? In that case, we have already discussed that, you should always list all dependency variables!</p>
<p>Is it because the useMemo doesn't really have any dependencies? Well, then just lift it out of the component, it doesn't belong in there!</p>
<pre><code class="language-javascript">import { useMemo } from 'react'

const Component = () => {
  // Do not do this.
  const memoizedValue = useMemo(() => {
    return 3 + 5
  }, [])

  return &#x3C;div>{memoizedValue}&#x3C;/div>
}
</code></pre>
<pre><code class="language-javascript">// Do this instead.
const memoizedValue = 3 + 5

const Component = () => {
  return &#x3C;div>{memoizedValue}&#x3C;/div>
}
</code></pre>
<h2>Do Not Declare Components Within Other Components</h2>
<p>I see this a lot, please stop doing it already.</p>
<pre><code class="language-javascript">const Component = () => {

  // Don't do this.
  const ChildComponent = () => {
    return &#x3C;div>I'm a child component&#x3C;/div>
  }

  return &#x3C;div>&#x3C;ChildComponent />&#x3C;/div>
}
</code></pre>
<p>What is the problem with it? The problem is that you are misusing React. As discussed before, variables declared within a component will be redeclared every time the component renders. In this case, it means that the functional child component has to be recreated every time the parent rerenders.</p>
<p>This is problematic for multiple reasons.</p>
<ol>
<li>A function will have to be instantiated on every render.</li>
<li>React won't be able to decide when to do any kind of component optimizations.</li>
<li>If hooks are used in ChildComponent, they will be reinitiated on every render.</li>
<li>The component's lines of code increases and it gets hard to read. I have seen files with tens or maybe twenties of these child components within a single React component!</li>
</ol>
<p>What to do instead? Merely declare the child component outside the parent component.</p>
<pre><code class="language-javascript">// Do this instead.
const ChildComponent = () => {
    return &#x3C;div>I'm a child component&#x3C;/div>
}

const Component = () => {
  return &#x3C;div>&#x3C;ChildComponent />&#x3C;/div>
}
</code></pre>
<p>Or even better, in a separate file.</p>
<pre><code class="language-javascript">// Do this instead.
import ChildComponent from 'components/ChildComponent'

const Component = () => {
  return &#x3C;div>&#x3C;ChildComponent />&#x3C;/div>
}
</code></pre>
<p><img src="https://www.perssondennis.com/images/articles/react-anti-patterns-and-best-practices-dos-and-donts/unstable-build-meme.webp" alt="Unstable build meme">
<em>Remember, I write this article for a reason</em></p>
<h2>Do Not Use Hooks in If Statements (No Conditional Hooks)</h2>
<p>This one is explained in <a href="https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level">React's Documentation</a>. One should never write conditional hooks, simply as that.</p>
<pre><code class="language-javascript">import { useState } from 'react'

const Component = ({ propValue }) => {
  if (!propValue) {
    // Don't do this.
    const [value, setValue] = useState(propValue)
  }

  return &#x3C;div>{value}&#x3C;/div>
}
</code></pre>
<h2>Do Not Use Hooks After Return (No Conditional Hooks)</h2>
<p>If statements are conditional by definition, it's therefore easy to understand that you shouldn't place hooks within them when reading <a href="https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level">React's Documentation</a>.</p>
<p>A little more sneaky keyword is the "return" keyword. Many people don't realize "return" can result in conditional hook renders. Look at this example.</p>
<pre><code class="language-javascript">import { useState } from 'react'

const Component = ({ propValue }) => {

  if (!propValue) {
    return null
  }

  // This hook is conditional, since it will only be called if propValue exists.
  const [value, setValue] = useState(propValue)

  return &#x3C;div>{value}&#x3C;/div>
}
</code></pre>
<p>As you can see, a conditional return statement will make a succeeding hook conditional. To avoid this, put all your hooks above the component's first conditional rendering. Or, easier to remember, simply always put you hooks at the top of the component.</p>
<pre><code class="language-javascript">import { useState } from 'react'

const Component = ({ propValue }) => {
  // Do this instead, place hooks before conditional renderings.
  const [value, setValue] = useState(propValue)

  if (!propValue) {
    return null
  }

  return &#x3C;div>{value}&#x3C;/div>
}
</code></pre>
<h2>Let Child Components Decide if They Should Render</h2>
<p>This one isn't something you always should do, but in many situations it's appropriate. Let's consider the following code.</p>
<pre><code class="language-javascript">import { useState } from 'react'

const ChildComponent = ({ shouldRender }) => {
  return &#x3C;div>Rendered: {shouldRender}&#x3C;/div>
}

const Component = () => {
  const [shouldRender, setShouldRender] = useState(false)

  return &#x3C;>
    { !!shouldRender &#x26;&#x26; &#x3C;ChildComponent shouldRender={shouldRender} /> }
  &#x3C;/>
}
</code></pre>
<p>Above is a common way to conditionally render a child component. The code is fine, apart from being a bit verbose when there are many child components. But dependent on what ChildComponent does, there may exist a better solution. Let's rewrite the code slightly.</p>
<pre><code class="language-javascript">import { useState } from 'react'

const ChildComponent = ({ shouldRender }) => {

  if (!shouldRender) {
    return null
  }

  return &#x3C;div>Rendered: {shouldRender}&#x3C;/div>
}

const Component = () => {
  const [shouldRender, setShouldRender] = useState(false)

  return &#x3C;ChildComponent shouldRender={shouldRender} />
}
</code></pre>
<p>In the example above, we have rewritten the two component's to move the conditional rendering into the child component. You may wonder, what's the benefit of moving conditional rendering into the child component?</p>
<p>The biggest benefit is that React can continue rendering ChildComponent even when it isn't visible. That means, ChildComponent can keep its state when it is hidden and then later getting rendered a second time without losing its state. It's always there, just not visible.</p>
<p>If the component instead would stop rendering, as it does with the first code, states saved in useState would be reset, and useEffects, useCallbacks and useMemos would all need to rerun and recalculate new values as soon as the component renders again.</p>
<p>If your code would trigger some network requests or doing some heavy calculations, those would also run when the component is rendered again. Likewise, if you would have some form data stored in the component's internal state, that would reset every time the component goes hidden.</p>
<p>As initially mentioned, this isn't something you always want to do. Sometimes you really want the component to unmount completely. For example, if you have a useEffect within the child component, you may not want to continue running it on rerenders. See the example below.</p>
<pre><code class="language-javascript">const ChildComponent = ({ shouldRender, someOtherPropThatChanges }) => {

  useEffect(() => {
    // If we don't want this code to run when shouldRender is false,
    // then don't keep render this component when shouldRender is false.
  }, [someOtherPropThatChanges])

  if (!shouldRender) {
    return null
  }

  return &#x3C;div>Rendered: {shouldRender}&#x3C;/div>
}

const Component = () => {
  const [shouldRender, setShouldRender] = useState(false)

  return &#x3C;ChildComponent
    shouldRender={shouldRender}
    someOtherPropThatChanges={someOtherPropThatChanges} />
}
</code></pre>
<p>We could of course use conditional logic inside the child component to make the code above to work, but that could be error-prone. And please recall, conditional hooks aren't allowed, so you cannot place the useEffect after the if statement.</p>
<pre><code class="language-javascript">const ChildComponent = ({ shouldRender, someOtherPropThatChanges }) => {

  if (!shouldRender) {
    return null
  }

  useEffect(() => {
    // We cannot avoid running this useEffect by putting it after the
    // null-render. Conditional hook rendering is not allowed in React!
  }, [someOtherPropThatChanges])

  return &#x3C;div>Rendered: {shouldRender}&#x3C;/div>
}

const Component = () => {
  const [shouldRender, setShouldRender] = useState(false)

  return &#x3C;ChildComponent
    shouldRender={shouldRender}
    someOtherPropThatChanges={someOtherPropThatChanges} />
}
</code></pre>
<h2>Use useReducer Instead of Multiple useState</h2>
<p>Instead of bloating the component with multiple useState, you can use one useReducer instead. It may be cumbersome to write, but it will both avoid unnecessary renders and can make the logic more understandable. Once you have a useReducer, it will be much easier to add new logic and states to your component.</p>
<p>There's no magical number of how many useState to write before refactoring to useReducer, but I would personally say around three.</p>
<pre><code class="language-javascript">import { useState } from 'react'

const Component = () => {
  // Do not add a lot of useState.
  const [text, setText] = useState(false)
  const [error, setError] = useState('')
  const [touched, setTouched] = useState(false)

  const handleChange = (event) => {
    const value = event.target.value
    setText(value)

    if (value.length &#x3C; 6) {
      setError('Too short')
    } else {
      setError('')
    }
  }

  return &#x3C;>
    {!touched &#x26;&#x26; &#x3C;div>Write something...&#x3C;/div> }
    &#x3C;input type="text" value={text} onChange={handleChange} />
    &#x3C;div>Error: {error}&#x3C;/div>
  &#x3C;/>
}
</code></pre>
<pre><code class="language-javascript">import { useReducers } from 'react'

const UPDATE_TEXT_ACTION = 'UPDATE_TEXT_ACTION'
const RESET_FORM = 'RESET_FORM'

const getInitialFormState = () => ({
  text: '',
  error: '',
  touched: false
})

const formReducer = (state, action) => {
  const { data, type } = action || {}

  switch (type) {
    case UPDATE_TEXT_ACTION:
      const text = data?.text ?? ''

      return {
        ...state,
        text: text,
        error: text.length &#x3C; 6,
        touched: true
      }
    case RESET_FORM:
      return getInitialFormState()
    default:
      return state
  }
}

const Component = () => {
  const [state, dispatch] = useReducer(formReducer, getInitialFormState());
  const { text, error, touched } = state

  const handleChange = (event) => {
    const value = event.target.value
    dispatch({ type: UPDATE_TEXT_ACTION, text: value})
  }

  return &#x3C;>
    {!touched &#x26;&#x26; &#x3C;div>Write something...&#x3C;/div> }
    &#x3C;input type="text" value={text} onChange={handleChange} />
    &#x3C;div>Error: {error}&#x3C;/div>
  &#x3C;/>
}
</code></pre>
<p><img src="https://www.perssondennis.com/images/articles/react-anti-patterns-and-best-practices-dos-and-donts/typescript-meme.webp" alt="Typescript meme">
<em>Need even more structure, consider using TypeScript!</em></p>
<h2>Write Initial States as Functions Rather Than Objects</h2>
<p>Note the code from the current tip. Look at getInitialFormState function.</p>
<pre><code class="language-javascript">// Code removed for brevity.

// Initial state is a function here.
const getInitialFormState = () => ({
  text: '',
  error: '',
  touched: false
})

const formReducer = (state, action) => {
  // Code removed for brevity.
}

const Component = () => {
  const [state, dispatch] = useReducer(formReducer, getInitialFormState());
  // Code removed for brevity.
}
</code></pre>
<p>See that I wrote the initial state as a function. I could rather have used an object directly.</p>
<pre><code class="language-javascript">// Code removed for brevity.

// Initial state is an object here.
const initialFormState = {
  text: '',
  error: '',
  touched: false
}

const formReducer = (state, action) => {
  // Code removed for brevity.
}

const Component = () => {
  const [state, dispatch] = useReducer(formReducer, initialFormState);
  // Code removed for brevity.
}
</code></pre>
<p>Why didn't I do that? The answer is simple, to avoid mutability. In the case above, when initialFormState is an object, we could happen to mutate the object somewhere in our code.</p>
<p>If that's the case, we wouldn't get the initial state back if we used the variable another time, for example when resetting the form. We would instead get the mutated object where for example <em>touched</em> could have a value of true.</p>
<p>That is also the case when running unit tests. When testing the code above, several tests could use the initialFormState and mutate it. Each test would then work when they run individually, while some of the tests would likely fail when all tests ran together in a test suite.</p>
<p>For that reason, it's a good practice to turn initial states into getter functions that returns the initial state object. Or even better, use libraries like <a href="https://immerjs.github.io/immer/">Immer</a> which is used to avoid writing mutable code.</p>
<h2>Use useRef Instead of useState When a Component Should Not Rerender</h2>
<p>Did you know you can optimize component renderings by replacing useState with useRef? Check this code.</p>
<pre><code class="language-javascript">import { useEffect } from 'react'

const Component = () => {
  const [triggered, setTriggered] = useState(false)

  useEffect(() => {
    if (!triggered) {
      setTriggered(true)

      // Some code to run here...
    }
  }, [triggered])
}
</code></pre>
<p>When you run the code above, the component will rerender when setTriggered is invoked. In this case, triggered state variable could be a way to make sure that the effect only runs one time (which actually doesn't work in React 18, learn why in <a href="https://www.perssondennis.com/articles/react-hook-use-run-once">this article about useRunOnce hook</a>).</p>
<p>Since the only use of triggered variable in this case, is to keep track if a function has been triggered or not, we do not need the component to render any new state. We can therefore replace useState with useRef, which won't trigger the component to rerender when it is updated.</p>
<pre><code class="language-javascript">import { useRef } from 'react'

const Component = () => {
  // Do this instead.
  const triggeredRef = useRef(false)

  useEffect(() => {
    if (!triggeredRef.current) {
      triggeredRef.current = true

      // Some code to run here...
    }

  // Note missing dependency. This isn't optimal.
  }, [])
}
</code></pre>
<p>Note the missing dependency to the useEffect, that one is a bit tricker to fix when using useRef, but React explains it in their <a href="https://reactjs.org/docs/refs-and-the-dom.html#callback-refs">documentation</a>.</p>
<p>In the case above, you may wonder why we need to use a useRef at all. Why can't we simply use a variable outside of the component?</p>
<pre><code class="language-javascript">// This does not work the same way!
const triggered = false

const Component = () => {
  useEffect(() => {
    if (!triggered) {
      triggered = true

      // Some code to run here...
    }
  }, [])
}
</code></pre>
<p>The reason we need a useRef is because the above code doesn't work in the same way! The above <em>triggered</em> variable will only be false once. If the component unmounts, the variable triggered will still be set to true when the component mounts again, because the triggered variable is not bound to React's life cycle.</p>
<p>When useRef is used, React will reset its value when a component unmounts and mounts again. In this case, we probably would want to uses useRef, but in other cases a variable outside the component may be what we are searching for.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>JavaScript</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/react-anti-patterns-and-best-practices-dos-and-donts/react-anti-patterns-and-best-practices-dos-and-donts.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[React Hook: useElementDimensions]]></title>
            <link>https://www.perssondennis.com/articles/react-hook-use-element-dimensions</link>
            <guid>https://www.perssondennis.com/articles/react-hook-use-element-dimensions</guid>
            <pubDate>Sun, 03 Dec 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[React hook useElementDimensions measures height, width and position of a node or element. It updates the dimensions on resize and scroll events.]]></description>
            <content:encoded><![CDATA[<p>CSS is great, but sometimes it is not enough. Sometimes you need to know the size of CSS elements in the JavaScript code, or to know where it is on the screen. In that case the useElementDimensions is perfect hook to use. This article describes what the hook is, how to implement it and shows some use cases of it.</p>
<p>Actually, we will look at two hooks in this article, both useStaticElementDimensions and useElementDimensions. We will start with the static hook, which has limited use cases but serves as a good example of why we need the more advanced hook.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-element-dimensions#usestaticelementdimensions-hook">useStaticElementDimensions Hook</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-element-dimensions#useelementdimensions-hook">useElementDimensions Hook</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-element-dimensions#cautions-and-improvements">Cautions and Improvements</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-element-dimensions#use-cases">Use Cases</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-element-dimensions#example-usage">Example Usage</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-element-dimensions#summary">Summary</a></li>
</ul>
<h2>useStaticElementDimensions Hook</h2>
<p>Below you can see a JavaScript implementation of a useStaticElementDimensions hook. The hook is also available to test at <a href="https://codesandbox.io/p/sandbox/useelementdimensions-h8kvp9?file=%2Fsrc%2FuseStaticElementDimensions.tsx%3A7%2C14">CodeSandbox</a>. The example on CodeSandbox is written in TypeScript, so if you're using it in a TypeScript project you should head over there, or get it from <a href="https://github.com/PerssonDennis/examples/blob/main/useElementDimensions/src/useStaticElementDimensions.tsx">GitHub</a>.</p>
<pre><code class="language-javascript">import { useCallback, useState } from 'react'

const useStaticElementDimensions = () => {
  const [dimensions, setDimensions] = useState(null)

  const ref = useCallback((node) => {
    if (!!node) {
      const domRect = node.getBoundingClientRect()
      setDimensions(domRectToDimensions(domRect))
    }
  }, [])

  return { dimensions, ref }
}

export default useStaticElementDimensions
</code></pre>
<p>The hooks is simple to use, but not straight forward to understand. So we will go through it in detail.</p>
<p>The hooks takes no arguments, but it returns an object with two properties. One of the return values is a reference <em>ref</em>, which we will pass to the DOM node we want to measure the size and position of. When doing that, the <em>dimensions</em> object returned from the hook will contain the <a href="https://www.w3schools.com/jsref/met_element_getboundingclientrect.asp">bounding client rect</a> which has the following attributes in its type definition:</p>
<pre><code>height: number;
width: number;
x: number;
y: number;
bottom: number;
left: number;
right: number;
top: number;
</code></pre>
<p>This means that we with this hook will be able to detect where on the screen the node is, and also its width and height. So usage of the hook would look something like this.</p>
<pre><code class="language-javascript">const SomeComponent = () => {
  const { dimensions, ref } = useStaticElementDimensions()
  const { height, width, x, y } = dimensions ?? {}

  return &#x3C;SomeNode ref={ref}>Example&#x3C;/SomeNode>
}
</code></pre>
<p>At this point, you may wonder, why did the hook return a useCallback function as ref when it could have used a useRef reference instead? The answer is about update frequency.</p>
<p>This useStaticElementDimensions hook is based on <a href="https://react.dev/reference/react-dom/components/common#ref-callback">callback refs</a>, more specifically at the <a href="https://legacy.reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node">old React docs of how to measure DOM nodes</a>. As you can read there, the regular ref retrieved from useRef function doesn’t notify about changes to the ref value, meaning we will only be informed about what value the node has when the component containing the referenced node mounts.</p>
<p>If the referenced node would be added later, using either conditional rendering or if a component is lazy loaded, the regular useRef reference wouldn't let us know that the node value has changed.</p>
<p>By using a callbackRef function rather than a normal ref, the reference will instead be bound to the actual node's mount and umount events. So, with the useCallback Ref, the hook does its job, but there's a bunch of use cases which isn't handled, which is probably why the example isn't included in the React docs anymore.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-hook-use-element-dimensions/we-need-a-better-solution.webp" alt="We need a better solution">
<em>Don't worry Napoleon, we have another hook</em></p>
<h2>useElementDimensions Hook</h2>
<p>So, now we have seen a hook which we could use to check the measurements of a DOM node with JavaScript. The hook does work, but it has some flaws.</p>
<p>First of all, it only measures the dimensions of the node when the node mounts, meaning it will not update when the element or viewport is updated. It's just a snapshot of the element, which can be used for static components which aren't dynamically rendered, thereby the name useStaticElementDimensions.</p>
<p>Websites are rarely static though. Sizes of DOM elements are often preserved, but positions are definitely not static. When the user scrolls on the page, or resizes the browser window, the position of the elements changes, and the static hook above doesn't consider that.</p>
<p>This is why we need a more sophisticated hook for this job, the useElementDimensions hook. The useElementDimensions hook works with browser scroll and resize events, and it also handles a special case where we manually need to refresh the dimensions.</p>
<p>You can see the updated hook below. Once again, a TypeScript version of the hook is available on <a href="https://github.com/PerssonDennis/examples/blob/main/useElementDimensions/src/useElementDimensions.tsx">GitHub</a> and <a href="https://codesandbox.io/p/sandbox/useelementdimensions-h8kvp9?file=%2Fsrc%2FuseElementDimensions.tsx">CodeSandbox</a>.</p>
<pre><code class="language-javascript">import useEventListener from 'hooks/useEventListener'
import { useCallback, useRef, useState } from 'react'

const useElementDimensions = () => {
  const ref = useRef(null)
  const [dimensions, setDimensions] = useState(null)

  const refresh = useCallback(() => {
    const domRect = ref.current?.getBoundingClientRect()

    if (domRect) {
      setDimensions(domRect)
    }
  }, [])

  useEventListener('resize', refresh);
  useEventListener('scroll', refresh, true);

  return { dimensions, ref, refresh }
}

export default useElementDimensions
</code></pre>
<p>The imported useEventListener looks like this.</p>
<pre><code class="language-javascript">import { useEffect } from 'react'

const useEventListener = (event, listener, useCapture) => {
  useEffect(() => {
    if (listener) {
      listener()
      window.addEventListener(event, listener, useCapture)

      return () => window.removeEventListener(event, listener, useCapture)
    }

    return () => {}
  }, [event, listener, useCapture])
}
</code></pre>
<p>As you can see, this hook is more advanced. The helper hook, useEventListener, should be easy to understand. It's a wrapper around a useEffect which subscribes and unsubscribes to events. In this case, the useElementDimensionsHook listens on the 'resize' and 'scroll' events specifically.</p>
<pre><code class="language-javascript">useEventListener('resize', refresh);
useEventListener('scroll', refresh, true);
</code></pre>
<p>You may also notice, that in this hook, we have ditched the callback ref and are now using a regular useRef reference. The useEventListener does invoke the listener when the effect runs, which means that the refresh function in the useElementDimensions hook will update the dimensions according to the current value of the node ref. That will re-trigger every time the component mounts, so there is no need for a callback ref.</p>
<p>The dimensions, are still stored in a useState though. This is because useRef values doesn't trigger components to re-render. So if we wouldn't use useState, the components using this hook wouldn't be notified about the change.</p>
<p>The useState, together with the resize and scroll listener hook useEventListener and the refresh function it triggers, is enough to keep the dimension return value up to date in most use cases. The user can resize the browser and scroll however it wants, and the hook will always provide the latest size and position of the node.</p>
<p>However, as I mentioned before, there are some special cases to handle, and that's why the hook exposes the refresh function as a return value. For example, if the dimensions returned from the function would be used to move or resize the node it references, the dimensions would become outdated. And since neither a scroll event or browser resize has occurred, the dimensions won't be updated.</p>
<p>If you find cases like that you can use the refresh function to manually update the dimensions. Although, more likely, you are doing some shady things and should watch out for infinite loops and nasty bugs. So in reality, you may be more safe by keeping the refresh function internal to the hook.</p>
<h2>Cautions and Improvements</h2>
<p>As just mentioned, you should be careful to use the refresh function manually outside the hook. You may end up in too many rerenders or strange behaviors. Only use the exposed refresh function if you know why you are doing so.</p>
<p>Furthermore, you should now about the implications of using the useElementDimensions hook. Listening on scroll positions is a slow operation. Generally, it is better to use the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API">Intersection Observer API</a> to check if nodes are visible on screen and for similar use cases, whenever it is possible.</p>
<p>Additionally, you may want to add a <a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#what-is-throttle-and-debounce">throttle or debounce</a> to the useElementDimensions hook. Or, if you have a quite limited use case for that hook, you may instead use the callback ref based hook useStaticElementDimensions. But remember, building responsive applications has been cool for a long time now.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-hook-use-element-dimensions/responsive-website.webp" alt="Responsive website">
<em>I can tell you, John did update all his sites to be responsive that night</em></p>
<h2>Use Cases</h2>
<p>In most cases, you would probably want to use the useElementDimensions hook. If you can be sure you won't need it, you have an option to use the less advanced useStaticElementDimensions hook.</p>
<p>Either way, here are a few use cases of when a hook like this may be needed.</p>
<ol>
<li>To ensure a menu or dropdown doesn't end up outside the viewport</li>
<li>To implement infinite scroll solutions</li>
<li>For dynamic components</li>
</ol>
<h3>1. To Ensure a Menu or Dropdown Doesn't End Up Outside the Viewport</h3>
<p>Menus such as dropdown menus and context menus are often rendered at the place the trigger button is placed. On many sites, the main menu is a hamburger menu in the top right corner of the site. Since these menus are fairly large, and often absolutely positioned, they can easily end up going out of the screen.</p>
<p>The same problem often occurs with dropdown menus or context menus on other places on the screen. For instance, when a dropdown menu is scrolled to be positioned at the bottom of the screen when it is being opened. In that case, the dropdown may drop out of screen and may need to open upwards instead, or at least being lift up so all of it is visible.</p>
<p>In these cases, a hook like useElementDimensions may be useful. A node's size and position can be compared to the window's innerWidth and innerHeight to determine if an element is inside or outside the viewport.</p>
<h3>2. To Implement Infinite Scroll Solutions</h3>
<p>Some more complex usage of this hook can be when a list is rendered. You are potentially implementing a infinite scroll component, which needs to recycle the list items to avoid loading too many DOM nodes into the DOM tree.</p>
<p>Such solutions can often involve calculating how many items which will fit within the list. This is an easy task if all elements are of the same height. That best case scenario is not always possible. Sometimes the height of elements will vary, and you may need to detect the size of the elements. That's another scenario when this hook could become useful.</p>
<h3>3. For Dynamic Components</h3>
<p>Components are not always static. You may render components dynamically, or even lazy load them. Or they may exist in you code but being opened with code. The useElementDimensions hook can in that case help you measuring the height and width of those components.</p>
<h2>Example Usage</h2>
<p>When this hook is used, it will generally look something like this.</p>
<pre><code class="language-javascript">import useElementDimensions from "hooks/useElementDimensions";

const DynamicComponent = () => {
  const { dimensions, ref } = useElementDimensions();
  const { height, width, x, y } = dimensions ?? {};

  return (
    &#x3C;>
      &#x3C;div ref={ref}>Some element&#x3C;/div>
      &#x3C;p>Height: {height}&#x3C;/p>
      &#x3C;p>Width: {width}&#x3C;/p>
      &#x3C;p>X: {x}&#x3C;/p>
      &#x3C;p>Y: {y}&#x3C;/p>
    &#x3C;/>
  );
};
</code></pre>
<p>You can pass the ref to any DOM node. This also works for TypeScript, since the hooks uses generic types in the examples on <a href="https://github.com/PerssonDennis/examples/blob/main/useElementDimensions/src/useElementDimensions.tsx">GitHub</a> and <a href="https://codesandbox.io/p/sandbox/useelementdimensions-h8kvp9?file=%2Fsrc%2FuseElementDimensions.tsx%3A14%2C10">CodeSandbox</a>.</p>
<h2>Summary</h2>
<p>useElementDimensions is a hook you can use for at least three use cases.</p>
<ol>
<li>To ensure a menu or dropdown doesn't end up outside the viewport</li>
<li>To implement infinite scroll solutions</li>
<li>For dynamic components</li>
</ol>
<p>The hook updates the ref upon scroll and window resize events. However, listening to such events is an expensive operation. You may want to use a throttle or a debounce, or maybe use the static variant of the hook, useStaticElementDimensions, which is based on callback refs, but isn't updated when the use scrolls or the browser window change size.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Hooks</category>
            <category>JavaScript</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/react-hook-use-element-dimensions/react-hook-use-element-dimensions.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[React Hook: useGlobalState]]></title>
            <link>https://www.perssondennis.com/articles/react-hook-use-global-state</link>
            <guid>https://www.perssondennis.com/articles/react-hook-use-global-state</guid>
            <pubDate>Sun, 20 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[React hook useGlobalState. React hook to share state without a context. Easy way to share state between components. ✓ TypeScript ✓ No context ✓ Examples]]></description>
            <content:encoded><![CDATA[<p>Sharing state between React components is crucial in most applications. With useGlobalState you can quickly share a state between multiple components without using a context provider or external lib. The hook is useful for small projects when a React context provider is not desired.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-global-state#how-to-use">How To Use</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-global-state#share-state-between-components">Share State Between Components</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-global-state#useglobalstate-hook-explained">useGlobalState Hook Explained</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-global-state#when-not-to-use">When Not To Use</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-global-state#redux-and-contexts-may-not-be-necessary">Redux and Contexts May Not Be Necessary</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-global-state#use-cases">Use Cases</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-global-state#server-rendering-support">Server Rendering Support</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-global-state#typescript-version">TypeScript Version</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-global-state#pubsub-implementation">PubSub Implementation</a></li>
</ul>
<h2>How To Use</h2>
<p>useGlobalState is just as easy to use as React's useState hook, only difference is that useGlobalState takes an object as first argument instead of the initial state.</p>
<p>The object has a required property <em>shareKey</em> which is used to identify the data which should be shared globally. All components which uses the same shareKey will share the same data.</p>
<pre><code class="language-javascript">import useGlobalState from "hooks/useGlobalState";

const SHARED_COUNT_KEY = "someUniqueKey";

const ComponentOne = () => {
  const [count, setCount] = useGlobalState&#x3C;number>({
    initialState: 0,
    shareKey: SHARED_COUNT_KEY
  });

  return (
    &#x3C;div>
      &#x3C;h2>Component one&#x3C;/h2>
      &#x3C;div>Count: {count}&#x3C;/div>
      &#x3C;button onClick={() => setCount(count + 1)}>Add 1&#x3C;/button>
    &#x3C;/div>
  );
};

export default ComponentOne;
</code></pre>
<h2>Share State Between Components</h2>
<p>If you have multiple components, each component can use one or more of this useGlobalState hook to share state with one or multiple other component. An example with two components sharing the same state can be found on <a href="https://codesandbox.io/s/useglobalstate-26n6kz?file=/src/useGlobalState.ts">CodeSandbox</a>.</p>
<p>If you want to test the hook while reading about it, it's available to try out there on CodeSandbox or downloadable from <a href="https://github.com/PerssonDennis/examples/tree/main/useGlobalState">GitHub</a>.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-hook-use-global-state/sharing-is-caring.webp" alt="Sharing is caring">
<em>Why not share this article with a friend?</em></p>
<h2>useGlobalState Hook Explained</h2>
<p>Let's take a look at the implementation of the hook, and later we look at some use cases.</p>
<pre><code class="language-javascript">import { pubSub } from "lib/pubsub"
import { useCallback, useEffect, useState } from "react"

const useGlobalState = ({
  initialState,
  onStateUpdated,
  shareKey
}) => {
  const [state, setState] = useState(initialState)

  const onStateUpdate = useCallback(
    (data) => {
      setState(data)
      onStateUpdated?.(data)
    },
    [onStateUpdated]
  )

  useEffect(() => {
    pubSub.subscribe(shareKey, onStateUpdate)

    return () => pubSub.unsubscribe(shareKey, onStateUpdate)
  }, [onStateUpdate, shareKey])

  const setSharedState = useCallback(
    (data) => {
      pubSub.emit(shareKey, data)
    },
    [shareKey]
  )

  return [state, setSharedState]
}

export default useGlobalState
</code></pre>
<p>First thing first, the hook depends on a pubsub import. In short, the pubsub import is what is actually used to share the state between components with the help of subscription and events. No React context needed. You can find the implementation of it at <a href="https://github.com/PerssonDennis/examples/blob/main/useGlobalState/src/pubsub.ts">GitHub</a> or <a href="https://www.perssondennis.com/articles/react-hook-use-global-state#pubsub-implementation">at the end of this article</a>, together with <a href="https://www.perssondennis.com/articles/react-hook-use-global-state#typescript-version">TypeScript</a> versions of the useGlobalState hook.</p>
<p>Second thing to notice, the hook takes an object with three properties. As can be seen in the TypeScript version a bit further down, <em>shareKey</em> is the only required property. That is the key used to identify the data you share. Components which uses this hook with the same shareKey will share the same state. If different shareKeys are used, they will not share the state. Simple as that.</p>
<p><em>initialState</em> is an optional property you can use to use to set an initial state. If you use this one, make sure to use the same initial state for all components using the same shareKey. Providing different values when you want to share a state doesn't make sense.</p>
<p>Last argument property is <em>onStateUpdate</em>. It's a callback that can be used to listen at state updates if that would be of interest.</p>
<p>The rest of the code is just to subscribe and unsubscribe to the pubsub, and to emit new values to it when setting a new state.</p>
<h2>When Not To Use</h2>
<p>Before talking about when to use this hook, I want to discuss when not to use it. As a developer, you should never just go with first available solution without consider the alternatives. You can read <a href="https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer">this article about proactive vs reactive developers</a> to understand why that is important.</p>
<p>If the project you are coding on already uses a state handling solution like Redux or MobX, you likely have no need for this hook. Better option would be to continue on that path. In fact, if you plan to store a good amount of data, Redux is still a good option to consider for that.</p>
<p>Another tough concurrent to this hook is regular React contexts. Let's face it, contexts are built for React and default option to store small states. It's perfect to use if you need to add some small functions to fake a small store, like a Redux store.</p>
<p>Remember though, a context combined with a reducer which many people promote as a replacement for Redux <a href="https://www.perssondennis.com/articles/how-to-avoid-react-context-trap#contexts-is-not-always-the-solution">is NOT a good option</a> if you need to store states larger than tiny. In that article, I just linked, you can find <a href="https://www.perssondennis.com/articles/how-to-avoid-react-context-trap#how-can-redux-save-us-from-the-context-trap">five reasons to why Redux is to prefer over reducer-context solution</a>.</p>
<h2>Redux and Contexts May Not Be Necessary</h2>
<p>Did I just convince you Redux and Contexts are more viable options than the hook in this article? Or did I scare you from using contexts? Either way, let's continue the discussion with some actual use cases and benefits of this hook.</p>
<p>React projects can be of any kind and any size. New hooks, libraries and frameworks are coming every day. Some of the hooks from the latest years are <a href="https://redux-toolkit.js.org/rtk-query/overview#use-hooks-in-components">RTK Query</a> and some other popular hooks like <a href="https://swr.vercel.app/">useSWR</a> and <a href="https://tanstack.com/query/v4/docs/react/reference/useQuery">useQuery</a>. With hooks like that, it's definitely not an obvious choice to use Redux as it used to be.</p>
<p>Hooks like useSWR work by caching your requests. You share the state between components by a cache which is built into the hook. The interesting thing here, is that useSWR hook does not require a context provider, it relies on a <a href="https://swr.vercel.app/docs/advanced/cache">global cache unless you opt in for a context for manual cache control</a>.</p>
<p>The useGlobalState is a concise example of what the cache control for a hook like useSWR could look like internally. And in fact, I'm very glad useSWR went for a solution without a context. Not because it's cumbersome to add a context provider, but because contexts are <a href="https://www.perssondennis.com/articles/how-to-avoid-react-context-trap">more complex to architect than you may think</a>. In general, moving them further up in the component tree means more rerenders, while moving them down leads to isolated contexts which are more difficult to keep synced with each other.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-hook-use-global-state/when-to-use-react-hook.webp" alt="When to use react hook">
<em>Easy Lenny, it's time now</em></p>
<h2>Use Cases</h2>
<p>With the previous chapters in mind, about usages of Redux and contexts, we can now tell a few cases when this hook could be suitable to use.</p>
<p><strong>1. Library Without a Need For a Context Provider</strong></p>
<p>As discussed earlier, we can use this hook when implementing a small library which needs a global state. With this hook, there's no need to use a context provider for the lib user.</p>
<p><strong>2. Singleton Hook</strong></p>
<p>You can use this hook in another hook to make that hook a singleton hook. Normally, each component which uses a hook gets a new state for that hook. The state of the hook is not shared with other components using the same hook.</p>
<p>In some cases, you want a hook which can share the state between all usages of the same hook. In that case, you can use this hook within you implemented hook to share its state, basically making it a singleton hook.</p>
<p><strong>3. One Time Usages for Small Projects</strong></p>
<p>Some projects are small. Adding Redux or a context or whatever you need may not be necessary. A small project with a single or a few pages can likely be small enough to just need a single shared state. Maybe it's even a proof of concept project. This hook may come in handy in that case.</p>
<h2>Server Rendering Support</h2>
<p>When you are using Next.js or other solutions where server side rendering may occur, you must as usual remember that component and hook states calculated on the server isn't available on the client. Not with this hook, not with React contexts and not with Redux. The states are stored one the client.</p>
<p>That doesn't mean that this hook cannot be used when server rendering exists. The hook does work with server rendering, it's just that the state will not be propagated to the server, it will stay on the client.</p>
<h2>TypeScript Version</h2>
<p>Even though I'm pretty sure TypeScript haters know TypeScript well enough to spot the types and remove them on their own, I still used the JavaScript implementation above, just because it's easy to overview. The TypeScript hook uses TypeScript generics to let you use use it with any type, custom or built in.</p>
<pre><code class="language-javascript">import { pubSub } from "lib/pubsub"
import { useCallback, useEffect, useState } from "react"

interface UseGlobalStateProps&#x3C;T> {
  shareKey: string
  initialState?: T
  onStateUpdated?: (data?: T) => void
}

const useGlobalState = &#x3C;T>({
  initialState,
  onStateUpdated,
  shareKey
}: UseGlobalStateProps&#x3C;T>) => {
  const [state, setState] = useState&#x3C;T>(initialState as T)

  const onStateUpdate = useCallback(
    (data: T) => {
      setState(data)
      onStateUpdated?.(data)
    },
    [onStateUpdated]
  )

  useEffect(() => {
    pubSub.subscribe(shareKey, onStateUpdate)

    return () => pubSub.unsubscribe(shareKey, onStateUpdate)
  }, [onStateUpdate, shareKey])

  const setSharedState = useCallback(
    (data: T) => {
      pubSub.emit(shareKey, data)
    },
    [shareKey]
  )

  return [state, setSharedState] as [T, (data: T) => void]
}

export default useGlobalState
</code></pre>
<h2>PubSub Implementation</h2>
<p>The pubsub TypeScript implementation the hook depends on is quite standard. It keeps a record of subscribers and provides functions for subscribing and unsubscribing to events. It is possible to subscribe to different events by calling the <em>subscribe</em> function with different values for <em>event</em> argument.</p>
<p>The PubSub object also has an <em>emit</em> function which can be used to submit events which will be propagated to all subscribers. If a subscriber would subscribe after some events already has been emitted, the last event for each event is stored and can optionally be emitted with the <em>emitLatestOnSubscribe</em> option passed in as an argument to the <em>subscribe</em> function.</p>
<p>The <em>emitLatestOnSubscribe</em> option is recommended to be used when React components are rendered conditionally. In that way, components can receive the latest state whenever they are mounted.</p>
<pre><code class="language-typescript">type PubSubCallback = (data: any) => void;

interface PubSubSubscribeOptions {
  emitLatestOnSubscribe?: boolean;
}

interface PubSub {
  emit: (event: string, data: unknown) => void;
  latestEvents: Record&#x3C;string, unknown>;
  subscribe: (
    event: string,
    callback: PubSubCallback,
    options?: PubSubSubscribeOptions
  ) => void;
  subscribers: Record&#x3C;string, PubSubCallback[]>;
  unsubscribe: (event: string, callback: PubSubCallback) => void;
}

export const pubSub: PubSub = {
  latestEvents: {},
  subscribers: {},

  subscribe: (event, callback, options = { emitLatestOnSubscribe: true }) => {
    const { emitLatestOnSubscribe } = options;

    if (!pubSub.subscribers[event]) {
      pubSub.subscribers[event] = [];
    }

    pubSub.subscribers[event].push(callback);

    if (
      emitLatestOnSubscribe &#x26;&#x26;
      Object.prototype.hasOwnProperty.call(pubSub.latestEvents, event)
    ) {
      callback(pubSub.latestEvents[event]);
    }
  },

  unsubscribe: (event, callback) => {
    if (pubSub.subscribers[event]) {
      pubSub.subscribers[event] = pubSub.subscribers[event].filter(
        (cb) => cb !== callback
      );
    }
  },

  emit: (event, data) => {
    if (pubSub.subscribers[event]) {
      pubSub.latestEvents[event] = data;
      pubSub.subscribers[event].forEach((callback) => {
        callback(data);
      });
    }
  },
};
</code></pre>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Hooks</category>
            <category>JavaScript</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/react-hook-use-global-state/react-hook-use-global-state.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[React Hook: useRunOnce]]></title>
            <link>https://www.perssondennis.com/articles/react-hook-use-run-once</link>
            <guid>https://www.perssondennis.com/articles/react-hook-use-run-once</guid>
            <pubDate>Sun, 17 Jul 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[React hook useRunOnce. A React hook to run code once on mount, or once per session. Easy way to run code only once in a React functional component.]]></description>
            <content:encoded><![CDATA[<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-run-once#userunonce-hook">useRunOnce Hook</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-run-once#run-once-on-mount">Run Once on Mount</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-run-once#run-once-per-session">Run Once per Session</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-run-once#when-not-to-use">When Not To Use</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-run-once#use-cases">Use Cases</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-run-once#examples">Examples</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hook-use-run-once#summary">Summary</a></li>
</ul>
<h2>useRunOnce Hook</h2>
<p>Below you can see how useRunOnce hook is implemented in JavaScript and typescript. The hook can be used to run a function once, either on mount or per browser session.</p>
<p>The hook takes an object as an argument, with two available properties. Firstly, a required <em>fn</em> property that is the callback function that will run. If no other property is passed, the callback function will run once every time the component mounts.</p>
<p>If the second property <em>sessionKey</em> is passed, the hook will instead utilize session storage to run the callback function just once per browser session. That is further explained later in this article.</p>
<p>The code is also available at <a href="https://codesandbox.io/s/userunonce-tdpmof?file=/src/App.js">CodeSandbox</a> and <a href="https://github.com/PerssonDennis/examples/tree/main/useRunOnce">GitHub</a>. You can try it out on CodeSandbox, but I will explain more about how it works here in the article.</p>
<h3>JavaScript</h3>
<pre><code class="language-javascript">import { useEffect, useRef } from "react";

const useRunOnce = ({ fn, sessionKey }) => {
  const triggered = useRef(false);

  useEffect(() => {
    const hasBeenTriggered = sessionKey
      ? sessionStorage.getItem(sessionKey)
      : triggered.current;

    if (!hasBeenTriggered) {
      fn();
      triggered.current = true;

      if (sessionKey) {
        sessionStorage.setItem(sessionKey, "true");
      }
    }
  }, [fn, sessionKey]);

  return null;
};

export default useRunOnce;
</code></pre>
<h3>TypeScript</h3>
<pre><code class="language-typescript">import React, { useEffect, useRef } from "react";

export type useRunOnceProps = {
  fn: () => any;
  sessionKey?: string;
};

const useRunOnce: React.FC&#x3C;useRunOnceProps> = ({ fn, sessionKey }) => {
  const triggered = useRef&#x3C;boolean>(false);

  useEffect(() => {
    const hasBeenTriggered = sessionKey
      ? sessionStorage.getItem(sessionKey)
      : triggered.current;

    if (!hasBeenTriggered) {
      fn();
      triggered.current = true;

      if (sessionKey) {
        sessionStorage.setItem(sessionKey, "true");
      }
    }
  }, [fn, sessionKey]);

  return null;
};

export default useRunOnce;
</code></pre>
<p><img src="https://www.perssondennis.com/images/articles/react-hook-use-run-once/react-hook-run-once-gump-meme.webp" alt="React hook useRunOnce Forest Gump meme">
<em>Forest Gump has never heard about segmentation fault</em></p>
<h2>Run Once on Mount</h2>
<p>If you want to run a function once a component mounts, simply pass a callback function to the argument object's <em>fn</em> attribute. The callback will only fire one time. Unless the component is being unmounted and mounted again, in that case, it will fire again.</p>
<pre><code>useRunOnce({
    fn: () => {
        console.log("Runs once on mount");
    }
});
</code></pre>
<h2>Run Once per Session</h2>
<p>If you would like to run a function only one time per session, you can pass a <em>sessionKey</em> to the hook. The hook will then use <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage">session storage</a> to ensure that the callback function only runs once per session.</p>
<p>In other words, when passing a sessionKey, the passed in function will only run one single time when a user visits your website. The callback function won't be triggered again, not even when the user reloads the website using the browser's reload button.</p>
<p>For the callback function to run one more time, the user will need to close the browser tab or the browser and then revisit the website in another tab or browser session. This is all according to the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage">session storage documentation</a></p>
<pre><code>useRunOnce({
    fn: () => {
        // This will not rerun when reloading the page.
        console.log("Runs once per session");
    },
    // Session storage key ensures that the callback only runs once per session.
    sessionKey: "changeMeAndFnWillRerun"
});
</code></pre>
<pre><code>Note. A common problem with session and local storage is that you cannot force users to close their browsers. Although, in some cases it may be necessary to clear the storage. Easiest way to do that is to use another storage key. So, if you are using this hook with a sessionKey and want all clients to rerun the hook, even if they aren't closing their browser, just make another deployment of your application with another sessionKey.
</code></pre>
<h2>When Not To Use</h2>
<p>Occationally, when I think I need this hook, I think twice about it and realize that I really don't. Here follows some cases when I wouldn't use the hook.</p>
<ol>
<li>Write a greeting message in web console when a user first visits your page.</li>
<li>Initialize a third-party library by calling one of their init-functions.</li>
<li>Send analytics data when a user visits your site (and resend it when user reloads the page).</li>
<li>Fetch data when a component mount.</li>
</ol>
<h3>1. Write a Greeting Message in Web Console When a User First Visits Your Page</h3>
<p>One reason you may not need the hook is because it's unnecessary to use a hook/useEffect if you don't need to read or set an internal state in a component. Writing a greeting message to the web console has nothing to do with React components or its life cycle, you can do that in pure JavaScript and there is no reason to do that within a React component.</p>
<h3>2. Initialize a Third-Party Library by Calling One of Their Init-Functions</h3>
<p>The reason to not using this hook when initializing third-party libraries is the same as when writing a message to the web console. Initializing third-party libraries may include registering plugins to a date library, configuring languages in a i18n library or whatsoever.</p>
<p>Such logic is rarely dependent on data in a React component and should therefore be initialized outside your components. Simply place the code in a file right above a React component and it will run once and only once, that's how <a href="https://dmitripavlutin.com/javascript-module-import-twice/">ES6 modules are designed</a>. See examples of when <a href="https://beta.reactjs.org/learn/synchronizing-with-effects#not-an-effect-initializing-the-application">not to use an useEffect in Reacts documentation</a>.</p>
<h3>3. Send Analytics Data When a User Visits Your Site (and Resend It When User Reloads the Page)</h3>
<p>You will find this point among the use cases as well. It really depends on what you want to measure. Do you want to resend analytics data when the user reloads a page with the web browser's reload button?</p>
<p>In that case, you may be able to fetch the data outside your React components as described above, if you don't need to read or set a component's internal state. On the other hand, if you don't want to refetch the data when a page is being reloaded, you can use the useRunOnce hook and provide a <em>sessionKey</em> to it.</p>
<h3>4. Fetch Data When a Component Mount</h3>
<p>This point is quite important if you don't want to introduce a lot of bugs in your code. In React 18 <a href="https://reactjs.org/docs/strict-mode.html">Strict Mode</a>, useEffects will run twice when mounting a component in development mode. In future releases that will also sometimes happen in production.</p>
<p>For that reason, you should be careful with sending network requests in useEffects. This hook includes a useEffect and does not handle it in a best-practice way, since it doesn't include all real dependencies in the useEffects dependency list.</p>
<p>You should most often avoid sending network requests in useEffects. Network requests of POST, PUT, PATCH or DELETE types should nearly never be placed in useEffects, they are usually triggered as a direct consequence of a user action and should therefore be triggered by a onClick handler, not in a useEffect.</p>
<p>It may be fine to fetch data in useEffects, but when doing that, you must ensure to handle the case when data is received twice or thrice. In other words, your callback function must be idempotent. You are better off using a hook like <a href="https://swr.vercel.app/">useSWR</a> which handles both caching and request deduplications for you. React have <a href="https://beta.reactjs.org/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development">documented how to handle cases like this in their docs</a>, make sure to read it, you will need to learn it eventually.</p>
<h2>Use Cases</h2>
<p>When would one want to use this hook? Here are some example use cases.</p>
<ol>
<li>Fetch data when a user visits your site (once per session).</li>
<li>Send analytics data when a component mount.</li>
<li>Send analytics data when a user visits your site (once per session).</li>
<li>Run code that should run once on client side and not at all on server-side.</li>
<li>Count how many times a user visits your site.</li>
</ol>
<h3>1. Fetch Data When a User Visits Your Site (Once per Session)</h3>
<p>First of all, if you have not read about not using this hook to <a href="https://www.perssondennis.com/articles/react-hook-use-run-once#4-fetch-data-when-a-component-mount">fetch data when a component mount</a>, do that first. If you do have a reason to fetch data only once per session though, this hook could be used for that. Then use it with a passed-in sessionKey attribute.</p>
<h3>2. Send Analytics Data When a Component Mount</h3>
<p>This is maybe the most common use case. The <a href="https://beta.reactjs.org/learn/synchronizing-with-effects#sending-analytics">docs for React 18</a> brings up how to handle analytics data in Strict Mode. What they mention is that it's a good idea letting it send it twice in development mode.</p>
<p>Anyhow, what they show is a simple case to handle. You may not be lucky enough that your analytics request only is dependent on a single <em>url</em> variable. It may be dependent on a lot of more variables, and you probably don't want to send the analytics request 30 times.</p>
<p>You can easily solve that in your code with code similar to what this hook contains, or you can use this hook.</p>
<h3>3. Send Analytics Data When a User Visits Your Site (Once per Session)</h3>
<p>Since this hook includes an option to include a sessionKey, you can also send analytics data once per browser session. This allows you to send analytic requests only once even when users are keeping their browser tab open for multiple days and just reloading it once in a while.</p>
<h3>4. Run Code That Should Run Once on Client Side and Not at All on Server-Side</h3>
<p>React supports server-side rendering (SSR), and there exist multiple frameworks that is built on React which supports SSR and even static site generation (SSG), one of those is Next.js.</p>
<p>When rendering React on server-side, the global <em>window</em> and <em>document</em> objects aren't available. Trying to access one of those objects on the server would throw an error. For that reason, following <a href="https://beta.reactjs.org/learn/synchronizing-with-effects#not-an-effect-initializing-the-application">Reacts suggestion for how to detect when an application initializes</a> isn't possible. This hook can therefore be very useful when dealing with frameworks that run server-side, since this hook only will trigger the callback function on client side.</p>
<h3>5. Count How Many Times a User Visits Your Site</h3>
<p>Why not count user visits? It may be useful sometimes. In that case, you can count on this hook.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-hook-use-run-once/react-hook-run-once-meme.webp" alt="React hook useRunOnce meme">
<em>Easiest way to fix a bug is to remove code</em></p>
<h2>Examples</h2>
<p>The code below illustrates how to use the useRunOnce hook to send analytics data when a component mounts. For demonstration, it also sets an internal state in the component and renders a text.</p>
<pre><code class="language-javascript">import React from 'react'
import useRunOnce from 'hooks/useRunOnce'

const MyComponent = () => {
  const [analyticsHasBeenSent, setAnalyticsHasBeenSent] = useState(falsse)

  useRunOnce({
    fn: () => {
      sendAnalytics()
      setAnalyticsHasBeenSent(true)
    }
  });

  return &#x3C;>{analyticsHasBeenSent ? 'Analytics has been sent' : 'Analytics has not been sent'}&#x3C;/>
}

export default MyComponent
</code></pre>
<p>In the example below, we instead log to local storage that analytics has been sent. This way, you probably don't need to use this hook. The reason is that nothing in the callback function is dependent on an internal state in the component. The code within the callback is pure JavaScript and can be lifted out of the React component.</p>
<pre><code class="language-javascript">import React from 'react'
import useRunOnce from 'hooks/useRunOnce'

const MyComponent = () => {

  useRunOnce({
    fn: () => {
      sendAnalytics()
      localStorage.setItem('analytics-has-been-sent', 'true')
    }
  });

  return &#x3C;>MyComponent&#x3C;/>
}

export default MyComponent
</code></pre>
<p>This is how the above code would look if we removed the hook and lifted out the code that fetches data and stores it in local storage.</p>
<pre><code class="language-javascript">import React from 'react'

sendAnalytics()
localStorage.setItem('analytics-has-been-sent', 'true')

const MyComponent = () => {
  return &#x3C;>MyComponent&#x3C;/>
}

export default MyComponent
</code></pre>
<p>If we don't want to resend analytics when the website is reloaded, we could use the hook to ensure that it only send data once per browser session, it would then look as this.</p>
<pre><code class="language-javascript">import React from 'react'
import useRunOnce from 'hooks/useRunOnce'

const MyComponent = () => {

  useRunOnce({
    fn: () => {
      sendAnalytics()
      localStorage.setItem('analytics-has-been-sent', 'true')
    },
    sessionKey: "anyStringHere"
  });

  return &#x3C;>MyComponent&#x3C;/>
}

export default MyComponent
</code></pre>
<h2>Summary</h2>
<p>useRunOnce is a hook you can use for two use cases.</p>
<ol>
<li>When you want to run some code every time a component mounts or remounts.</li>
<li>When you want to run some code once per browser session.</li>
</ol>
<p>Since the hooks wraps a useEffect, running code when a function mount can infer side effects in React 18 Strict Mode. Read <a href="https://beta.reactjs.org/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development">React's documentation to see how to handle that</a>.</p>
<p>The hook uses session storage to run code once per browser session. The hook will therefore run its code as soon as a new session is initiated, see <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage">session storage documentation</a> for details or read through this article.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Hooks</category>
            <category>JavaScript</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/assets/blog/default-article-image-unknown.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[React Hooks: useThrottledValue and useThrottledFunction]]></title>
            <link>https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function</link>
            <guid>https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function</guid>
            <pubDate>Sun, 14 Aug 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Use cases for throttle, debounce and new React 18 hooks useDeferredValue and useTransition. Custom hooks useThrottledValue and useThrottledFunction explained.]]></description>
            <content:encoded><![CDATA[<p>This article explains the new React 18 hooks useDeferredValue and useTransition and compares them to throttle and debounce functions. It also presents two similar custom hooks, useThrottledValue and useThrottledFunction, which can be used to throttle a function or value change when the React hooks isn't sufficient</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#usethrottledfunction-hook">useThrottledFunction Hook</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#usethrottledvalue-hook">useThrottledValue Hook</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#usedeferredvalue-and-usetransition">useDeferredValue and useTransition</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#what-is-throttle-and-debounce">What is Throttle and Debounce</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#throttle-vs-new-react-18-hooks">Throttle vs New React 18 Hooks</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#when-not-to-use-usethrottledfunction-or-usethrottledvalue">When Not To Use useThrottledFunction or useThrottledValue</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#when-to-use-usethrottledfunction-and-usethrottledvalue">When To Use useThrottledFunction and useThrottledValue</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#usethrottledvalue-implementation">useThrottledValue Implementation</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#examples">Examples</a></li>
<li><a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#summary">Summary</a></li>
</ul>
<h2>useThrottledFunction Hook</h2>
<p>useThrottledFunction is a hook you can use when you need to prevent a function from running too often. It works similar to React 18's <em>useTransition</em> hook but has a slightly different use case. I will provide the code for it later, but before doing that, we will look at the new hooks in React 18, <em>useTransition</em> and <em>useDeferredValue</em>. We will also look at what <em>throttling</em> and <em>debounce</em> actually means and how they differ from each other.</p>
<h2>useThrottledValue Hook</h2>
<p>useThrottledValue is a hook similar to useThrottledFunction. The difference is that useThrottledValue simply throttles a value change instead of a function call. The code for it will be provided later in this article.</p>
<h2>useDeferredValue and useTransition</h2>
<p>useDeferredValue is a new hook available in React 18. I recommend you to read <a href="https://blog.webdevsimplified.com/2022-05/use-deferred-value/">this article about why they added it here</a>, but in short, it's because they want to give us an opportunity to postpone an update of a value until more important code has run. It essentially burns down to deferring code execution so more prioritized UI updates can be render quicker.</p>
<p>To use useDeferredValue, simply pass a value to it and it will automatically be deferred if necessary.</p>
<pre><code class="language-javascript">import { useDeferredValue } from 'react'

const UseDeferredValueExample = ({ items }) => {
  const deferredItems = useDeferredValue(items)

  return (&#x3C;ul>
    {deferredItems.map((item) => &#x3C;li key={item.id}>{item.text}&#x3C;/li>)}
  &#x3C;/ul>)
}

export default UseDeferredValueExample
</code></pre>
<p>With React 18, came also a similar hook called useTransition. useTransition defers an update just like useDeferredValue does, but instead of merely updating a value it allows to customize the state update more granularly.</p>
<pre><code class="language-javascript">import { useState, useTransition } from 'react'

const UseTransitionExample = ({ text }) => {
  const [isPending, startTransition] = useTransition()
  const [shouldShow, setShouldShow] = useState(false)

  const showEventually = () => {
    startTransition(() => {
      setShouldShow(true)
    })
  }

  return (&#x3C;div>
    &#x3C;button onClick={showEventually}>Show Text&#x3C;/button>
    {isPending &#x26;&#x26; &#x3C;p>Text will show soon!&#x3C;/p>}
    {shouldShow &#x26;&#x26; &#x3C;p>{text}&#x3C;/p>}
  &#x3C;/div>)
}

export default UseTransitionExample
</code></pre>
<h2>What is Throttle and Debounce?</h2>
<p>Throttle and debounce are two terms that often are mixed up together. The purpose of them both are to prevent a function from running too often. A similar use case is not to update a value for a certain amount of time.</p>
<p>A throttle and a debounce both take a callback function as an argument and a time interval that decides how often the callback function should be allowed to be invoked. The return value is a new function that is the throttled/debounced callback function.</p>
<p>The difference between them is that a throttle will run multiple times while a debounce only will run once. When a function is being throttled for X seconds, it will at maximum run once every X second, regardless of how many times the function is called upon.</p>
<p>In other words, a throttle allows the function to run every X second, but will only run if it has been invoked one or more times during those X seconds.</p>
<p>Unlike a throttle, the time interval passed to a debounce will not make a function run periodically. A time interval passed to a debounce function can be seen as a cooldown time for the callback function that reset itself every time someone tries to trigger it.</p>
<p>A debounce is like a stubborn child that has made up its mind not to eat the food until the parents have stopped nagging about it for at least X seconds. As soon as the parents have been silent for X seconds, the child eats its vegetables.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-hooks-use-throttled-value-and-use-throttled-function/stubborn-child-debounce-meme.webp" alt="Stubborn child debounce meme">
<em>Mama' needs to learn how debounce works</em></p>
<p>The picture below depicts the usage of a throttle and a debounce. The lines labeled <em>regular</em> represents when the function is being called. You can see that the stubborn debounce only invokes the function as soon as the function has stopped being invoked while the throttled function is invoked periodically with a minimum time between every invocation. You can try it yourself at <a href="https://web.archive.org/web/20220117092326/http://demo.nimius.net/debounce_throttle/">this site</a>.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-hooks-use-throttled-value-and-use-throttled-function/debounce-and-throttle-explained.webp" alt="Debounce and throttle explained">
<em>Throttle will trigger periodically while debounce will trigger when invocation has stopped</em></p>
<p>Note that throttle and debounce functions often comes with settings. A debounce function can usually be configured to either run before or after the provided time interval. For the stubborn child, that would mean it would eat its vegetables the first time the parents asked, but would not eat another piece of it until the parents had been quiet for X seconds.</p>
<h2>Throttle vs New React 18 Hooks</h2>
<p>As described above, both a throttle and the new React hooks can be used to defer a function call or an update of a value. There is a slight difference between throttling and using the new React hooks though. useTranstition and useDeferredValue will update the state as soon as React has time for it. That's not the case with a throttle.</p>
<p>A throttle will wait for a specified amount of time before regardless of whether it is necessary for performance or not. This means that useDeferredValue and useTransition will be able to update the state sooner since they don't have to postpone it if it isn't really necessary.</p>
<p>A common reason to use a throttle is to prevent overheating an application with more function calls than the computer can handle. Such overheating can often be prevented or mitigated with the new useDeferredValue or useTransition hooks, since those hooks can detect when React has time to update the state. For that reason, many people claim that useDeferredValue and useTransition hooks removes the need for manually use a throttle or debounce.</p>
<p>The truth is, overheating an application isn't the only use case of a throttle or a debounce. Another use case is to prevent multiple invocations of a function in use cases where it could hurt the application in some way.</p>
<p>Maybe a backend service would return a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429">429 HTTP error code</a> when too many requests are sent, or maybe a resource intensive or expensive job would run to often without a throttle. In those cases, it's still necessary to use a throttle or debounce. There are often other solutions for such problems, but React's new hooks isn't what you search for in those cases.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-hooks-use-throttled-value-and-use-throttled-function/429-http-error-code.webp" alt="429 Http Error Code">
<em>Totally legit HTTP error code</em></p>
<h2>When Not To Use useThrottledFunction or useThrottledValue</h2>
<p>As described above, there are some scenarios where you should use useDeferredValue or useTransition rather than using the useThrottledValue or useThrottledFunction hook. Here are some examples of when to prefer the built-in React 18 hooks.</p>
<ol>
<li>When the reason to use the hook is to let more important code or UI updates run first.</li>
<li>When the reason to use the hook is to optimize performance when a value updates a few times.</li>
</ol>
<p>Well, the first use case is obvious. That's exactly what React's new hooks are supposed to do. To let you prioritize some updates as more important than other.</p>
<p>The second use case is maybe a bit more obvious, why wouldn't we throttle a function to optimize performance? The thing is, a lot of developers try to micro-optimize their code. Preventing a function from being called a few times is most often not a problem for performance. Failing to design a good frontend architecture, misusing the framework of use, or neglecting the importance of managing states and data flows correctly are big issue though. Handle those things properly and you won't need to micro-optimize your code on a function call level.</p>
<p>If you still would judge your use case as a case where it's important to micro-optimize, useDeferredValue and useTransition can help you out with that. They will help you deferring the updates until React feels there is time for it.</p>
<h2>When To Use useThrottledFunction and useThrottledValue</h2>
<p>Now when we know when not to use the hooks, we will look at when to use them.</p>
<ol>
<li>When the hook triggers a function that could be harmful to any other service or code.</li>
<li>When the function or value change triggers a resource intensive or expensive job.</li>
<li>When the reason to use the hook is to optimize performance when a value updates a lot of times.</li>
</ol>
<p>We did previously touch upon the two first scenarios under the <em>Throttle vs New React 18 Hooks</em> heading. We mentioned that a network service could respond with a 429 HTTP error code. Other scenarios could be that we would want to prevent a user from spamming a functionality that is allowed to be triggered multiple times.</p>
<p>Regarding the second use case, when an intensive job is triggered. A typical scenario could be when the value is listed as a dependency to a useMemo hook. The useMemo hook is usually used to prevent heavy calculations from running multiple times. Using a throttle to prevent the memo from updating too many times could therefore be a valid use case.</p>
<p>The third use case is almost the same as the second scenario of when not to use the hooks. The argument not to use the hooks was because it wasn't important to micro-optimize code on a function level. However, there is of course a threshold for when it would be necessary. An example would be when listening on mouse movement.</p>
<p>Remember the picture describing throttle and debounce? That picture was actually captured from a mouse movement. In that picture (duplicated here below), we can see that the debounce and throttle prevents a huge amount of function calls. If the function call is fairly heavy to run, it could be a good idea to throttle or debounce it.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-hooks-use-throttled-value-and-use-throttled-function/debounce-and-throttle-explained.webp" alt="Debounce and throttle explained">
<em>A debounce or throttle can prevent a lot of unnecessary function calls when it is triggered by mouse movement</em></p>
<h2>useThrottledValue Implementation</h2>
<p>A lot of text above, but finally we can look at the first hook implementation! Let's start with useThrottledValue, there's both a JavaScript and a TypeScript implementation of it.</p>
<p>The hook takes a single argument, an object containing a <em>value</em> and optionally <em>throttleMs</em>. The optional <em>throttleMs</em> is the throttle time for how often the value should be allowed to update. If left out, we have a default time at 800 ms (<em>DEFAULT_THROTTLE_MS</em>).</p>
<p>The hook consists of a single useEffect that will trigger as soon as a new value is passed in to the hook. If the hook hasn't updated the value for <em>throttleMs</em> milliseconds, it will update the value and save the time for the last update.</p>
<p>If the value updates more times within <em>throttleMs</em> milliseconds, it will set a timeout that will update the value as soon as it is time for it to update. To prevent memory leaks for the timers, the timeout is cleaned up every time the useEffect runs.</p>
<h3>JavaScript Implementation</h3>
<pre><code class="language-javascript">import {
  useCallback, useEffect, useRef, useState,
} from 'react'

const DEFAULT_THROTTLE_MS = 3000

const getRemainingTime = (lastTriggeredTime, throttleMs) => {
  const elapsedTime = Date.now() - lastTriggeredTime
  const remainingTime = throttleMs - elapsedTime

  return (remainingTime &#x3C; 0) ? 0 : remainingTime
}

const useThrottledValue = ({
  value,
  throttleMs = DEFAULT_THROTTLE_MS,
}) => {
  const [throttledValue, setThrottledValue] = useState(value)
  const lastTriggered = useRef(Date.now())
  const timeoutRef = useRef(null)

  const cancel = useCallback(() => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current)
      timeoutRef.current = null
    }
  }, [])

  useEffect(() => {
    let remainingTime = getRemainingTime(lastTriggered.current, throttleMs)

    if (remainingTime === 0) {
      lastTriggered.current = Date.now()
      setThrottledValue(value)
      cancel()
    } else if (!timeoutRef.current) {
      timeoutRef.current = setTimeout(() => {
        remainingTime = getRemainingTime(lastTriggered.current, throttleMs)

        if (remainingTime === 0) {
          lastTriggered.current = Date.now()
          setThrottledValue(value)
          cancel()
        }
      }, remainingTime)
    }

    return cancel
  }, [cancel, throttleMs, value])

  return throttledValue
}

export default useThrottledValue
</code></pre>
<h3>TypeScript Implementation</h3>
<pre><code class="language-typescript">import {
  useCallback, useEffect, useRef, useState,
} from 'react'

const DEFAULT_THROTTLE_MS = 3000

const getRemainingTime = (lastTriggeredTime: number, throttleMs: number) => {
  const elapsedTime = Date.now() - lastTriggeredTime
  const remainingTime = throttleMs - elapsedTime

  return (remainingTime &#x3C; 0) ? 0 : remainingTime
}

export type useThrottledValueProps&#x3C;T> = {
  value: T
  throttleMs?: number
}

const useThrottledValue = &#x3C;T, >({
  value,
  throttleMs = DEFAULT_THROTTLE_MS,
}: useThrottledValueProps&#x3C;T>) => {
  const [throttledValue, setThrottledValue] = useState&#x3C;T>(value)
  const lastTriggered = useRef&#x3C;number>(Date.now())
  const timeoutRef = useRef&#x3C;NodeJS.Timeout|null>(null)

  const cancel = useCallback(() => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current)
      timeoutRef.current = null
    }
  }, [])

  useEffect(() => {
    let remainingTime = getRemainingTime(lastTriggered.current, throttleMs)

    if (remainingTime === 0) {
      lastTriggered.current = Date.now()
      setThrottledValue(value)
      cancel()
    } else if (!timeoutRef.current) {
      timeoutRef.current = setTimeout(() => {
        remainingTime = getRemainingTime(lastTriggered.current, throttleMs)

        if (remainingTime === 0) {
          lastTriggered.current = Date.now()
          setThrottledValue(value)
          cancel()
        }
      }, remainingTime)
    }

    return cancel
  }, [cancel, throttleMs, value])

  return throttledValue
}

export default useThrottledValue
</code></pre>
<h2>useThrottledFunction Implementation</h2>
<p>The next hook, useThrottledFunction, works very similar to useThrottledValue and the implementations is nearly identical. The passed in <em>value</em> argument has been replaced with a <em>callbackFn</em>, which is the function that should be throttled.</p>
<p>The function returns an object. The object contains <em>throttledFn</em>, which is a throttled version of the passed in <em>callbackFn</em>. It also returns a cancel function, which can be called whenever the throttle timer's needs to be stopped.</p>
<h3>JavaScript Implementation</h3>
<pre><code class="language-javascript">import { useCallback, useEffect, useRef } from 'react'

const DEFAULT_THROTTLE_MS = 800

const getRemainingTime = (lastTriggeredTime, throttleMs) => {
  const elapsedTime = Date.now() - lastTriggeredTime
  const remainingTime = throttleMs - elapsedTime

  return (remainingTime &#x3C; 0) ? 0 : remainingTime
}

const useThrottledFunction = ({
  callbackFn,
  throttleMs = DEFAULT_THROTTLE_MS,
}) => {
  const lastTriggered = useRef(Date.now())
  const timeoutRef = useRef(null)

  const cancel = useCallback(() => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current)
      timeoutRef.current = null
    }
  }, [])

  const throttledFn = useCallback((args) => {
    let remainingTime = getRemainingTime(lastTriggered.current, throttleMs)

    if (remainingTime === 0) {
      lastTriggered.current = Date.now()
      callbackFn(args)
      cancel()
    } else if (!timeoutRef.current) {
      timeoutRef.current = setTimeout(() => {
        remainingTime = getRemainingTime(lastTriggered.current, throttleMs)

        if (remainingTime === 0) {
          lastTriggered.current = Date.now()
          callbackFn(args)
          cancel()
        }
      }, remainingTime)
    }
  }, [callbackFn, cancel])

  useEffect(() => cancel, [cancel])

  return { cancel, throttledFn }
}

export default useThrottledFunction
</code></pre>
<h3>TypeScript Implementation</h3>
<pre><code class="language-typescript">import { useCallback, useEffect, useRef } from 'react'

const DEFAULT_THROTTLE_MS = 800

const getRemainingTime = (lastTriggeredTime: number, throttleMs: number) => {
  const elapsedTime = Date.now() - lastTriggeredTime
  const remainingTime = throttleMs - elapsedTime

  return (remainingTime &#x3C; 0) ? 0 : remainingTime
}

export type useThrottledFunctionProps = {
    callbackFn: &#x3C;T, >(args?: T) => any
    throttleMs?: number
}

const useThrottledFunction = ({
  callbackFn,
  throttleMs = DEFAULT_THROTTLE_MS,
}: useThrottledFunctionProps) => {
  const lastTriggered = useRef&#x3C;number>(Date.now())
  const timeoutRef = useRef&#x3C;NodeJS.Timeout|null>(null)

  const cancel = useCallback(() => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current)
      timeoutRef.current = null
    }
  }, [])

  const throttledFn = useCallback(&#x3C;T, >(args?: T) => {
    let remainingTime = getRemainingTime(lastTriggered.current, throttleMs)

    if (remainingTime === 0) {
      lastTriggered.current = Date.now()
      callbackFn(args)
      cancel()
    } else if (!timeoutRef.current) {
      timeoutRef.current = setTimeout(() => {
        remainingTime = getRemainingTime(lastTriggered.current, throttleMs)

        if (remainingTime === 0) {
          lastTriggered.current = Date.now()
          callbackFn(args)
          cancel()
        }
      }, remainingTime)
    }
  }, [callbackFn, cancel])

  useEffect(() => cancel, [cancel])

  return { cancel, throttledFn }
}

export default useThrottledFunction
</code></pre>
<h2>Examples</h2>
<p>The code below shows how the useThrottledValue may be used. When a button is clicked, a <em>value</em> state variable is updated. After the user have clicked the button, a heavy calculation is done.</p>
<p>To prevent the heavy calculation from running too many times if the user spams the button, we use this hook to throttle the recalculation of the memorized value. You have a <a href="https://codesandbox.io/s/usethrottledvalue-3yo3n6?file=/src/App.js">CodeSandbox of it here</a> to try it, and if you want to clone, star or watch it on GitHub you have the <a href="https://github.com/PerssonDennis/examples/tree/main/useThrottledValue">repository for it here</a>.</p>
<pre><code class="language-javascript">import { useMemo, useState } from "react";
import useThrottledValue from "./useThrottledValue";

// Note that this will be called twice with React StrictMode because
// it's a callback provided to a useMemo.
const performHeavyCalculation = (value) => {
  console.log("Heavy calculation for value:", value);
  return value;
};

export default function App() {
  const [value, setValue] = useState(0);
  const throttledValue = useThrottledValue({ value, throttleMs: 5000 });

  const memoizedValue = useMemo(() => {
    return performHeavyCalculation(throttledValue);
  }, [throttledValue]);

  return (
    &#x3C;div>
      &#x3C;button onClick={() => setValue(value + 1)}>Increment value&#x3C;/button>
      &#x3C;p>Calculates a new value every fifth second.&#x3C;/p>
      &#x3C;p>Value: {value}&#x3C;/p>
      &#x3C;p>Last caculated result: {memoizedValue}&#x3C;/p>
    &#x3C;/div>
  );
}
</code></pre>
<p>Below code depicts a use case of useThrottledFunction. In this case, a function performHeavyCalculation is throttled to prevent it from being called for every fired scroll event. <a href="https://codesandbox.io/s/usethrottledfunction-vlx22d">CodeSandbox to try it code</a>. <a href="https://github.com/PerssonDennis/examples/tree/main/useThrottledFunction">GitHub repository here</a>.</p>
<pre><code class="language-javascript">import { useCallback, useEffect } from "react";
import useThrottledFunction from "./useThrottledFunction";

const performHeavyCalculation = () => {
  console.log("Heavy calculation");
};

export default function App() {
  const callbackFnToThrottle = useCallback(() => {
    performHeavyCalculation();
  }, []);

  const { throttledFn } = useThrottledFunction({
    callbackFn: callbackFnToThrottle,
    throttleMs: 5000
  });

  useEffect(() => {
    window.addEventListener("scroll", throttledFn);

    return () => {
      window.removeEventListener("scroll", throttledFn);
    };
  }, [throttledFn]);

  return (
    &#x3C;div>
      &#x3C;p>Scroll and look in console.&#x3C;/p>
      &#x3C;p>Code uses a throttle of 5 seconds.&#x3C;/p>
      &#x3C;div style={{ height: "4000px" }} />
      &#x3C;p>End of scroll...&#x3C;/p>
    &#x3C;/div>
  );
}
</code></pre>
<p>Note that there are two things to note for the code above. First thing is that the callback function called <em>callbackFnToThrottle</em> isn't necessary in this case. It would be possible to directly pass the performHeavyCalculation function to the callbackFn argument attribute. The callback is only added for demonstration.</p>
<p>The second thing to mention is that this use case isn't necessarily optimal. When looking at scroll events, there are many times often better solutions to apply. Using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API">Intersection Observer API</a> could be a better solution than listening for scroll events if the use case is to detect if an element is visible on screen.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-hooks-use-throttled-value-and-use-throttled-function/is-there-an-end-to-this-article-meme.webp" alt="Long article meme">
<em>I rather wonder why you are still reading it?</em></p>
<h2>Summary</h2>
<p>useThrottledValue and useThrottledFunction are hooks you can use in a few use cases.</p>
<ol>
<li>To throttle a function call that could be harmful to run many times.</li>
<li>To throttle a function call or value change that triggers a resource intensive or expensive job.</li>
<li>To optmize performance when a value is being updated lot of times.</li>
</ol>
<p>React 18 also introduced two new hooks, useDeferredValue and useTransition. These hooks can be used to run code with lower priority, to allow for more important code to run first. In some cases, it is better to use one of those hooks instead. That is the case when:</p>
<ol>
<li>When the reason to use the hook is to let more important code or UI updates run first.</li>
<li>When the reason to use the hook is to optimize performance when a value updates a few times.</li>
</ol>
<p>This article also described the difference between throttle and debounce. While both are used to avoid running code too often, they differ in how many times they will invoke the function. A throttle will periodically invoke the function dependent on a throttle time while a debounce will run the function only once, either at the start of or at the end of a series of invocations.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Hooks</category>
            <category>JavaScript</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/react-hooks-use-throttled-value-and-use-throttled-function/react-hooks-use-throttled-value-and-use-throttled-function-black.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Understanding useEffect, useRef and Custom Hooks]]></title>
            <link>https://www.perssondennis.com/articles/react-useEffect-render-flow</link>
            <guid>https://www.perssondennis.com/articles/react-useEffect-render-flow</guid>
            <pubDate>Sun, 06 Mar 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn in which order React triggers custom hooks and life cycle hooks such as useEffect and useRef.]]></description>
            <content:encoded><![CDATA[<p>A question I like to ask developers is "do you understand React's life cycle"? The answer is very often a confident "yes".</p>
<p>Then I show them the code for a <em>usePrevious</em> hook and let them explain why it works. If you don't know what a usePrevious hook is, you can see one below. It's used to get a previous value of a prop or state in a component, see <a href="https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state">React docs</a>.</p>
<pre><code class="language-javascript">const usePrevious = (value, defaultValue) => {
  const ref = useRef(defaultValue);

  useEffect(() => {
    ref.current = value;
  }, [value]);

  return ref.current;
};
</code></pre>
<p>Usually, the answer I get is a diffuse answer mentioning something about useRef updating instantly independent of the life cycle or that useRef doesn't trigger a rerender. That's correct.</p>
<p>Then I ask, "if the useEffect is updating the ref value as soon as the passed in <em>value</em> prop updates, won't the hook return the updated ref value?". The response is most often confusion. Even though my statement is fundamentally wrong, they don't really know React's life cycle well enough to explain what is wrong with my question. In fact, they most often believe that what I am saying is true and stands clueless of why the hook works.</p>
<p>Let us therefore take a look at how the usePrevious hook works. It's a perfect case for explaining how React handles useEffect and useRef.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-useEffect-render-flow/react-useEffect-render-flow-confusion.webp" alt="Confusion meme">
<em>What did you previously say?</em></p>
<h2>Logging the Sh*t Out of usePrevious</h2>
<p>Here we have a simple React component, using a usePrevious hook. What it does is to increment a count when a button is clicked. It's an overcomplicated way to do such a thing, we wouldn't really need a usePrevious hook in this case, but since the topic under discussion is the usePrevious hook, the article would be quite boring if we left it out.</p>
<pre><code class="language-javascript">// ### App.js
// When the button is clicked, the value is incremented.
// That will in turn increment the count.

import React, { useEffect, useState } from "react";
import usePrevious from "./usePrevious";

export default function App() {
  const [value, setValue] = useState(0);
  const [count, setCount] = useState(0);

  const previouseValue = usePrevious(value, 0);

  useEffect(() => {
    if (previouseValue !== value) {
      setCount(count + 1);
    }
  }, [previouseValue, value, count]);

  return (
    &#x3C;div>
      &#x3C;p>Count: {count}&#x3C;/p>
      &#x3C;button onClick={() => setValue(value + 1)}>Increment&#x3C;/button>
    &#x3C;/div>
  );
}
</code></pre>
<p>To better understand what React does when running the code, I have the same code here below but with a lot of console logs within it. I will carefully go through them all. You can find the code example at <a href="https://codesandbox.io/s/sad-yonath-skhbx6?file=/src/App.js">CodeSandbox</a> if you want to elaborate on your own.</p>
<pre><code class="language-javascript">// ### App.js (with logs)
// When the button is clicked, the value is incremented.
// That will in turn increment the count.

import React, { useEffect, useState } from "react";
import usePrevious from "./usePrevious";

export default function App() {
  const [value, setValue] = useState(0);
  const [count, setCount] = useState(0);

  console.log("[App] rendering App");
  console.log("[App] count (before render):", count);
  console.log("[App] value:", value);
  const previouseValue = usePrevious(value, 0);
  console.log("[App] previousValue:", previouseValue);

  useEffect(() => {
    console.log("[App useEffect] value:", value);
    console.log("[App useEffect] previouseValue:", previouseValue);

    if (previouseValue !== value) {
      console.log("[App useEffect] set count to value:", value, "\n\n");
      setCount(count + 1);
    } else {
      console.log("[App useEffect] not increasing count");
    }
  }, [previouseValue, value, count]);

  console.log("[App] count (after render):", count);
  console.log("[App] done rendering App\n\n");

  return (
    &#x3C;div>
      &#x3C;p>Count: {count}&#x3C;/p>
      &#x3C;button onClick={() => setValue(value + 1)}>Increment&#x3C;/button>
    &#x3C;/div>
  );
}

</code></pre>
<pre><code class="language-javascript">// ### usePrevious.js (with logs)

import { useRef, useEffect } from "react";

const usePrevious = (value, defaultValue) => {
  console.log("[usePrevious] value:", value);
  const ref = useRef(defaultValue);

  useEffect(() => {
    console.log("[usePrevious useEffect] value:", value);
    console.log("[usePrevious useEffect] increment ref.current:", ref.current);
    ref.current = value;
  }, [value]);

  console.log("[usePrevious] ref.current:", ref.current);

  return ref.current;
};

export default usePrevious;

</code></pre>
<p>Enough of code now, I think. Let's look at what happens when we click the <em>Increment</em> button. Here's what we will see in the output console. I highly recommending opening a second browser window to keep the code visible while you read the rest of this article.</p>
<pre><code class="language-markdown"># App component renders (1)
[App] rendering App
[App] count (before render): 0
[App] value: 1
[usePrevious] value: 1
[usePrevious] ref.current: 0
[App] previousValue: 0
[App] count (after render): 0
[App] done rendering App

# useEffects run (2)
[usePrevious useEffect] value: 1
[usePrevious useEffect] increment ref.current: 0
[App useEffect] value: 1
[App useEffect] previouseValue: 0
[App useEffect] set count to value: 1

# App component rerenders again (3)
[App] rendering App
[App] count (before render): 1
[App] value: 1
[usePrevious] value: 1
[usePrevious] ref.current: 1
[App] previousValue: 1
[App] count (after render): 1
[App] done rendering App

# useEffects run again (4)
[App useEffect] value: 1
[App useEffect] previouseValue: 1
[App useEffect] not increasing count

# (5)
</code></pre>
<hr>
<p><strong>Note:</strong> The description that follows should be treated as an interpretation of the code and output above. It's not the exact algorithm React uses. More about that later.</p>
<p><strong>(1)</strong> So here's what happens. When we click the increase button, it updates the <em>value</em> state to 1 which triggers a rerender of the App component. The usePrevious hook is the first code to be reached in the rerender, so it gets invoked directly. In that hook, we get the updated prop <em>value</em> of 1 while <em>ref.current</em> is still the default value of 0. React notes that the dependency to useEffect has changed, but it doesn't trigger the useEffect yet. Instead, it returns the <em>ref.current</em> value of 0 from the hook and store it in <em>previousValue</em> variable.</p>
<p>The rendering of the App component continuous and it reaches the useEffect. At this time, <em>value</em> has been updated from 0 to 1, so the useEffect should be triggered, but not yet. Instead of triggering it, React completes its rendering with a default <em>count</em> value of 0.</p>
<p><img src="https://www.perssondennis.com/images/articles/react-useEffect-render-flow/react-useEffect-render-flow-dependencies-noted.webp" alt="Dependencies noted meme">
<em>React notes that a dependency has updated, but does not run the effect immediately</em></p>
<p><strong>(2)</strong> Now, after having completed the rerender of the App component, it's time to run useEffects. React has noted that both the useEffect in usePrevious hook and in App component should be triggered. It starts invoking the useEffect in the usePrevious hook, that's the useEffect that was reached first during rendering.</p>
<p>When it runs the useEffect code it updates the <em>ref.current</em> to 1 and that's all. React continuous with the next useEffect in line, the one in the App component. At the time when the App component was rerendered and React first noticed that a value in the dependency list had updated, the <em>previousValue</em> variable was still set to 0. The reason we triggered the useEffect was because <em>value</em> had incremented from 0 to 1. So, the if-statement comparing <em>value</em> with <em>previousValue</em> will be truthy and we will update the count from 0 to 1.</p>
<p><strong>(3)</strong> We have now emptied the useEffects queue. No more effects to trigger. React can now check if a rerender is required, and it will notice that it is. <em>setCount</em> has been invoked so the <em>count</em> variable has updated to 1 from 0, so React decides to rerender the component once again.</p>
<p>The state variable <em>value</em> is still 1, we haven't increased that value. This time usePrevious hook gets invoked with the same value as last rendering, so there's no need to trigger the useEffect in the usePrevious hook. <em>ref.current</em> still has a value of 1, so the <em>previousValue</em> variable will be assigned a value of 1. When we then reach the useEffect in App component, React notes that <em>previousValue</em> has updated but does nothing about it. It continues the rerendering of the App component and exits gracefully with a count of 1.</p>
<p><strong>(4)</strong> Rerendering has completed, but we do have a useEffect in queue to run. As mentioned, the useEffect in usePrevious had no reason to trigger, so React continues directly with the effect in App component. <em>previousValue</em> is now 1, that's why we triggered the useEffect. <em>value</em> hasn't changed though and is still set to 1, so we don't invoke the setCount function.</p>
<p><strong>(5)</strong> We are now done running the useEffects, so it's time for React to check if a rerender is required again. It isn't though, since neither <em>value</em> or <em>count</em> did update when we ran the effects. So React calms down and waits for further user input.</p>
<h2>What Does the Life Cycle Look Like?</h2>
<p>What I did describe above is not a technical description of React's life cycle, rather it's an interpretation of what happens when the code runs. There's no time for a detailed explanation of what the React code really looks like here. It's obviously a bit more advanced than I describe in this article. We would need a more complex example which includes child components etc., and we would need to talk about <a href="https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html#browsing-commits">render and commit phase</a>. For those who are interested, a brief explanation of that can be found <a href="https://techdoma.in/react-16-tutorial/what-are-render-phase-and-commit-phase-in-react">here</a>.</p>
<p>Anyhow, for the sake of helping you understand the execution order I described in the five steps above, I will summarize it with some pseudocode.</p>
<pre><code class="language-javascript">const rerender = () => {
    // run code in component

    // if we reach a useEffect
    if (useEffectDependenciesHasUpdated) {
        useEffectQueue.push(useEffectCode)
    }

    // continue running code in component
}

const reactLifeCycle = () => (
    while (true) {
        if (stateHasChanged) {
            rerender()
            runEffectsInQueue()
        }
    }
)
</code></pre>
<p>As you can see, the above pseudocode is sufficient to explain why the usePrevious hook works. On a basic level, the life cycle could be expained in this way. React renders a component and runs the code within it. Whenever a useEffect is reached, react looks at its dependency list. If a variable within the dependency list has changed, React adds the callback function in the useEffect to a queue.</p>
<p>Whenever the rerendering has completed, react starts to pop effect callbacks out of that queue and invoke them. When the queue gets empty, React starts checking if it is necessary to rerender any components again.</p>
<h2>Why My Question was Faulty</h2>
<p>In the beginning of the article, I explained how I asked people this question about the usePrevious hook. Are you able to explain what it is wrong with the question now?</p>
<blockquote>
<p><em>if the useEffect is updating the ref value as soon as the passed in value prop updates, won't the hook return the updated ref value?</em></p>
</blockquote>
<p>Well, the answer to the question is actually: yes. <strong>If</strong> the useEffect was updating the ref value <strong>as soon</strong> as the passed in value updated, then yes, in that case, we would return the updated ref value. But that's not how React works. The useEffect isn't invoked instantly. It's invoked after React has completed the rendering phase and the parent component already has read the old ref value.</p>
<h2>Conclusion</h2>
<p>There are many things to say about React's life cycle handling. In this article we only look at useEffect, useRef and a custom usePrevious hook to see in which order React runs the code.</p>
<p>What we can discover by using a custom usePrevious hook is that React invokes the custom hook as soon as it reaches it during the rendering phase. The hook is merely a piece of code lifted out of the component.</p>
<p>However, at the time we reach a useEffect hook, React seemingly does nothing at all, rather it waits for the component rendering to finish, and then first after that has finished, the callback in the useEffect gets invoked.</p>
<p>I said <em>seemingly nothing at all</em>, because it's how it appears to work. Internally React handles many things under the hood. The dependency list must be checked in order to know if we even should run the callback or not. React must also keep track of the old dependencies to be able to compare them. But that's a topic for another day. What you need to know today, is that useEffect callbacks are invoked <strong>after</strong> a component has finished rendering, and they are executed in the same order as the code reaches them.</p>
<p>When a useEffect has run, the component may rerender a second time if its state has updated, e.g. if a set function returned by a useState has been invoked. If a useEffect only updates a useRef value, then React won't rerender the component. That value is updated immediately.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>Hooks</category>
            <category>JavaScript</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/assets/blog/default-article-image-unknown.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[The 20 Most Common Use Cases for JavaScript Arrays]]></title>
            <link>https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays</link>
            <guid>https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays</guid>
            <pubDate>Sun, 22 Oct 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Cheat sheet for JavaScript arrays with use cases for the most common array methods for immutable arrays. ✓ JavaScript ✓ List of array methods ✓ Cheat sheet]]></description>
            <content:encoded><![CDATA[<p>Splice, slice, pop and shift. Is the array sort method stable and not in-place? It's not easy to remember all JavaScript array methods and what the difference between them are. They are all synonyms, as if they where taken directly from a thesaurus.</p>
<p>This array cheat sheet lists all the array methods you usually need in JavaScript, and the ones you don't need, is not here. Simple as that! To make it even easier for you, I have based the cheat sheet on common use cases.</p>
<p><img src="https://www.perssondennis.com/images/articles/the-20-most-common-use-cases-for-javascript-arrays/the-20-most-common-use-cases-for-javascript-arrays.webp" alt="JavaScript array methods meme">
<em>New challenge, try to list all array methods without forgetting one of them</em></p>
<h2>Immutability</h2>
<p>Before we begin, a notice about immutability. All functions used in this article are <a href="https://hackernoon.com/mutability-and-immutability-in-javascript-explained-in-detail-x7q33ag">immutable</a>, which shortly means, that you never mutate your original array when you use these methods. Immutability is very important in modern JavaScript, at least according to <a href="https://stackoverflow.com/a/34385684/7584643">this Stack Overflow guy</a> (and the rest of the Internet).</p>
<p>Even though each of these methods is immutable on their own, you are not totally safe against immutability. If you include mutable data types (arrays, objects, functions) in your immutable arrays, you can still mutate the mutable data within the array. We call such arrays to be shallowly immutable, in contrast to deeply immutable arrays which only includes immutable items.</p>
<h2>Array Use Cases</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#1-add-element-to-start-of-array">Add Element to Start of Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#2-add-element-to-end-of-array">Add Element to End of Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#3-remove-an-element-from-start-of-array">Remove an Element From Start of Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#4-remove-an-element-from-end-of-array">Remove an Element From End of Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#5-insert-element-at-index-in-array">Insert Element at Index in Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#6-replace-an-element-at-index-in-array">Replace an Element at Index in Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#7-remove-an-element-at-index-in-array">Remove an Element at Index in Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#8-remove-an-element-by-value-from-an-array">Remove an Element By Value From an Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#9-remove-objects-by-property-from-an-array">Remove Objects By Property From an Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#10-check-if-array-includes-an-element">Check if Array Includes an Element</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#11-check-if-array-includes-object-with-property">Check if Array Includes Object with Property</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#12-check-if-all-objects-in-an-array-has-a-property">Check if All Objects in an Array has a Property</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#13-convert-array-to-an-object">Convert Array to an Object</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#14-convert-array-of-objects-to-an-object">Convert Array of Objects to an Object</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#15-convert-object-to-an-array">Convert Object to an Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#16-combine-two-arrays">Combine Two Arrays</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#17-sort-an-array">Sort an Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#18-sort-an-array-of-objects">Sort an Array of Objects</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#19-reverse-an-array">Reverse an Array</a></li>
<li><a href="https://www.perssondennis.com/articles/the-20-most-common-use-cases-for-javascript-arrays#20-remove-duplicates-from-an-array">Remove Duplicates From an Array</a></li>
</ol>
<h2>1. Add Element to Start of Array</h2>
<p>To prepend an item to the beginning of an array, use array spreading.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];
const result = [0, ...arr];
console.log(result);
// [0, 1, 2, 3]
</code></pre>
<p>Do not use the <em>unshift</em> method, that will mutate the original array.</p>
<h2>2. Add Element to End of Array</h2>
<p>To append an item to the end of an array, use array spreading.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];
const result = [...arr, 4];
console.log(result);
// [1, 2, 3, 4]
</code></pre>
<p>Do not use the <em>push</em> method, that will mutate the original array.</p>
<h2>3. Remove an Element From Start of Array</h2>
<p>To remove the first item in an array, use <em>slice</em> method.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];
// Keep index 1 and everything after that.
const result = arr.slice(1);
console.log(result);
// [2, 3]
</code></pre>
<p>Do not use the <em>shift</em> or <em>splice</em> methods, they will mutate the original array.</p>
<h2>4. Remove an Element From End of Array</h2>
<p>To remove the last item in an array, use <em>slice</em> method.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];
// Keep index 0 and everything after that, except one element at the array.
const result = arr.slice(0, -1);
console.log(result);
// [1, 2]
</code></pre>
<p>Do not use the <em>pop</em> or <em>splice</em> methods, they will mutate the original array.</p>
<h2>5. Insert Element at Index in Array</h2>
<p>To add an item at a specific index of an array, use the <em>toSpliced</em> method.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];
// Keep index 1, delete 0 elements, add the element "one point five" and keep everything after that.
const result = arr.toSpliced(1, 0, "one point five");
console.log(result);
// [1, "one point five", 2, 3]
</code></pre>
<p>Do not use the <em>splice</em> method, that will mutate the original array.</p>
<h2>6. Replace an Element at Index in Array</h2>
<p>To replace an item from some index in an array, use the <em>toSpliced</em> or <em>with</em> method.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];

// Using toSpliced.
// Keep index 1, delete 1 elements, add the element "two" and keep everything after that.
const result1 = arr.toSpliced(1, 1, "two");
console.log(result1);
// [1, "two", 3]

// Using with.
// Copy the old array arr with index 1 replaced with "two".
const result2 = arr.with(1, "two");
console.log(result2);
// [1, "two", 3]
</code></pre>
<p>Do not use the <em>splice</em> method, that will mutate the original array.</p>
<h2>7. Remove an Element at Index in Array</h2>
<p>To remove an item from an array, use the <em>toSpliced</em> method.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];

// At index 1, delete 1 elements.
const result = arr.toSpliced(1, 1);
console.log(result);
// [1, 3]
</code></pre>
<p>Do not use the <em>splice</em> method, that will mutate the original array.</p>
<h2>8. Remove an Element By Value From an Array</h2>
<p>To remove a specific value from an array, use the <em>filter</em> method.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];
const result = arr.filter((element) => element !== 2);
console.log(result);
// [1, 3]
</code></pre>
<p>Do not use the <em>indexOf</em> together with <em>splice</em> method, that will mutate the original array.</p>
<h2>9. Remove Objects By Property From an Array</h2>
<p>To remove an object with a specific attribute from an array, use the <em>filter</em> method.</p>
<pre><code class="language-javascript">const arr = [{ num: 1 }, { num: 2 }, { num: 3 }];
const result = arr.filter((obj) => obj.num !== 2);
console.log(result);
// [{ num: 1 }, { num: 3 }]
</code></pre>
<p>Do not use the <em>findIndex</em> together with <em>splice</em> method, that will mutate the original array.</p>
<h2>10. Check if Array Includes an Element</h2>
<p>To check if an array contains a value, use <em>includes</em> method.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];
const result = arr.includes(2);
console.log(result);
// true
</code></pre>
<h2>11. Check if Array Includes Object with Property</h2>
<p>To check if an array contains an object with a property, use <em>some</em> method.</p>
<pre><code class="language-javascript">const arr = [{ num: 1 }, { num: 2 }, { num: 3 }];
const result = arr.some((obj) => obj.num === 2);
console.log(result);
// true
</code></pre>
<h2>12. Check if All Objects in an Array has a Property</h2>
<p>To check if every object in an array has a property, use <em>every</em> method.</p>
<pre><code class="language-javascript">const arr1 = [{ num: 1 }, { num: 2 }, { num: 3 }];
const result1 = arr1.every((obj) => obj.num === 2);
console.log(result1);
// false

const arr2 = [{ num: 2 }, { num: 2 }, { num: 2 }];
const result2 = arr2.every((obj) => obj.num === 2);
console.log(result2);
// true
</code></pre>
<h2>13. Convert Array to an Object</h2>
<p>To convert an array to a custom object, use <em>reduce</em> method.</p>
<pre><code class="language-javascript">// A function which maps a key to a value.
const arr1 = [1, 2, 3];
const result1 = arr1.reduce((acc, cur, index) => {
  acc[`attr${index}`] = cur;
  return acc;
}, {});
console.log(result1);
// { attr0: 1, attr1: 2, attr2: 3 }

// A function which count occurrences could look like this.
const arr2 = ["a", "b", "c", "c"];
const result2 = arr2.reduce((acc, cur) => {
  if (acc[cur]) {
    acc[cur] += 1;
  } else {
    acc[cur] = 1;
  }
  return acc;
}, {});
console.log(result2);
// { a: 1, b: 1, c: 2 })

// A function which maps elements in array to boolean values can look like this.
// I.e. convert array to object keys.
const arr3 = ["a", "b", "c"];
const truthValues = ["b", "c"];
const result3 = arr3.reduce((acc, cur) => {
  acc[cur] = truthValues.includes(cur);
  return acc;
}, {});
console.log(result3);
// { a: false, b: true, c: true })
</code></pre>
<h2>14. Convert Array of Objects to an Object</h2>
<p>To convert an array of objects to an object, use <em>Object.assign</em> method and array spread syntax.</p>
<pre><code class="language-javascript">const arr = [{ attr1: 1 }, { attr2: 2 }, { attr3: 3 }];
const result = Object.assign({}, ...arr);
console.log(result);
// { attr1: 1, attr2: 2, attr3: 3 }
</code></pre>
<h2>15. Convert Object to an Array</h2>
<p>To create an array from an object, use <em>Object.keys</em>, <em>Object.values</em>, or <em>Object.entries</em>, potentially together with a <em>map</em> method.</p>
<pre><code class="language-javascript">const obj = { a: 1, b: 2, c: 3 };

// Array of keys.
const result1 = Object.keys(obj);
console.log(result1);
// ["a", "b", "c"]

// Array of values.
const result2 = Object.values(obj);
console.log(result2);
// [1, 2, 3]

// Array of key-value objects.
const result3 = Object.entries(obj).map(([key, value]) => ({ key, value }));
console.log(result3);
// [{ key: "a", value: 1 }, { key: "b", value: 2 }, { key: "c", value: 3 }]
</code></pre>
<p>In some cases, it is useful to chain some <em>map</em> and <em>filter</em> methods to modify and filter out values.</p>
<pre><code class="language-javascript">const obj = { a: 1, b: 2, c: 3 };

// Array of squared values greater than 3.
const result1 = Object.values(obj)
  .map((value) => value * value)
  .filter((value) => value > 3);
console.log(result1);
// [4, 9]

// Array of key-value objects which has a value greater than 1.
const result2 = Object.entries(obj)
  .map(([key, value]) => ({ key, value }))
  .filter((keyValueObj) => keyValueObj.value > 1);
console.log(result2);
// [{ key: "b", value: 2 }, { key: "c", value: 3 }]
</code></pre>
<h2>16. Combine Two Arrays</h2>
<p>To combine two JavaScript arrays, use <em>concat</em> method or the spread syntax for arrays.</p>
<pre><code class="language-javascript">const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

// Concat method is faster.
const combinedArray1 = arr1.concat(arr2);
console.log(combinedArray1);
// [1, 2, 3, 4, 5, 6]

// Spread syntax may be more readable.
const combinedArray2 = [...arr1, ...arr2];
console.log(combinedArray2);
// [1, 2, 3, 4, 5, 6]
</code></pre>
<p>Do not use the <em>push</em> method, that will mutate the original array.</p>
<h2>17. Sort an Array</h2>
<p>If you want to sort an array by value, use <em>toStorted</em> method.</p>
<p>The <em>toStorted</em> method is stable, meaning that it keeps the order of elements which are equal to each other intact. The method is not in-place, which usually is a good thing, since it means that it won't mutate the existing array.</p>
<pre><code class="language-javascript">// To sort strings.
let arr1 = ["b", "c", "a"];
const result1 = arr1.toSorted();
console.log(result1);
// ["a", "b", "c"]

// Note: Numbers are sorted by their toString value,
// not by their numerical value!
const arr2 = [10, 1, 5];
const result2 = arr2.toSorted();
console.log(result2);
// [1, 10, 5]

// To sort numbers, use a comparator.
const arr3 = [10, 1, 5];
const result3 = arr3.toSorted((a, b) => a - b);
console.log(result3);
// [1, 5, 10]
</code></pre>
<p>Do not use the <em>sort</em> method, that will mutate the original array since it does in-place sorting.</p>
<h2>18. Sort an Array of Objects</h2>
<p>To sort an array by value, use <em>toStorted</em> method with a comparator. A comparator is a function which determines which of two values that should be sorted first.</p>
<p>The <em>toStorted</em> method is stable, meaning that it keeps the order of elements which are equal to each other intact. The method is not in-place, which usually is a good thing, since it means that it won't mutate the existing array.</p>
<pre><code class="language-javascript">const arr = [{ num: 3 }, { num: 1 }, { num: 2 }];

// ObjA will be sorted before objB if comparator returns a positive value.
const byNumberAttribute = (objA, objB) => objA.num - objB.num;
const result1 = arr.toSorted(byNumberAttribute);
console.log(result1);
// [{ num: 1 }, { num: 2 }, { num: 3 }]

// More generic comparator.
const byAttribute = (attr) => (objA, objB) => objA[attr] - objB[attr];
const result2 = arr.toSorted(byAttribute("num"));
console.log(result2);
// [{ num: 1 }, { num: 2 }, { num: 3 }]

// Note. The comparator function must return an integer value.
// If you need to sort other data types, return 1, 0 or -1.
const arr3 = [{ letter: "c" }, { letter: "a" }, { letter: "b" }];
const alphabetically = (objA, objB) => {
  if (objA.letter &#x3C; objB.letter) {
    return -1;
  }

  if (objA.letter > objB.letter) {
    return 1;
  }

  // objA === objB
  return 0;
};
const result3 = arr3.toSorted(alphabetically);
console.log(result3);
// [{ letter: 'a' }, { letter: 'b' }, { letter: 'c' }]
</code></pre>
<p>Do not use the <em>sort</em> method, that will mutate the original array.</p>
<h2>19. Reverse an Array</h2>
<p>To reverse all values in an array, use <em>toReversed</em> method.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];
const result = arr.toReversed(2);
console.log(result);
// [3, 2, 1]
</code></pre>
<h2>20. Remove Duplicates From an Array</h2>
<p>To remove duplicated elements in an array, use <em>filter</em> method or a set.</p>
<pre><code class="language-javascript">const arr = [1, 2, 3, 2, 1];

// Using filter method.
const result1 = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(result1);
// [1, 2, 3]

// Using a set.
const result2 = [...new Set(arr)];
console.log(result2);
// [1, 2, 3]
</code></pre>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>JavaScript</category>
            <enclosure url="https://www.perssondennis.com/images/articles/the-20-most-common-use-cases-for-javascript-arrays/the-20-most-common-use-cases-for-javascript-arrays.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[The Art of Code Review and Why You Need It]]></title>
            <link>https://www.perssondennis.com/articles/the-art-of-code-review-and-why-you-need-it</link>
            <guid>https://www.perssondennis.com/articles/the-art-of-code-review-and-why-you-need-it</guid>
            <pubDate>Sun, 01 Oct 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn why you should do code reviews and how to benefit from reviewing code. There's a lot of reasons to review code and very few disadvantages of it.]]></description>
            <content:encoded><![CDATA[<p>Code reviewing is an art. Although most companies conduct code reviews, only a few of them fully harness the potential benefits that code reviews offer. In this article, we will look at what you and your team can do to fully leverage the potential they offer.</p>
<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/the-art-of-code-review-and-why-you-need-it#code-review-is-a-team-activity">Code Review Is a Team Activity</a></li>
<li><a href="https://www.perssondennis.com/articles/the-art-of-code-review-and-why-you-need-it#why-to-do-code-reviews">Why To Do Code Reviews?</a></li>
<li><a href="https://www.perssondennis.com/articles/the-art-of-code-review-and-why-you-need-it#why-you-should-not-do-code-reviews">Why You Should Not Do Code Reviews</a></li>
<li><a href="https://www.perssondennis.com/articles/the-art-of-code-review-and-why-you-need-it#what-to-do-before-a-code-review">What To Do Before a Code Review</a></li>
<li><a href="https://www.perssondennis.com/articles/the-art-of-code-review-and-why-you-need-it#what-to-do-during-a-code-review">What To Do During a Code Review</a></li>
<li><a href="https://www.perssondennis.com/articles/the-art-of-code-review-and-why-you-need-it#what-to-do-after-a-code-review">What To Do After a Code Review</a></li>
</ol>
<h2>Code Review Is a Team Activity</h2>
<p>First rule of code reviewing, code reviewing concerns the whole team. Every person is different, developers have different opinions about code and also different expectations of a code review. Critiques are also received differently from person to person, some are more sensitive than others.</p>
<p>To make sure the whole team agrees to how the code reviews should be handled, you can do one of two things. Either have a meeting about it to talk about expectations, or, make it less formal and start a discussion with the team when you do your first code review. If you bring it up when you present your first code review, you can be quite strict with your comments and still appear as a caring person.</p>
<p>When you discuss the code reviews, try to settle what you think is important. Should the code review be about finding bugs, or should you comment with improvements and opinions? If you encourage opinions, should those be mandatory to fix or can they be ignored?</p>
<p>Discuss and come up with an agreement every developers agrees with, but try to avoid creating explicit checklists of what to check. Using checklists, can easily turn into developers checking off each item an then thinking they are done with the code review, without really reflecting over the solution at all.</p>
<h2>Why To Do Code Reviews?</h2>
<p>From a manager's perspective, code reviews are often all about finding bugs and assure that the committed code won't hit back when testers test it. For me, as a developer, the main goal of a code review isn't to stop bugs, it's to involve more persons in the solution and to initiate discussions for alternative solutions and knowledge sharing. In the long term, that's what really going to improve the product quality and make developers write less error-prune code.</p>
<p>If you do code reviews correctly, they can help your team in many areas. These are just some of the benefits a code review can help you with.</p>
<ul>
<li>Reflecting over your code before you commit</li>
<li>Learn and reflect about other developer's code and opinions</li>
<li>Teaching and helping other developers</li>
<li>Align the teams view on the product and its code and newly added code</li>
<li>Getting better knowledge of the full code base</li>
<li>Stop bugs from coming through</li>
<li>Improve the quality of the code</li>
<li>Improve the quality of tests</li>
<li>Reduced technical debt</li>
<li>Enhanced documentation with cleaner commits and better comments</li>
<li>Identify security issues</li>
<li>Save time by fixing issues during the code review instead of two weeks after</li>
<li>Building a team</li>
</ul>
<p>The last point in the list is what many people forget, but still one of the most important points. A good team communication is essential for all kind of business and development. Code reviews are an excellent way to let the team grow together because it is likely to cause conflicts, and anyone who knows anything about team building or conflict management knows that conflicts are necessary for a team to excel.</p>
<p><img src="https://www.perssondennis.com/images/articles/the-art-of-code-review-and-why-you-need-it/no-coffee-for-years.webp" alt="No coffee for years meme">
<em>Tea drinkers would think it's a compliment</em></p>
<h2>Why You Should Not Do Code Reviews</h2>
<p>There aren't very many reasons for not doing code reviews honestly. It does takes time, yes, but that time you will definitely get back in the long term with all the benefits it comes with.</p>
<p>Think about it a bit. If you founded a tech company and hired developers. Would you like anyone to push any code without a single person looking at what they pushed? Would you rely on an open source project where anyone could contribute but no one was reviewing what was committed?</p>
<p>If your answer to any of those questions is no, or if you want to build a better team and improve code quality, then code reviews are for you.</p>
<h2>What To Do Before a Code Review</h2>
<p>A code review doesn't start with a pull request, there are certain things needed to be done before that, both as the developer who commits the code and for the person who is going to review it.</p>
<h3>As a Coder</h3>
<p>In a divergent team, there's always that architect guy who checks whole teams code, but also several more fast-paced developers who never really look twice at code and blindly push their code using their two characters alias for "git add . &#x26;&#x26; git commit -m "save" &#x26;&#x26; git push".</p>
<p>When submitting code for a code review (or even without a code review), those hasty developers should try to be a bit more like the architect guy. Some things that always should be done before committing code are:</p>
<ol>
<li>Keep the commit small, only a single story/task should be implemented in the commit. In that way, it's easier to review and also easier for teammates to track why a change was made when in doubt.</li>
<li>Don't include code unrelated to the task you are working on in your commit. If you have fixed stuff unrelated to your task, commit it in another commit before or after the task.</li>
<li>Does your commit include temporary code? Try to fix it before committing. If not possible, mark it with a TODO comment and plan when to follow it up.</li>
<li>Does your commit include a complex solution? Write comments for the parts which needs it.</li>
<li>Look through your code before pushing. Even if you have followed all the previous steps above without missing anything, you might find improvements for you code or other ways to implement the solution.</li>
<li>Test your code manually. And if you haven't written any test, write those.</li>
</ol>
<p>First when all above has been done, you are ready to commit your code and ask for a code review. When that is done, it's time for another coffee!</p>
<p><img src="https://www.perssondennis.com/images/articles/the-art-of-code-review-and-why-you-need-it/wait-until-monday-meme.webp" alt="Wait until monday meme">
<em>You know, I've seen better developers. On their first cup...</em></p>
<h3>As a Reviewer</h3>
<p>The main work of a code review as a reviewer is obviously to review the code, but before doing that, make sure to do a few things.</p>
<p>Firstly, make sure that the developer is done with the development and that all tests for it have been written. Don't review partly finished work unless it isn't to help out with another pair of eyes. Partly finished code is likely to change, especially if tests haven't been written and bugs may be found.</p>
<p>Secondly, talk to the developer who developed the feature to understand what the commit is about. Preferably with the pull request and feature in front of you. Doing this will make it easier to understand the code and the developer's reasoning.</p>
<p>Lastly, you can think about how you would implement the feature before looking at the pull request. This is a great practice to practice problem solving, since you will both come up with a solution on your own and potentially see an alternative solution for the same problem. If you are lucky, you the developer of the pull request implemented the feature in another way, which will make the code review much more interesting.</p>
<h2>What To Do During a Code Review</h2>
<p>When a pull request has been made, it's time to review it. This work lies mainly on the reviewer, but even the code contributor has a few things to think about.</p>
<h3>As a Coder</h3>
<p>As the developer of the pull request, you can often just sit and relax while the reviewer tears its hair. To make the life easier for the reviewer, make sure to be available for questions. If the reviewer and you don't know each other very well, make sure to mention you are available for questions, so that person dares to ask.</p>
<h3>As a Reviewer</h3>
<p>Reviewing large pull requests takes time. As a reviewer it is important to remember it is worth the time without stressing it, take a minute to look back at the section about why to do code reviews in the beginning of this article. Then embrace the opportunity to grow as a developer.</p>
<p>For anything larger than one-liner commits, make sure to check out the code for the pull request in your IDE. This makes it easier to follow links in the code and to search for usages of functions and variables. It also allows you to spot changes the developer should have done but have missed out, e.g. if a function is invoked at several places but the developer only have updated it at one place.</p>
<p>When writing comments on the review, be clear what you mean. If it is a matter of opinion, please make sure to motivate your answer. Apart from when your office's coffee machine decides to brew a "null coffee", there are few things as annoying as an opinionated review comment without an explanation sent with a confident "I'm the architect" attitude.</p>
<p><img src="https://www.perssondennis.com/images/articles/the-art-of-code-review-and-why-you-need-it/prefer-coffee-overflow-to-null-coffee.webp" alt="Prefer coffee overflow to null coffee">
<em>A little more seems about enough</em></p>
<p>Speaking about opinions. Don't be that bossy architect guy, unless your team haven't discussed the expectations of code reviews and asked for very critical reviews. If you have opinions, my personal opinion is that they shouldn't block merging if it isn't important.</p>
<p>To continuously interrupting work to fix arguably unimportant stuff like a function name which "could have been better" or an if statement which "could have used an if else" is really annoying and is time spent on fairly worthless matters. Not everyone cares if the attributes are sorted alphabetically. If you have strong feelings about it, make the linter complain about it.</p>
<p>In the end, it's up to your team to decide where the line goes. What are opinions and when will they need to be fixed? Should they block merging or do they only have to be fixed if there are more severe changes which needs to be done?</p>
<h2>What To Do After a Code Review</h2>
<p>When the reviewer have reviewed the pull request and it is time to hand the comments over to the contributor, it's a good time for a talk. By going through the comments together both developers get a time together for some knowledge sharing and to sort out any unclear comments and avoid misunderstandings.</p>
<p>As the author of the commit, this is the best opportunity to express any objections. If you think the comments make sense, make sure to not do the same mistake next time you push a pull request.</p>
<p>If everything looks good an you both are happy with the solution, go for a coffee together!</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Productivity</category>
            <category>SoftSkills</category>
            <enclosure url="https://www.perssondennis.com/images/articles/the-art-of-code-review-and-why-you-need-it/the-art-of-code-review-and-why-you-need-it.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Three Simple Rules to Solve Unsolvable Organizational Problems]]></title>
            <link>https://www.perssondennis.com/articles/three-simple-rules-to-solve-unsolvable-organizational-problems</link>
            <guid>https://www.perssondennis.com/articles/three-simple-rules-to-solve-unsolvable-organizational-problems</guid>
            <pubDate>Tue, 12 Nov 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Three effective ways to solve communication problems in your organization and to create self-organized teams by eliminating dependencies to other teams.]]></description>
            <content:encoded><![CDATA[<p>There are some problems every company faces, no matter the size or industry. Issues like incorrectly assigned responsibilities and poor or overwhelming communication can slow teams down. In this article, we’ll explore three simple rules that can help you tackle these common challenges and get your organization on track.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/three-simple-rules-to-solve-unsolvable-organizational-problems#single-responsibility">Single Responsibility</a></li>
<li><a href="https://www.perssondennis.com/articles/three-simple-rules-to-solve-unsolvable-organizational-problems#communication">Communication</a></li>
<li><a href="https://www.perssondennis.com/articles/three-simple-rules-to-solve-unsolvable-organizational-problems#dependency-elimination">Dependency Elimination</a></li>
</ul>
<h2>Single Responsibility</h2>
<p>Every developer who knows about design patterns has heard of SOLID principles - five simple rules to follow when writing good code. It's an extremely popular subject, so popular that my article about <a href="https://www.perssondennis.com/articles/write-solid-react-hooks">SOLID principles in React</a> is one of my most-read pieces, despite the abundance of similar content out there.</p>
<p>We're not going to examine these principles today, but we will briefly touch the first one, the S. The S in SOLID stands for Single Responsibility Principle, which states that one piece of code should have one and only one responsibility.</p>
<p>The reasoning behind this is quite simple. Managing two or more tasks at once is difficult - not for the computer, but for the developer. The code becomes harder to read, more challenging to test, more difficult to reuse, and the chances of introducing bugs increase.</p>
<p>The question isn't why we have this rule for code, rather, why companies don't embrace this principle when assigning roles to employees?</p>
<p>I'll say it again, it's not the computer that finds it cumbersome to run code that does multiple things simultaneously, it's the human brain which struggles to understand and maintain it.</p>
<p>In fact, this isn't specific to code. Generally, humans are terrible at multitasking. Period. For this reason, companies should not assign two or three different responsibilities to the same person. Each person should have one and only one job.</p>
<p>Are you a manager who recently assigned a new area of responsibility to your best and most reliable employee? Congratulations, you've just found the quickest way to make them fail.</p>
<p><img src="https://www.perssondennis.com/images/articles/three-simple-rules-to-solve-unsolvable-organizational-problems/spiderman-meeting-meme.webp" alt="Spiderman meeting meme">
<em>With great responsibilities comes great meetings</em></p>
<h2>Communication</h2>
<p>A company can have everything figured out when it comes to roles, workloads, and required tasks, yet still fail miserably at delivering their products. The main reason for this is often a lack of or poor communication. Effective communication is critical for any company, regardless of its size.</p>
<p>There are many important aspects of communication at different levels. To keep this brief, we'll focus on two critical concepts:</p>
<ol>
<li>Pulling vs pushing information</li>
<li>Avoiding single-person communication bottlenecks</li>
</ol>
<h3>Pulling vs Pushing Information</h3>
<p>Information must be available. Without appropriate information, a team cannot work effectively, resulting in major time losses. However, how information is received matters significantly. This includes not only the medium (Slack, email, or in-person communication) but also whether the recipient requested the information or had it pushed to them.</p>
<p>There's no absolute right or wrong way to handle information flow - whether it should be pushed to someone or whether they should seek it themselves. When recipients aren't aware of information they need to know, the information holder must proactively share it. However, if people know how to access the information they need, there's no reason to push it to them.</p>
<p>This sounds simple, but it rarely works this way in practice. Most of us receive numerous irrelevant emails daily. Many of us are automatically assigned to email lists and Teams groups that don't concern us.</p>
<p>Meanwhile, product issues arise due to information gaps, and we blame others for not sharing essential information with us. We wonder why we weren't invited to meetings which were highly relevant for our work.</p>
<p>Though challenging, this problem has viable solutions. The most important step is communicating what information is available. Every company and team should have a central location where people can discover where to find specific information. This might include contact lists, collections of links, or an overview of available Slack channels.</p>
<p>Once people know where to find information, the approach should shift to an information subscription model. Everyone can subscribe to the information they deem necessary, and then as soon as there is new information on that topic, they will get notified about it.</p>
<p>There's one small but critical detail here which must be mentioned though - you must push that source of information to all employees, making sure they know how to find and use it. If they don't know that they will stand without any information at all.</p>
<h3>Avoiding Single-Person Communication Bottlenecks</h3>
<p>Large companies have many roles, and each role comes with specific responsibilities. Product Owners (POs), for example, are responsible for their products. While it's important that POs know everything about their products and stay informed about developments, this doesn't mean all product-related communication needs to flow through them.</p>
<p>POs interact with many stakeholders. In large organizations, they might communicate with function owners, system verification engineers, designers, and others. As developers, we should communicate directly with these stakeholders rather than routing everything through the PO.</p>
<p>If all information flowed through the PO, it would create a significant bottleneck. Just like with scaling hardware resources in production, communication should scale horizontally, not vertically - meaning it's better to have many direct conversations between team members than to funnel everything through a single person.</p>
<h2>Dependency Elimination</h2>
<p>A few years ago, I was convinced communication was the key to success for large companies. However, it turned out to be only half the key - the other half being dependency elimination.</p>
<p>I could continue discussing why communication is important, but the truth is, communication fails. Books about communication will tell you it's a shared responsibility between sender and receiver, with various disturbances in transmission. While this theory is true, communication will ultimately fail, often massively.</p>
<p>One reason for this failure, beyond miscommunication, is poor retention of information and inadequate follow-up actions. The learning pyramid, a visual model showing retention rates across different learning methods, illustrates this well.</p>
<p><img src="https://www.perssondennis.com/images/articles/three-simple-rules-to-solve-unsolvable-organizational-problems/learning-pyramid.webp" alt="Learning Pyramid">
<em>Learning pyramid</em></p>
<p>As you can see, people remember only 5% of what they hear, meaning your colleague will forget 19 out of 20 things you tell them. They retain about 10% of what they read, so even when writing Slack messages you would need to send them each message ten times.</p>
<p>Combining hearing, reading, and visual elements improves retention somewhat. Group discussions (read: expensive meetings) can achieve 50% retention. However, since half the participants are likely checking their phones, the effective retention rate drops far below that.</p>
<p>See the pattern? Communication is essential but inefficient. There's only one way to avoid miscommunication, lost messages, and information that never reaches its destination: dependency elimination - the bulletproof way to avoid communication by removing the need for it entirely.</p>
<p>For developers who might have wondered why we've focused so much on human interaction, let's return to technical scenarios. Imagine if you:</p>
<ul>
<li>never had to request a feature from another team again</li>
<li>never had to be blocked by another team's bug again</li>
<li>never had to miss a delivery because of a failed PI planning</li>
<li>never had to explain to other developers how they should implement APIs</li>
</ul>
<p>These aren't merely communication issues - they're communication dependencies you should minimize or eliminate. After all, don't you want your API lean and efficient?</p>
<h3>How To Eliminate Dependencies</h3>
<p>"But Dennis, you can't just stop communicating and solve all issues, that would be absurd." Yes, it would. But you can minimize the need for communication.</p>
<p>A good architect thinks about this. They detect important data flows and ensure services communicate only when necessary, through simple, understandable channels, preferably based on subscriptions rather than pushing or periodic polling.</p>
<p>The same principle should apply to team and management structure. Unnecessary communication and dependencies between teams should be eliminated. In practice, this can be done in several ways:</p>
<ul>
<li>by moving responsibilities and products between teams</li>
<li>by implementing appropriate team structures (cross-functional teams instead of silos, etc.)</li>
<li>by ensuring teams are self-organized, taking responsiblity for work instead of asking others what to do</li>
<li>by letting people subscribe to information they need, rather than overwhelming them with irrelevant information</li>
<li>by having clear responsibilities so people know who should do what</li>
<li>by ensuring each person has one and only one responsibility (reducing the amount of dependencies they can have)</li>
</ul>
<p>Does your company have features blocked by other teams? Then the solution in the first bullet-point might be what you need, letting the team which is blocked taking ownership of the dependency which blocks them.</p>
<p>Are your testers overwhelmed because developers aren't testing their software adequately, causing bugs to bounce back and forth between development and testing teams? The second point about team structure might be your answer. After all, what testing team would be overwhelmed if there wasn't a separate team to report bugs to?</p>
<p>Bugs would still exist, but testers could verify them directly with greater knowledge about what they're testing. They wouldn't need to hunt for requirements to understand how each application should work. Just as you wouldn't want a developer working on dozens of applications, why expect that from a tester?</p>
<p>Although cross-functional and self-organized teams might sound similar, there's a difference in the meaning. A cross-functional team handles work which normally spans over multiple departments (development, testing, production monitoring etc.), while a self-organized team takes responsibility to manage their own tasks rather than waiting for orders from managers.</p>
<p>By being a self-organized team, the communication and interaction to other parts of the company can be reduced, together with the benefit of building a very strong team which have control over their products.</p>
<p>Regarding the fourth point: how many of your emails truly interests you? How many Slack or Teams channels do you read thoroughly? Conversely, how many people actually read your messages in the <em>general</em> channel?</p>
<p>The reality is there's too much information, and people rightfully focus on what's relevant to their job. As discussed earlier, people should ideally search for information they need and subscribe to relevant updates. The only required communication should be explaining how to find this information.</p>
<p>Finally, the last two points about having clear responsibilities and only one responsible per person brings us back to where we started with the Single Responsibility Principle. Each person should have one clear job. Why? As discussed in the communication section, people become bottlenecks when handling too much information. Messages get stuck with them instead of reaching their intended recipients.</p>
<p>Reducing individual responsibilities reduces dependencies, ensuring information reaches its proper destination and allowing people to focus on what they were actually hired to do.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Productivity</category>
            <category>SoftSkills</category>
            <enclosure url="https://www.perssondennis.com/images/articles/three-simple-rules-to-solve-unsolvable-organizational-problems/three-simple-rules-to-solve-unsolvable-organizational-problems.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Three Tricks for Chrome DevTools to Find Logs More Easily]]></title>
            <link>https://www.perssondennis.com/articles/three-tricks-for-chrome-developer-tools-to-find-logs-more-easily</link>
            <guid>https://www.perssondennis.com/articles/three-tricks-for-chrome-developer-tools-to-find-logs-more-easily</guid>
            <pubDate>Sun, 18 Sep 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Tricks to use in Chrome DevTools developer tools. Easy ways to find log output in the console and network tab with colored logs and inverted filter.]]></description>
            <content:encoded><![CDATA[<p>Chrome's developer tools are incredibly powerful. Unfortunately, both the console and network tab tend to be filled up with a lot of logs which are rarely looked at, making it difficult to find what you are there to look at.</p>
<p>Today I will show you three tricks of how you more easily can find the information you are searching for. You may have seen the first tip before, but the second and third ones are lesser known tricks I rarely see people use or write about.</p>
<h2>1. Let Your Logs Stand Out</h2>
<p>Make your console logs look beautiful like this.</p>
<p><img src="https://www.perssondennis.com/images/articles/three-tricks-for-chrome-developer-tools-to-find-logs-more-easily/colored-log.webp" alt="Colored console log">
<em>Colored log in chrome dev tools console</em></p>
<p>While it easy to notice, it's a bit verbose to write. You can create a JavaScript utility function for it to make it easy to write.</p>
<pre><code class="language-javascript">const clog = (log) => console.log(`%c ${log} `, 'background: #ffff00; color: #0012e9');

# Usage
clog("I am colorful!")
</code></pre>
<p><img src="https://www.perssondennis.com/images/articles/three-tricks-for-chrome-developer-tools-to-find-logs-more-easily/colored-log-function.webp" alt="Colored console log function">
<em>You can create a shorthand function for colored console logs</em></p>
<p>Another alternative is to <a href="https://code.visualstudio.com/docs/editor/userdefinedsnippets#_create-your-own-snippets">create a snippet in VS Code</a> so VS Code can autocomplete the code for you when you just write a prefix of your choice.</p>
<p>Below you can see two snippets. The first one, with the prefix <em>clog</em>, will output a colorful log statement for you when you write <em>clog</em> in a file and autocomplete it with the tab key. The second one, named <em>vlog</em>, logs out both a label and a value.</p>
<pre><code class="language-json">{
  "Colored Console": {
    "prefix": "clog",
    "body": [
      "console.log('%c $1 ', 'background: #ffff00; color: #0012e9');",
      "$2"
    ],
    "description": "Log colored message to console"
  },
  "Colored Value Console": {
    "prefix": "vlog",
    "body": [
      "console.log('%c $1 ', 'background: #ffff00; color: #0012e9', $1);",
      "$3"
    ],
    "description": "Log colored message to console and an additional value"
  }
}
</code></pre>
<h2>2. Group Console Messages</h2>
<p>Do you have annoyingly many console messages and don't want to remove them? What if I said you can keep them and still hide them? The solution you search for is console.group. In this way you can for example group logs per file or module. Or maybe wrap all logs used for app initialization in a group.</p>
<p>To wrap some logs in a group, simply write <em>console.group()</em> before your logs and <em>console.groupEnd()</em> after the logs. The web console will fold all the logs there in between.</p>
<p><img src="https://www.perssondennis.com/images/articles/three-tricks-for-chrome-developer-tools-to-find-logs-more-easily/console-group.webp" alt="Console group">
<em>Folded console group in Chrome DevTools console</em></p>
<p>And when you expand the group, it looks like this.</p>
<p><img src="https://www.perssondennis.com/images/articles/three-tricks-for-chrome-developer-tools-to-find-logs-more-easily/console-group-expanded.webp" alt="Console group expanded">
<em>Expanded console group in Chrome DevTools console</em></p>
<h2>3. Filter Network Requests Instead of Searching</h2>
<p>The network tab tends to be very bloated in medium and large sized applications, especially when analytics and log requests are sent remotely. As you might already know, you can filter network requests based on their type, e.g., images or AJAX requests (Fetch/XHR). I would guess you even have found the filter field where you can filter network requests.</p>
<p><img src="https://www.perssondennis.com/images/articles/three-tricks-for-chrome-developer-tools-to-find-logs-more-easily/filter-options.webp" alt="Chrome developer tools filter options">
<em>Filter options under the network tab in Chrome DevTools</em></p>
<p>I have seen a lot of persons using the filter field to search for the request they want to view, it's an easy way to ignore all other kind of spam requests. The cumbersome thing about that is that you have to write a filter term every time you want to find a new request.</p>
<p>To avoid that, I instead use the filter field to filter out logs I never am interested to see. To do so, just check the invert button beside the filter box and enter the words you don't want to see. Separate each word with a whitespace.</p>
<p>In the example below, all requests including the terms "inspect" and ".css" are filtered out. You can keep this filter active to always have a clean network log showing only requests you commonly look at.</p>
<p><img src="https://www.perssondennis.com/images/articles/three-tricks-for-chrome-developer-tools-to-find-logs-more-easily/no-filter.webp" alt="Chrome developer tools no filter">
<em>Example of network tab in Chrome DevTools without a filter</em></p>
<p><img src="https://www.perssondennis.com/images/articles/three-tricks-for-chrome-developer-tools-to-find-logs-more-easily/filter.webp" alt="Chrome developer tools with filter">
<em>Example of the same network tab in Chrome DevTools with a filter filtering out css files and requests with the word "inspect" in its name</em></p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Frontend</category>
            <category>JavaScript</category>
            <category>Productivity</category>
            <enclosure url="https://www.perssondennis.com/assets/blog/default-article-image-unknown.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Top 10 Celebrities Who Code]]></title>
            <link>https://www.perssondennis.com/articles/top-10-celebrities-who-code</link>
            <guid>https://www.perssondennis.com/articles/top-10-celebrities-who-code</guid>
            <pubDate>Sun, 10 Jul 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[10 celebrities who could have a career as developers. Mr. JavaBean, Brad Git, Taylor Swift and many more. Funny programmer jokes and memes.]]></description>
            <content:encoded><![CDATA[<p>Trust me if you want, but here are the ten most famous celebrities who also has a career as developers.</p>
<ol>
<li><strong>Mr. JavaBean</strong> <em>(Java developer)</em></li>
<li><strong>Brad Git</strong> <em>(GitOps expert)</em></li>
<li><strong>Nathalie Postman</strong> <em>(Backend developer)</em></li>
<li><strong>Matt Daemon</strong> <em>(OS programmer)</em></li>
<li><strong>Kanye Jest</strong> <em>(Unit tester)</em></li>
<li><strong>Taylor Swift</strong> <em>(iOS developer)</em></li>
<li><strong>Json Mraz</strong> <em>(Fullstack developer)</em></li>
<li><strong>Vim Diesel</strong> <em>(Unix developer)</em></li>
<li><strong>Jay-C</strong> <em>(C developer)</em></li>
<li><strong>Miley Cypress</strong> <em>(E2E tester)</em></li>
</ol>
<p><img src="https://www.perssondennis.com/images/articles/top-10-celebrities-who-code/top-10-celebrities-who-code-meme.webp" alt="Kanye West and Taylor Swift developer meme">
<em>Kanye Jest ain't testing Swift code</em></p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Jokes</category>
            <enclosure url="https://www.perssondennis.com/images/articles/top-10-celebrities-who-code/top-10-celebrities-who-code.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[What I Learned About Unit Testing Working at Volvo Group]]></title>
            <link>https://www.perssondennis.com/articles/unit-testing-volvo</link>
            <guid>https://www.perssondennis.com/articles/unit-testing-volvo</guid>
            <pubDate>Sun, 13 Mar 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[After having working at Volvo Group I learned how to write good unit tests. I found advantages using React Testing Library instead of Enzyme.]]></description>
            <content:encoded><![CDATA[<p>Recently, I resigned from Volvo Group Connected Solutions AB (VGCS). It was a great workplace, they are developing surveillance systems for truck and bus fleets. The company is as large-scaled as it gets. They run many different kinds of tests on multiple levels and also have many different roles for employed testers. Despite all the tests, a handful of bugs creep all the way to production occasionally. A product cannot get tested enough. You can spend too much time on testing it though, and this article will explain why it happens and how you can avoid it.</p>
<p>All teams on VGCS have their own rules. In the team I worked in we aimed for a 100 % coverage of unit tests. Our team alone had quite a few thousands of unit tests for the code we managed. Other teams were more into integration tests and spent less time on unit tests. Today, I will give you my two cents regarding unit testing.</p>
<h2>Unit Tests Takes Time, Is It Worth It?</h2>
<p>Writing unit tests is a slow process. I would claim experienced developers spend as much time writing unit tests as writing code. Novel developers would spend maybe up to three or four times as much as they write their code, along with that they need support learning it. It's a great opportunity to enlighten them how to write better code that is more easily tested, although I personally prefer doing that during code reviews or weekly tech meetings.</p>
<p>The time it takes to write the tests is not in vain. You will get the time back if you do it wise. Shooting wildly and hoping to catch bugs would not be considered wise. That will do nothing more than emptying your magazine and you will end up with a lot of time spent on nothing.</p>
<p><img src="https://www.perssondennis.com/images/articles/unit-testing-volvo/shooting-wildly.gif" alt="Shooting wildly meme">
<em>Not the best way to catch bugs (image source: GIPHY)</em></p>
<h2>Most Unit Tests Are Useless</h2>
<p>If you aim at 100 % coverage, chances are that most of them are useless. Among all the code I have updated, I have very rarely failed unit tests due to bugs I have introduced in the code. That doesn't mean I haven't introduced bugs, I certainly have.</p>
<p>What I mean is that bugs I introduce almost never is the reason to why the unit tests fail. Rather they fail purely because the updated code isn't compatible with how the tests were written. Let me clarify that with an example.</p>
<pre><code class="language-javascript">import React from 'react'
import { shallow } from 'enzyme'
import TodoList, { Todo } from '../TodoList'

it('should pass title to Todo component', () => {
  const todos = [
    { id: 1, title: 't1' },
    { id: 2, title: 't2' },
  ]
  const wrapper = shallow(&#x3C;TodoList todos={todos} />)
  const firstTodo = wrapper.find(Todo).at(0)
  expect(firstTodo.prop('title')).toEqual('t1')
})
</code></pre>
<p><em>Enzyme test for a todo list. Code available at <a href="https://codesandbox.io/s/1md0wl?file=/src/tests/todo.test.js">CodeSandbox</a> or <a href="https://github.com/PerssonDennis/examples/tree/main/enzyme">GitHub</a>.</em></p>
<p>Above is a typical Jest test for React written with Enzyme. What it does is to render a TodoList component and ensures that the correct title is passed to the first Todo component.</p>
<p>Let's say that we are updating the code, maybe letting each Todo component getting its own title from a context or backend. That means we would stop passing in the title to the Todo component. The test would then fail since we don't pass in a title anymore. Since we don't test anything else, we can simply remove the test, which means it was an unnecessary test to write in the first place.</p>
<p>Maybe the same TodoList component is showing a message when we have no todos and we have written a test that checks that the message is visible. A possible improvement could be to let the user create a new component instead of showing the message. In that case we would once again end up with a test that fails due to a change we actually intended to do.</p>
<p>These kinds of edits are very common. If you follow best practices and keep your components (units) small, most of your test failures will be of this kind. With that design, components will have a narrow use case, and as soon as you change the use case, its unit tests will be invalidated. The tests will fail just because you deliberately chose to design the code or UI in another way, not because you have introduced a bug in the old code. In many cases it isn't sufficient to update the tests and you will have to write completely new tests from scratch.</p>
<p>This means that most tests are only valid for as long as you don't touch the code, and as soon as you update it, you either discard or rewrite the tests. You have basically simply tested that the code continues to work as long as you don't touch it. What do you think Einstein would have said about that?</p>
<p><img src="https://www.perssondennis.com/images/articles/unit-testing-volvo/unit-testing-volvo-einstein-meme.webp" alt="Einstein testing insanity meme">
<em>Definitely a legit Einstein quote</em></p>
<h2>Should You Skip Unit Tests?</h2>
<p>Occasionally we borrow developers from other teams at Volvo Group. One time one of those developers came from a team that preferred integration tests over unit tests. I understand his reasoning and I prefer to <a href="https://www.perssondennis.com/articles/mvp">keep stuff minimal</a> and keeping development at a fast pace, I could to some extent agree with him. But in large scaled projects <a href="https://stackoverflow.com/questions/1788436/why-using-integration-tests-instead-of-unit-tests-is-a-bad-idea">a lot of people think he is wrong</a> in that, you should really have <a href="https://softwareengineering.stackexchange.com/questions/204786/do-i-need-unit-test-if-i-already-have-integration-test">both unit and integration tests</a>.</p>
<h2>When Are Unit Tests Useful?</h2>
<p>When I previously accused unit tests to be useless I never meant all of them are. What I was talking about was that it is inefficient to test simple code that doesn't include very much logic or code that will change drastically whenever you make an update to it. That kind of code is common when it comes to UI components or boilerplate code. Not all code looks like that.</p>
<p>Math functions, utils functions, hooks and different kind of pure functions like reducers are all perfect examples of when you should write unit tests. Sometimes they contain complex logic which you absolutely should test. Other functions may have many edge cases to tests. Maybe one of the most common causes to bugs in Javascript is when dealing with <a href="https://blog.sapegin.me/all/avoid-mutation/">mutations</a>. With unit tests that's very fast and easy to test.</p>
<p>These kinds of functions should be tested even if you only plan to write them once and then never updating them. It is ridiculously easy to introduce bugs in logic-heavy code and you can't always test it graphically to see that it works. I would strongly recommend Test Driven Development, <a href="https://en.wikipedia.org/wiki/Test-driven_development">TDD</a>, when writing that kind of code. TDD forces you to think of edge cases on beforehand which often can save you time already when writing the code. Without it, you may end up rewriting the code multiple times just because you find new edge-cases with every new solution you come up with.</p>
<h2>How to Write Good Unit Tests</h2>
<p>I have already touched upon what good unit tests are. When testing logical code, it's important to test edge-cases and test that functions doesn't mutate the code. That can be achieved by invoking functions multiple times or by using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality">strict equal operator</a> in Javascript.</p>
<p>I won't go into any more details there. Instead, I want to turn back to testing UI components again, that's the kind of unit testing I claimed to be useless in many cases. In details, we will discuss the concepts of shallow and mounting tests with <a href="https://enzymejs.github.io/enzyme/">Enzyme</a>, and also interactional unit testing with <a href="https://testing-library.com/docs/dom-testing-library/intro">Testing Library</a>. Testing Library can be used with many libraries, <a href="https://testing-library.com/docs/react-testing-library/intro/">including React</a>.</p>
<h3>Unit Testing with Enzyme</h3>
<p>If you don't know the difference between shallow and mount component testing, the main difference is that when you test a component shallowly you only test that component's logic without rendering its child components. Mounting will instead render the full DOM tree including all child components which aren't explicitly mocked. A more detailed comparison between Enzyme's shallow and mount can be <a href="https://wasuradananjith.medium.com/testing-with-jest-and-enzyme-in-react-part-4-shallow-vs-mount-in-enzyme-d60cad73f85c">found here</a>.</p>
<h3>Enzyme vs React Testing Library</h3>
<p>Regarding the differences between Enzyme and React Testing Library, one can see at <a href="https://www.npmtrends.com/@testing-library/react-vs-enzyme">npm trends</a> that Testing Library is more used nowadays. Meanwhile Enzyme is slowly dying since it isn't being maintained and <a href="https://github.com/enzymejs/enzyme/issues/2429">lacks unofficial support for React 17</a>.</p>
<p><img src="https://www.perssondennis.com/images/articles/unit-testing-volvo/unit-testing-volvo-npm-trends-enzyme-vs-rtl.webp" alt="Npm trends enzyme vs react testing library">
<em>All time npm trends - Enzyme vs React Testing Library</em></p>
<h3>Shallow Tests</h3>
<p>Many people prefer shallow testing. Not all are of the same opinion but personally I would recommend it over mounting components, or maybe I would recommend to use a mix of them. What shallow testing means is that you basically test each component's logic without caring about how it would integrate with other components when you run your code.</p>
<p>Maybe the non-integrating part doesn't sound very inviting, we will come to that. At least shallow testing tests the component itself and if you test every component fully you will get a 100 % test coverage in the end. If you update your components, you are likely to rewrite your complete tests as I talked about earlier in this article.</p>
<h3>Mounting Tests</h3>
<p>Mounting tests are very much like shallow tests. The positive thing is that mounting also tests the integrations to child components. You can ensure that the components work together.</p>
<p>Since you will test child components when testing component, you will end up with a lot more than 100 % coverage for some deeply nested child components. A button that is used in tenth or hundredth of components will be tested over and over and over again. That's where the drawback hides. At a first glance it doesn't seem to hurt very much. But wait until you update that button component in a way that affects all components that uses it. You will end up with failed unit tests in all those tens or hundreds of components you had written tests for.</p>
<h3>Interactional Tests</h3>
<p>The third type of tests I wanted to bring up is unit tests that focuses on interactions. The <a href="https://testing-library.com/docs/guiding-principles">idea behind it</a> is to test the components in their real environment based on what really happens when you interact with the DOM nodes. In that way, we can test React components in their natural environment as they would behave in a real browser. It's one step closer to integration tests even though we still are testing units.</p>
<p>Interactional tests in React Testing Library will behave more like Enzyme's mount tests than the shallow tests, since it will render child components as well. You are of course free to mock whatever component you want to mock, so it's completely possible to tests all components shallowly if you would prefer that, just mock all child components.</p>
<p>Not convinced yet? Let's continue, I'm getting to it. The huge advantage I like about interactional unit testing is that you often will be able to keep your unit tests untouched even if you refactor components, or even multiple components. Just like if you would have tested your code with an integration testing tool like <a href="https://www.cypress.io/">Cypress</a> or <a href="https://www.selenium.dev/documentation/">Selenium</a>.</p>
<p>Let's look at the Todo example again. This time using React Testing Library.</p>
<pre><code class="language-javascript">import React from "react"
import { render } from "@testing-library/react"
import TodoList from "../TodoList"

test("it should pass title to Todo component", () => {
  const todos = [
    { id: 1, title: "t1" },
    { id: 2, title: "t2" }
  ]
  const { getAllByRole } = render(&#x3C;TodoList todos={todos} />)
  const todoItems = getAllByRole("listitem")
  expect(todoItems[0]).toHaveTextContent("t1")
})
</code></pre>
<p><em>React Testing Library test for a todo list. Code available at <a href="https://codesandbox.io/s/dc4tnp?file=/src/__tests__/todo.js">CodeSandbox</a> or <a href="https://github.com/PerssonDennis/examples/tree/main/react-testing-library">GitHub</a>.</em></p>
<p>With the code above, we can update the TodoList component and Todo component in any way we want without having to update the test, as long as we keep using list items for the todo items. If you think it is annoying to depend on list items, we can remove that dependency as well. Testing Library allows looking at data-test-id:s or pure texts as well. Read about <a href="https://testing-library.com/docs/queries/about">supported queries here</a>. Here's some examples of what you can do.</p>
<pre><code class="language-javascript">// Checking presence of text using a regex.
getByText(/t1/i)
// Checking for data-test-id with the text.
expect(getByTestId('todo-item-1')).toHaveTextContent('t1')
// Checking for a button with the text "Press me".
expect(getByRole('button')).toHaveTextContent('Press me')
</code></pre>
<p><em>Code available at <a href="https://codesandbox.io/s/dc4tnp?file=/src/__tests__/todo.js">CodeSandbox</a> or <a href="https://github.com/PerssonDennis/examples/tree/main/react-testing-library">GitHub</a>.</em></p>
<h2>Conclusion</h2>
<p>Unit tests and integration tests are both necessary. Keeping unit tests at a 100 % coverage is not a bad thing. But if you don't test your code in an efficient manner, it will cost you tremendous of time. Be smart when designing your unit tests and choose the right tools for it.</p>
<p>Code with a lot of logic and calculations are easy to mess up, and it's hard to think of all edge cases and to always have mutability in mind. Test that kind of code thoroughly and preferably with a TDD approach to force you to consider all edge cases before you start writing the code.</p>
<p>When it comes to testing UI and React components you should really think twice about how to write your tests. Using React Testing Library instead of Enzyme is a great start. Not only because Enzyme is poorly maintained, but rather because Testing Library approaches unit testing in a more efficient way. Testing library focuses on testing DOM elements and elements visible to the user. That kind of interactive unit testing is also possible to write using Enzyme, but Enzyme isn't written for that purpose.</p>
<p>By focusing on DOM elements or the UI visible to the user, rather than the implemented components, you can avoid rewriting your tests over and over again. The tests can then fulfil their purpose of catching bugs whenever the code is being updated. When focusing too much on testing implementation details you will end up rewriting your tests every time you update the code, which makes the unit tests more or less useless.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Architecture</category>
            <category>Frontend</category>
            <category>JavaScript</category>
            <category>Productivity</category>
            <category>Testing</category>
            <enclosure url="https://www.perssondennis.com/images/articles/unit-testing-volvo/unit-testing-volvo-npm-trends-enzyme-vs-rtl.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[useEffect - The Hook React Never Should Have Rendered]]></title>
            <link>https://www.perssondennis.com/articles/useeffect-the-hook-react-never-should-have-rendered</link>
            <guid>https://www.perssondennis.com/articles/useeffect-the-hook-react-never-should-have-rendered</guid>
            <pubDate>Sun, 07 May 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[This is why you always should avoid using the useEffect hook in React and how to avoid using useEffect in your components. ✓ React ✓ useEffect ✓ Hooks]]></description>
            <content:encoded><![CDATA[<p>React was once a fantastic library. Quick to learn, easy to customize and made it easy for you to write clean code. At least it used to be, at the time when they first white-painted the library with hooks instead of the old browny class components.</p>
<p>When React repainted the library, they did a mistake. They left a red brush in the white bucket which they now are using to paint the whole library into a pink disaster. React repainted their future with React 18, but in that picture, the useEffect hook doesn't belong.</p>
<p>I think it's time to get rid of that dangerous and disputed hook, but until then, I'll give you some tips of how to use it without getting pink paint all over your code.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/useeffect-the-hook-react-never-should-have-rendered#useeffect-the-red-brush-in-the-white-bucket">useEffect - The Red Brush in the White Bucket</a></li>
<li><a href="https://www.perssondennis.com/articles/useeffect-the-hook-react-never-should-have-rendered#react-keeps-painting-with-the-red-brush">React Keeps Painting With the Red Brush</a></li>
<li><a href="https://www.perssondennis.com/articles/useeffect-the-hook-react-never-should-have-rendered#the-proper-way-to-use-useeffect">The Proper Way To Use useEffect</a></li>
<li><a href="https://www.perssondennis.com/articles/useeffect-the-hook-react-never-should-have-rendered#importance-of-idempotency">Importance of Idempotency</a></li>
<li><a href="https://www.perssondennis.com/articles/useeffect-the-hook-react-never-should-have-rendered#tldr">TL;DR</a></li>
</ul>
<h2>useEffect - The Red Brush in the White Bucket</h2>
<p>React have added a wonderful useEffect hook to their bucket of hooks. Only problem, it doesn't belong there. When React 18 first came, the web exploded with warnings about useEffect, claiming it shouldn't be used and that we should not think about React in life cycles.</p>
<p>Truth is, useEffect was an issue long before that. It was very common to see developers <a href="https://stackoverflow.com/a/58579462/7584643">leaving out the dependency array</a> when they intended to have an empty dependency array, which causes the useEffect to be effectively useless.</p>
<p>And since React unfortunately leaves a lot of the optimization of the code to the developer, you may need to optimize your code using useCallback, otherwise you can <a href="https://stackoverflow.com/q/62601538/7584643">get stuck in infinite rendering loops</a>. Or, in a similar way, it can happen that your code will run on every render.</p>
<pre><code class="language-javascript">const ExampleComponent = () => {
  // This function will be triggered on every render.
  const getData = () => {
    // Get some data from server.
  }

  useEffect(() => {
    getData()
  }, [getData]);

  return &#x3C;div>Example&#x3C;div>
}
</code></pre>
<pre><code class="language-javascript">const ExampleComponent = () => {
  // Solution is to optimize the code with a useCallback...
  const getData = useCallback(() => {
    // Get some data from server.
  }, [])

  useEffect(() => {
    // We could also place the getData function in the useEffect,
    // with the drawback of readability if the function is big.
    // const getData = () => { ... }

    getData()
  }, [getData]);

  return &#x3C;div>Example&#x3C;div>
}
</code></pre>
<p>In earlier days, there were also a lot of articles about why you always should add all dependencies to your useEffect, even when you don't want the effect to run when some of the dependencies changes. That lead to ugly hacks with if statements to avoid code from running.</p>
<pre><code class="language-javascript">import { useEffect } from 'react'

const Component = ({ someOtherDependency }) => {
  const [value, setValue] = useState(null)

  useEffect(() => {
    // A common seen if statement added just to
    // prevent the effect from running.
    if (value === null) {
      setValue("someValue")
    }
  }, [value, someOtherDependency])

  return &#x3C;div>Example&#x3C;div>
}
</code></pre>
<p>Other alternatives were more clean, but only usable in a few cases. Below example shows a trick to avoid adding a state variable to the dependency array.</p>
<pre><code class="language-javascript">import { useEffect } from 'react'

const Component = () => {
  const [count, setCount] = useState(0)

  useEffect(() => {
    // By passing a function to setCount, we can access its old
    // value without adding count to the dependency array.
    setCount(oldCount => oldCount + 1)
  }, [])

  return &#x3C;div>Example&#x3C;div>
}
</code></pre>
<h2>React Keeps Painting With the Red Brush</h2>
<p>If it wasn't difficult enough to make use of useEffect in React 17, React 18 made it even more troublesome. The main problem with the hook today isn't ugly if statements, missing dependencies or the fact that you should add all dependencies to the dependency array regardless of if you want to or not. Fact is, even if you do all of that, your useEffect may still run several times, due to concurrent rendering.</p>
<p>Luckily, React creators noticed concurrent mode caused a lot of concerns, so they solved it by <a href="https://react.dev/blog/2022/03/29/react-v18#gradually-adopting-concurrent-features">only enabling it in parts of your code that uses the new React 18 features</a>. A pretty good solution I would say. Pretty.</p>
<p>Problem is, the <a href="https://react.dev/reference/react/useEffect">React docs for useEffect</a> is quite extensive. When opting in for the new features, and thereby turning on concurrent mode, the <a href="https://react.dev/learn/synchronizing-with-effects">docs for useEffect gets even more complicated</a>. One page describing useEffect is not enough, you need <a href="https://react.dev/learn/you-might-not-need-an-effect">another long page</a>, and <a href="https://react.dev/learn/lifecycle-of-reactive-effects">another one</a>, and <a href="https://react.dev/learn/separating-events-from-effects">another</a>, and <a href="https://react.dev/learn/removing-effect-dependencies">another</a>...</p>
<p>You have to think about if concurrent mode is enabled. You have to think of all the pitfalls. You have to think of all the optimizations. You have to think about what is best practice. You have to think about how the component renders even if you are encouraged not to think in terms of the old class life cycle methods such as componentDidMount and componentDidUpdate.</p>
<p>React is no longer a framework that has a low learning code. It's quick to start building with, but it takes a long time to learn how to write it correctly without introducing plenty of bugs.</p>
<p><img src="https://www.perssondennis.com/images/articles/useeffect-the-hook-react-never-should-have-rendered/two-architects-meme.webp" alt="Two architectures meme">
<em>Visual representation of React. Can you spot the useEffect?</em></p>
<h2>The Proper Way To Use useEffect</h2>
<p>React is getting a lot of new good features. Meanwhile, useEffect is becoming more and more dangerous. This article would become way too long if I continued describing issues with useEffect, just look at how big documentation there is for it. For that reason, I will give you one single tip for how to handle useEffect.</p>
<pre><code>Let useEffect render.
</code></pre>
<p>With letting it render, I don't mean you voluntarily should let it render on every rendering. What I mean is that you should not be afraid of letting it render too many times. Add all dependencies to its dependency array and let it do its work every time it runs.</p>
<p>What you shouldn't do, is to prevent the effect from running in certain use cases. The below code is awful and extremely bug prone.</p>
<pre><code class="language-javascript">const getDataFromBackend = () => {
  // Some code.
}

const ExampleComponent = ( {
  someVariable,
  anotherVariable,
  thirdVariable
}) => {
  useEffect(() => {
    if (someVariable === null) {
      if (anotherVariable > 10
        &#x26;&#x26; (thirdVariable !== undefined || thirdVariable !== null)
        ) {
        getDataFromBackend()
      }
    }
  }, [someVariable, anotherVariable, thirdVariable]);

  return &#x3C;div>Example&#x3C;div>
}
</code></pre>
<p>The ugly code above should look like this instead:</p>
<pre><code class="language-javascript">const getDataFromBackend = () => {
  // Some code.
}

const ExampleComponent = ( {
  someVariable,
  anotherVariable,
  thirdVariable
}) => {
  useEffect(() => {
    getDataFromBackend()
  }, [someVariable, anotherVariable, thirdVariable]);

  return &#x3C;div>Example&#x3C;div>
}
</code></pre>
<p>But? We cannot spam backend with plenty of network requests? Can we?</p>
<p>No, you should not spam backend. What you should do, is to make sure to write getDataFromBackend only fetch data when necessary. Not with the help of if statements, but by using caches, <a href="https://www.perssondennis.com/articles/react-hooks-use-throttled-value-and-use-throttled-function#what-is-throttle-and-debounce">debounce or throttling</a>.</p>
<p>Hooks like <a href="https://swr.vercel.app/">useSWR</a>, <a href="https://tanstack.com/query/v4/docs/react/reference/useQuery">useQuery</a> and <a href="https://redux-toolkit.js.org/rtk-query/usage/queries">RTK Query</a> handle such things for you, with some need for configurations. Using hooks like those are quite essential nowadays, not only because of issues with useEffect, but also because they include lots of logic you otherwise would have to implement yourself, with retries and state handling.</p>
<h2>Importance of Idempotency</h2>
<p>Under previous heading we could see how to properly fetch data in a useEffect. I also claimed that you should avoid preventing useEffect from running. In some cases, that might not feel possible. Sometimes we cannot use caches or debounce, that may be the case when sending POST requests to backend.</p>
<p>PUT requests should be fine, because they are <a href="https://stackoverflow.com/questions/1077412/what-is-an-idempotent-operation/1077421#1077421">idempotent</a> by definition, meaning, it doesn't matter how many times an action is triggered, the result of calling it multiple times is the same as calling it a single time.</p>
<p>Sending POST request to a server are not necessarily idempotent, calling it multiple times may cause a unintended behavior or causing bugs. How can we handle that if useEffect can be triggered multiple times?</p>
<p>Answer is, try to avoid using a useEffect at all. There are multiple ways to do that, but it depends on the situation. If the function isn't dependent on the React component's state, it is <a href="https://www.perssondennis.com/articles/react-anti-patterns-and-best-practices-dos-and-donts#do-not-use-useeffect-to-initiate-external-code">possible to lift out the function out of the component</a>.</p>
<p>Another example is when triggering effects on user interactions. In that case, you don't need an effect at all. I often see code similar to the code below.</p>
<pre><code class="language-javascript">import { useEffect } from 'react'
import { sendPostRequest } from '/services'

const Component = () => {
  const [buttonClicked, setButtonClicked] = useState(false)

  // Send a request when the button has been clicked.
  useEffect(() => {
    if (buttonClicked) {
      sendPostRequest()
    }
  }, [buttonClicked])

  return &#x3C;button onClick={() => setButtonClicked(true))}>Click me&#x3C;/button>
}
</code></pre>
<p>The thing is, you don't need that useEffect, not even the useState. The code above should look like the code below.</p>
<pre><code class="language-javascript">import { useEffect } from 'react'
import { sendPostRequest } from '/services'

const Component = () => {
  // This is what you should do if you really want to send the
  // request when the button is clicked.
  return &#x3C;button onClick={() => sendPostRequest())}>Click me&#x3C;/button>
}
</code></pre>
<p>There are many other ways to get rid of useEffects, you can google how avoid useEffect. But sometimes you do need the effect, and in that case, you should make sure the code within it is idempotent, and then let the effect run as it wants to.</p>
<h2>TL;DR</h2>
<p>React is getting more and more difficult to learn and use. Optimizations are left up to developers and it gets more and more easy to write React code in a wrong way. React has very soon a steep learning curve and the useEffect is one of the main reasons to that.</p>
<p>To make the best out of the situation, one should try not to care too much about optimizing useEffects - let useEffect run many times. Then make sure the code within the effect is idempotent. For fetching data, you have really nice hooks like like useSWR, useQuery and RTK Query which helps you cache requests.</p>
<p>If a cache isn't the solution, a debounce or throttle may be. Many times you can even remove the useEffect completely since the code can be rewritten in a better way without it.</p>
<p>One day, we may see a React without the useEffect, and maybe even without useCallback? Or maybe the issues with the useEffect hook will keep on growing? In the end, I would say React is one hook away from being a wonderful framework.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Architecture</category>
            <category>Frontend</category>
            <category>Hooks</category>
            <category>JavaScript</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/useeffect-the-hook-react-never-should-have-rendered/useeffect-the-hook-react-never-should-have-rendered.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[What If Animals Could Code...]]></title>
            <link>https://www.perssondennis.com/articles/what-if-animals-could-code</link>
            <guid>https://www.perssondennis.com/articles/what-if-animals-could-code</guid>
            <pubDate>Sun, 07 Aug 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[What if animals could code? Funny programming jokes and development memes. Snakes code in Python and you wouldn't hire bugs!]]></description>
            <content:encoded><![CDATA[<p>Okay, here we go again! In the last article in this series you came up with amazingly 40 hilarious comments on the topic <a href="https://dev.to/perssondennis/top-10-celebrities-who-code-7g7">celebrities who code</a>. I look forward to see what you geniuses may come up with this time.</p>
<p>So here's today's topic. When YouTube goes down, highly trained monkeys join up to fix the problem as fast as possible. Monkeys may be the only non-human animal that codes, but what would other animals do if they were developers?</p>
<p><img src="https://www.perssondennis.com/images/articles/what-if-animals-could-code/youtube-code-monkeys.webp" alt="YouTube monkey business">
<em>I believe them, why would they lie?</em></p>
<p><strong>Use your imagination and comment funny suggestions of what it could be like to hire an animal as a developer</strong>. Here's some suggestions of mine, feel free to reuse the same animals if you want to.</p>
<ol>
<li><strong>Pandas</strong> <em>- would be pandastic programmers!</em></li>
<li><strong>Snails</strong> <em>- would always be working from home</em></li>
<li><strong>Snakes</strong> <em>- do I need to mention Python?</em></li>
<li><strong>Bugs</strong> <em>- I have a feeling they would struggle finding a workplace who wants them</em></li>
<li><strong>Cows</strong> <em>- they are more into hardware, they follow mooooores law</em></li>
<li><strong>Lions</strong> <em>- strong partners for a startup, but expect them to take the lion share of the profit</em></li>
<li><strong>Sloths</strong> <em>- would probably benefit using Copilot</em></li>
<li><strong>Sheep</strong> <em>- may be sheep to hire, but is it worth it?</em></li>
<li><strong>Cats</strong> <em>- wouldn't touch code, they would promote themselves to managers</em></li>
<li><strong>Pigs</strong> <em>- dirty code, but they are actually pretty clever</em></li>
<li><strong>Moles</strong> <em>- they would love to C#</em></li>
<li><strong>Bats</strong> <em>- as long as you are fine with putting your screen upside down, they could maybe be worth hiring</em></li>
<li><strong>Dogs</strong> <em>- would probably be their best. day. ever.</em></li>
<li><strong>Whales</strong> <em>- hire one and you boss will call you in to talk about office expenses</em></li>
</ol>
<p><img src="https://www.perssondennis.com/images/articles/what-if-animals-could-code/koalificated-meme.webp" alt="Developer animal meme">
<em>I'm sorry Mr. Koala, but you always do the bear minimum of work</em></p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Jokes</category>
            <enclosure url="https://www.perssondennis.com/images/articles/what-if-animals-could-code/what-if-animals-could-code.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[What If CSS Properties Had Personalities]]></title>
            <link>https://www.perssondennis.com/articles/what-if-css-properties-had-personalities</link>
            <guid>https://www.perssondennis.com/articles/what-if-css-properties-had-personalities</guid>
            <pubDate>Sun, 28 Sep 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[What if CSS properties had personalities? Funny CSS jokes about CSS properties as people. A series of funny programming jokes and developer humor.]]></description>
            <content:encoded><![CDATA[<p>Have you ever wondered what your CSS properties would be like if they were real people? I mean, with all the time you spend with them, don't you wonder what they would be like in real life?</p>
<p>Well, I do. Now let me introduce you to some of the persons in the CSS world to see if it feels like you already know them or not!</p>
<h2>display: flex - The Yoga Instructor</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-css-properties-had-personalities/flex-yoga-instructor.webp" alt="flex yoga instructor">
<em>Just lay-out a yoga mat and breathe</em></p>
<p>Meet <strong>display: flex</strong>, the yoga instructor of CSS. Always talking about alignment, balance, and flow.</p>
<p>"Let's center everything with perfect harmony," they say while making your content bend in ways you never thought was possible.</p>
<p>They're surprisingly flexible (pun intended) and can adapt to any situation they face. If you ever need some help, you can always count on Flex.</p>
<h2>position: absolute - The Loner</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-css-properties-had-personalities/absolute-loner.webp" alt="absolute loner">
<em>Create your own path, it will save you from the queues</em></p>
<p><strong>position: absolute</strong> is that friend who always sits in the corner at parties. They don't follow the normal flow of conversation, they just put themselves wherever they want and expect everyone else to work around them.</p>
<p>They're incredibly independent but also kind of needy, they will not do what you want if you don't give their parents the position they require.</p>
<p>Meanwhile, they'll ignore all the normal rules and just float around doing their own thing. They're that one person in the year book photo who stands completely separate from everyone else.</p>
<h2>z-index: 9999 - The Attention Seeker</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-css-properties-had-personalities/z-index-attention-seeker.webp" alt="z-index attention seeker">
<em>I'm not a show off - I'm a show on!</em></p>
<p><strong>z-index: 9999</strong> is that person who always has to be in the front of every photo. They're constantly seeking attention and will do anything to look smart and glorious.</p>
<p>They're basically that friend who always cuts into conversations to share their latest achievement, no matter what the discussion was about.</p>
<h2>overflow: hidden - The Secretive One</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-css-properties-had-personalities/overflow-hidden-secretive.webp" alt="overflow hidden secretive">
<em>Out of sight, out of mind</em></p>
<p><strong>overflow: hidden</strong> is the person who sweeps everything under the rug. They're that friend who always cleans up before you visit, but you know their closet is a total mess.</p>
<p>They're actually pretty helpful when you have content that's acting up, but sometimes they hide things you actually want to see. And when you send them a long text message they read half of it and ignores the rest.</p>
<h2>margin auto - The Peacemaker</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-css-properties-had-personalities/margin-auto-peacemaker.webp" alt="margin auto peacemaker">
<em>The best age is the aver-age</em></p>
<p><strong>margin: auto</strong> is the peacemaker of CSS. They're always trying to find the middle ground and keep everyone happy.</p>
<p>They're immensely diplomatic and can resolve almost any conflict, they simply check where all parts stands and find a solution where everyone can meet in the middle.</p>
<p>But remember, don't ask them to handle vertical centering, that's when they stand immobilized and silent having no idea how to respond.</p>
<h2>border-radius: 50% - The Sensitive Person</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-css-properties-had-personalities/border-radius-sensitive-person.webp" alt="border radius sensitive person">
<em>I hope to see you around!</em></p>
<p><strong>border-radius: 50%</strong> is the sensitive person who easily gets hurt by sharp comments and never would harm anyone.</p>
<p>They're optimistic and careful people who would never dare to live on the edge. Subconsciously they always choose the round table at restaurants even if they are already taken and plush animals are their favorite animals.</p>
<h2>opacity: 0.5 - The Ghost</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-css-properties-had-personalities/opacity-ghost.webp" alt="opacity ghost">
<em>🤫</em></p>
<p><strong>opacity: 0.5</strong> is the ghost of CSS. They're there, but they're not really there.</p>
<p>They are shy people who nervously whispers "I'm just passing through" while they hurry past you. When they write you a note they write it to be barely visible so you have to squint to read the text.</p>
<p>They are always with you but they rarely speak a word, and when they do, they whisper so low so you wonder if they really said something.</p>
<h2>transform: rotate(45deg) - The Dizzy One</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-css-properties-had-personalities/transform-rotate-dizzy.webp" alt="transform rotate dizzy">
<em>Let's see it from the tilted side...</em></p>
<p><strong>transform: rotate(45deg)</strong> is that person who's always tilting their head and seeing things from different angles. "Everything looks better when it's rotated," they say while making your text completely unreadable.</p>
<p>They're creative and see the world differently than everyone else. They're that friend who always has a unique perspective on things, even if it's sometimes a bit confusing. Just don't ask them to do your home assignment - the teacher will know you didn't write it.</p>
<h2>@media queries - The Chameleon</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-css-properties-had-personalities/media-queries-chameleon.webp" alt="media queries chameleon">
<em>One size doesn't fit all</em></p>
<p><strong>@media queries</strong> are the chameleons of CSS. They can adapt to any situation and look good on any picture.</p>
<p>They're very flexible and always thinking about how other people experience situations. They're that friend who can fit in with any crowd and always knows how to adapt to different situations.</p>
<p>It doesn't matter if you reach out to them in the middle of the night, they are always very responsive. And sometimes when you feel the world is black and white, it can be kinda comfortable to hear them describe all their different point of views.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Jokes</category>
            <category>UI</category>
            <enclosure url="https://www.perssondennis.com/images/articles/what-if-css-properties-had-personalities/what-if-css-properties-had-personalities.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[What If Movie Characters Had LinkedIn Profiles]]></title>
            <link>https://www.perssondennis.com/articles/what-if-movie-characters-had-linkedin-profiles</link>
            <guid>https://www.perssondennis.com/articles/what-if-movie-characters-had-linkedin-profiles</guid>
            <pubDate>Sun, 04 Sep 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[What if movie character's had LinkedIn profiles? What would their banners look like? See Batman's, Sheldon Coopers and more funny LinkedIn profiles.]]></description>
            <content:encoded><![CDATA[<p>Have you ever wondered what Sheldon Cooper's LinkedIn profile would look like? Oh, stupid question. Of course you have! I will here now present eight well-known movie character's professional profiles.</p>
<h2>Sheldon Cooper</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-movie-characters-had-linkedin-profiles/sheldon-cooper-linkedin-profile.webp" alt="Sheldon Cooper&#x27;s LinkedIn profile">
<em>Sheldon Cooper's LinkedIn profile</em></p>
<p>We know him as the childish genius who repeatedly fails to decipher sarcasm. As one of the main characters in The Big Bang Theory, Sheldon Cooper shouldn't have to live without a LinkedIn profile. The question is, would he use LinkedIn when it lacks a bazinga reaction?</p>
<h2>Mulan</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-movie-characters-had-linkedin-profiles/mulan-linkedin-profile.webp" alt="Mulan&#x27;s LinkedIn profile">
<em>Mulan's LinkedIn profile</em></p>
<p>Loyal, brave and true. Mulan has done more for women and the Emperor than most people. Without any need for recognition or compensation she voluntarily fought against the Huns to protect her family. It is now time for her to step into the spotlights and enter LinkedIn.</p>
<h2>Builder Bob</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-movie-characters-had-linkedin-profiles/builder-bob-linkedin-profile.webp" alt="Builder Bob&#x27;s LinkedIn profile">
<em>Builder Bob's LinkedIn profile</em></p>
<p>If one would ask Bob if he wanted a LinkedIn profile, he would probably answer with a counter question: Can we fix it? And the answer is, yes we can! LinkedIn profiles normally don't have the profile image centered, but we can fix that too! We can build a LinkedIn where it is possible!</p>
<h2>Batman</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-movie-characters-had-linkedin-profiles/batman-linkedin-profile.webp" alt="Batman&#x27;s LinkedIn profile">
<em>Batman's LinkedIn profile</em></p>
<p>Does Batman have a LinkedIn profile? I don't know, I'm not on the <a href="https://dcau.fandom.com/wiki/List_of_people_who_know_Batman%27s_secret_identity">list of people who knows his true identity</a>. Batman's professional LinkedIn profile could have looked like above though. Just as with Builder Bob, it's no issue for Batman to have his profile picture right adjusted, he is wealthy enough to buy LinkedIn.</p>
<h2>Aquaman</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-movie-characters-had-linkedin-profiles/aquaman-linkedin-profile.webp" alt="Aquaman&#x27;s LinkedIn profile">
<em>Aquaman's LinkedIn profile</em></p>
<p>Judging by his LinkedIn banner, Aquaman is a bit less picky than Batman. Being the <a href="https://movieweb.com/richest-superheroes-movies/">richest superhero of his time</a>, he could beneficially have spent a bit more money on the banner design. Presumably, he has even skimped on the translation costs, because that website URL doesn't look very accurate.</p>
<h2>Homer Simpson</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-movie-characters-had-linkedin-profiles/homer-simpson-linkedin-profile.webp" alt="Homer Simpson&#x27;s LinkedIn profile">
<em>Homer Simpson's LinkedIn profile</em></p>
<p>It's no secret Homer Simpson appreciates donuts, and he's probably better of marketing himself for that on LinkedIn than to <a href="https://simpsons.fandom.com/wiki/List_of_Homer%27s_jobs">list all the jobs he has had</a>. There are likely not a lot of recruiters searching for donut experts on LinkedIn, but with all his experience, recruiters would constantly stumble onto his profile and eventually he could become LinkedIn's own Rick Roll.</p>
<h2>Phoebe Buffay</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-movie-characters-had-linkedin-profiles/phoebe-buffay-linkedin-profile.webp" alt="Phoebe Buffay&#x27;s LinkedIn profile">
<em>Phoebe Buffay's LinkedIn profile</em></p>
<p>Can you play guitar with a bear claw? Or with a turkey leg? No? If you want to learn, you can go to Phoebe. But please remember, do not touch a guitar while learning the chords! Joey <a href="https://www.youtube.com/watch?v=xLNJfAYgvkw">learned that lesson the embarrassing way</a>, let's not question Phoebe's methods one more time.</p>
<h2>La Linea</h2>
<p><img src="https://www.perssondennis.com/images/articles/what-if-movie-characters-had-linkedin-profiles/la-linea-linkedin-profile.webp" alt="La Linea&#x27;s LinkedIn profile">
<em>La Linea's LinkedIn profile</em></p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Jokes</category>
            <category>UI</category>
            <enclosure url="https://www.perssondennis.com/images/articles/what-if-movie-characters-had-linkedin-profiles/what-if-movie-characters-had-linkedin-profiles.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[What If You Would Marry a Programming Language]]></title>
            <link>https://www.perssondennis.com/articles/what-if-you-would-marry-a-programming-language</link>
            <guid>https://www.perssondennis.com/articles/what-if-you-would-marry-a-programming-language</guid>
            <pubDate>Sun, 26 Feb 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[What if you would marry a programming language? What programming language would you marry? A series of funny programming jokes and developer humor.]]></description>
            <content:encoded><![CDATA[<p>What if programming languages were human and you could marry them? What could you expect in relationships like that? This is what I think it would be like to live with four of the most known programming languages.</p>
<h2>In the Kitchen</h2>
<p><strong>Java</strong>:</p>
<p>A good baker following recipes in detail, but will need an apron, food processor, colander, steak hammer and a cork screw to even make a sandwich.</p>
<p><strong>JavaScript</strong>:</p>
<p>JavaScript doesn't care if the only ingredients you have at home is chocolate sauce, canned tuna and some potato peels from the sink, it's fine to combine!</p>
<p><strong>Python</strong>:</p>
<p>Python gladly accepts any meal request you have and lets C prepare it for you.</p>
<p><strong>C++</strong>:</p>
<p>C++ makes sure you have whatever utensil you may need, but don't expect any help cooking the food. And don't you dare buying meat that is already minced, that's not why C++ bought you that meat grinder!</p>
<p><img src="https://www.perssondennis.com/images/articles/what-if-you-would-marry-a-programming-language/potato-peel.webp" alt="Too much potato meme">
<em>What's not to like? Chocolate good. Tuna good. Potato peel...</em></p>
<h2>In the Bedroom</h2>
<p><strong>Java</strong>:</p>
<p>Just bring the necessary tools and Java can run anywhere. No need to keep it inside, it works just as fine outside the windows.</p>
<p><strong>JavaScript</strong>:</p>
<p>JavaScript doesn't understand the importance of foreplay, it believes it can get you ready during the act and finish just in time.</p>
<p><strong>Python</strong>:</p>
<p>Can probably give you what you want, otherwise it works perfectly to invite a third party.</p>
<p><strong>C++</strong>:</p>
<p>Do I really need to say anything more than that C++ has made a great reputation from being quick?</p>
<h2>First Meeting With Family</h2>
<p><strong>Java</strong>:</p>
<p>Don't be fooled by your great connection with Java, if your parents aren't the right types, Java will refuse to meet them.</p>
<p><strong>JavaScript</strong>:</p>
<p>Even though there are other ways, JavaScript is most comfortable when meeting your family over the internet.</p>
<p><strong>Python</strong>:</p>
<p>There's a great chance your parents will like Python. Unfortunately, there's a risk they may find Python being quite slow.</p>
<p><strong>C++</strong>:</p>
<p>There's no chance your parents will get C++ from start, they will for sure be some misunderstandings.</p>
<h2>Mental Connection</h2>
<p><strong>Java</strong>:</p>
<p>Old and reliable but quite boring. You know Java is always there for you but can be rather grumpy if you don't follow its rules and conventions.</p>
<p><strong>JavaScript</strong>:</p>
<p>Acceptive, versatile and will always introduce you to new friends. If you do something wrong, JavaScript won't let you now, you will have to find that out on your own.</p>
<p><strong>Python</strong>:</p>
<p>Nice to communicate with, easy to read and will always try to get rid of all the garbage in your life.</p>
<p><strong>C++</strong>:</p>
<p>If you want the smartest tool in the shed, C++ is a good choice. But don't complain if it doesn't listen to you, it's probably your fault it's having memory leaks.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Jokes</category>
            <enclosure url="https://www.perssondennis.com/images/articles/what-if-you-would-marry-a-programming-language/what-if-you-would-marry-a-programming-language.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Why Server Components - A Brief History of Web]]></title>
            <link>https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web</link>
            <guid>https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web</guid>
            <pubDate>Sun, 09 Jul 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Benefits of Server Components in Next.js App Router compared to server rendering options like SSR, SSG and ISR. ✓ Next.js 13 ✓ Server Components ✓ Pros and cons]]></description>
            <content:encoded><![CDATA[<p>According to <a href="https://survey.stackoverflow.co/2023/#section-admired-and-desired-web-frameworks-and-technologies">Stack Overflow survey 2023</a>, Next.js is now the third most desired web framework, and the sixth most admired one among developers. Even though their old <a href="https://nextjs.org/docs/pages">Pages Router</a> is great, they have introduced a new <a href="https://nextjs.org/docs/app">App Router</a> in version 13 of the framework. With that change, they also migrated to use Server Components which can be seen as the next level server rendering.</p>
<p>To understand why Next.js and Server Components are so much more than just traditional client-side React applications, this article will guide you from the beginning of the web, through different types of server rendering with all their benefits, and to the very latest state of web development with Next.js Server Components.</p>
<h2>In This Article</h2>
<ul>
<li><a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#from-server-rendering-to-spas-and-then-back-to-server">From Server Rendering to SPAs and Then Back to Server</a></li>
<li><a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#client-components-vs-server-components">Client Components vs Server Components</a></li>
<li><a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#server-side-rendering-ssr-vs-static-site-generation-ssg">Server Side Rendering (SSR) vs Static Site Generation (SSG)</a></li>
<li><a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#client-components-vs-server-components-revisited">Client Components vs Server Components Revisited</a></li>
<li><a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#what-rendering-solution-should-i-use">What Rendering Solution Should I Use?</a></li>
<li><a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#static-vs-dynamic-rendering">Static vs Dynamic Rendering</a></li>
<li><a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#pros-and-cons-with-server-rendering">Pros and Cons With Server Rendering</a></li>
<li><a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#server-components-come-with-additional-benefits">Server Components Come with Additional Benefits</a></li>
<li><a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#server-components-are-not-perfect">Server Components Are Not Perfect</a></li>
<li><a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#conclusion">Conclusion</a></li>
</ul>
<h2>From Server Rendering to SPAs and Then Back to Server</h2>
<p>To better understand Server Components, we should talk about why they where introduced. For that, we will need a short history lesson.</p>
<p>In the old traditional web programming days, a website consisted of a server rendering HTML code, sending it over network to a client browser which displayed the already rendered HTML code to the user. With that, you had CSS and some small JavaScript files to handle user interactions and navigation to other pages on the website (and also to show a cool visitor counter, which was kind of mandatory).</p>
<p>Newer technologies came and we got smartphones and better computers with increased performance. The web evolved and single page applications (SPA) became the new standard, which basically meant that only one initial webpage where sent to the client. Upon navigating or interacting with the page, REST requests where used to retrieve data from the server and modified the page without actually navigating to another page on the website.</p>
<p>One of the biggest key players for that evolution was the jQuery library, and then the principle kept growing with modern frameworks like React, Angular and Vue which in first place rendered everything on the client side, with support for opting-in to use server side rendering (SSR). As web migrated to SPAs we started to call websites with rich functionalities for web applications.</p>
<p>More and more web application frameworks emerged, and different ways to pre-render web applications arose. Pre-rendering webpages on requests with SSR wasn't enough, frameworks also added support to pre-render pages in build time, so called static site generation (SSG).</p>
<p>We will soon look closer at SSR and SSG, and at the end of the article we will discuss pros and cons of server rendering. But for now, let's forget the <em>why</em> and focus on the <em>what</em> and <em>how</em>.</p>
<p>Where we are today, it's not a question about client rendering or server rendering, we have actually reached a point where we can choose to render small parts of the site differently, and that's where Client Components and Server Components come in.</p>
<h2>Client Components vs Server Components</h2>
<p>If you have used SPA frameworks like React or Angular, you should be familiar with Client Components already. Client components are basically what a React component really is in nature, a bit of JavaScript code which renders a component on a webpage when it reaches the browser.</p>
<p>Server Components on the other hand, are components rendered into HTML on the server. When I say that, I don't refer to pre-rendering HTML for complete pages with SSR or SSG, I literally mean rendering a single component, like a single React component. It is that granularity Next.js offers with the new App Router system.</p>
<p>To get a better vision of it. Let's look at the old pre-rendering solutions and then come back to Server Components again after that.</p>
<h2>Server Side Rendering (SSR) vs Static Site Generation (SSG)</h2>
<p>The basics of SSR and SSG are the same, pre-render HTML code on the server and then fetching JavaScript to make the page interactive in a process called hydration. Dependent on framework, navigation can either result in fetching completely new pages from the server or be handled by hydrated JavaScript code as a SPA would do.</p>
<p><img src="https://www.perssondennis.com/images/articles/why-server-components-a-brief-history-of-web/pre-rendering.webp" alt="Pre-render-and-hydration">
<em>Pre-rendering will fetch HTML and then hydrate JavaScript to make the page interactive</em></p>
<p>When using SSR as a pre-render solution, a complete web page is rendered into HTML on the server at the time when a page is requested. The server will then also fetch the JavaScript and start the hydration process.</p>
<p><img src="https://www.perssondennis.com/images/articles/why-server-components-a-brief-history-of-web/server-side-rendering.webp" alt="Server Side Rendering">
<em>Server side rendering renders HTML for a page when a browser requests it</em></p>
<p>SSG instead allows you to pre-render the application already at build time, which makes it possible to serve the same HTML page quickly to any user without having to render a page in runtime.</p>
<p><img src="https://www.perssondennis.com/images/articles/why-server-components-a-brief-history-of-web/static-site-generation.webp" alt="Static Site Generation">
<em>Static site generation renders HTML at build time and serves it on all requests</em></p>
<p>While SSG allows to serve instant web pages, it doesn't allow to serve different HTML to different users. All users will get the same content. Dynamic rendering based on user data is not possible with that.</p>
<p>SSG neither allows you to change the HTML by time, since all the HTML code are generated during build time. To solve that issue, Next.js supports something called <a href="https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration">incremental static regeneration (ISR)</a>. What it does, is to allow you to manually, on demand, or periodically regenerate a static generated page.</p>
<p>Although ISR exists in the old Pages Router, it isn't available with the new App Router. It has passed on its baton to Server Components.</p>
<h2>Client Components vs Server Components Revisited</h2>
<p>So, now when we know about the old options to render pages on the server, we can now go back and look at what Client and Server Components actually are. Look at this picture. It shows you a web page with alternated Client and Server Components.</p>
<p><img src="https://www.perssondennis.com/images/articles/why-server-components-a-brief-history-of-web/client-and-server-components.webp" alt="Client and Server Components">
<em>A page can consist of layers of Client and Server Components</em></p>
<p>As mentioned earlier in the article, Server Components allow you to render individual components purely on the server, while other components on the same page remain as Client Components rendered on the client (with Next.js, they are pre-rendered once on server and hydrated on the client). The picture above, shows and example what that can look like. Green components are rendered into HTML on the server, while the blue ones are rendered with JavaScript on the client.</p>
<p>What this means, is that Next.js now allows to decide for each component whether it should be pre-rendered on the server or if it needs to be rendered on the client. As we will see later, in the <a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#static-vs-dynamic-rendering">Static vs Dynamic Rendering</a> section, Next.js will also automatically determine whether those Server Components need to be rendered at runtime or if they can be rendered in advance at build time.</p>
<p><img src="https://www.perssondennis.com/images/articles/why-server-components-a-brief-history-of-web/server-components-ripper-meme.webp" alt="Server components ripper meme">
<em>Ack ack, who's there?</em></p>
<h2>What Rendering Solution Should I Use?</h2>
<p>As we have seen, there are a lot of options available for rendering modern web applications. If you use Next.js 13, you have all the options discussed available to choose between. If you start a new project, I recommend using the new App Router system. App Router is production ready, although some other new related features are still in alpha or beta.</p>
<p>To make life easier for you, we will look at which rendering solutions to choose for both Pages Router and new App Router.</p>
<h3>Next.js Pages Router</h3>
<p>With Pages Router, you have four render options to choose between.</p>
<ul>
<li>Client Side Rendering (CSR)</li>
<li>Server Side Rendering (SSR)</li>
<li>Static Site Generation (SSG)</li>
<li>Incremental Static Regeneration (ISR)</li>
</ul>
<p>Remember that all these options are per page. The normal behavior is that one application uses most of these options. For example, information pages such as an about us page can usually be generated using SSG, while other pages with more dynamic data would use SSR.</p>
<p>As we will see <a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#pros-and-cons-with-server-rendering">later in the article</a>, modern web development tend to favor server rendering over client side rendering. CSR is therefore only recommended if there's a need for it. Some cases when it's necessary or recommended to render an application on the client are:</p>
<ul>
<li>When you need to use browser specific Web APIs</li>
<li>When you need the user's real location via the geolocation Web API or a IP Geolocation API</li>
<li>When your data relies on data stored in the browser, like LocalStorage</li>
<li>When apps are communicating in a peer-to-peer network</li>
<li>When data changes very frequently, we may want to keep the load on the client not to overload the server</li>
</ul>
<p>In most other cases, some kind of pre-rendering on the server is recommended. The aim is to cache the generated content as long as possible. If the site is completely static, SSG is usually preferred, if possible.</p>
<p>If you have too many pages to render at build time, or if the static pages need to be updated occasionally, ISR may be an excellent rescue. With ISR, builds can be generated at runtime when you need them, and then regenerated manually or by setting a cache validation time.</p>
<p>If a page isn't completely static, and data isn't only changed by time, but also dependent on authenticated user information or request headers, SSR or CSR is probably what you need to use instead.</p>
<h3>Next.js App Router</h3>
<p>With the App Router, we don't have as many alternatives. The two main options are Client Component or Server Component.</p>
<p>The concept of static and dynamic rendering is still relevant when we use the App Router, but it's not that prominent. The details about it are a bit complicated, but will be discussed in <a href="https://www.perssondennis.com/articles/why-server-components-a-brief-history-of-web#static-vs-dynamic-rendering">Static vs Dynamic Rendering</a> section.</p>
<p>The easy part to grasp is when to use Server Components. Just as with the Pages Router, server side rendering is to prefer when using App Router. This means, that we should use Server Components as long as we do not have a reason to use a Client Component. That's also why Next.js defaults to Server Components.</p>
<p>It may sound strange, but the cases of when to use Client Components slightly differs from when to use CSR with the Pages Router. The reason is because the whole underlying structure and design is different with the App Router, so we cannot use the very same rules.</p>
<p>With App Router, you can follow a simple rule. If there is a need to use the browser in any way, or to store some state that may change as a result of user interactions, then you should go for a Client Component, otherwise you can use a Server Component.</p>
<p>More explicitly, a Client Component will be required when:</p>
<ul>
<li>When you need to use browser specific Web APIs</li>
<li>When you need the user's real location via the geolocation Web API or a IP Geolocation API</li>
<li>When your data relies on data stored in the browser, like LocalStorage</li>
<li>The component uses a lifecycle hook or internal state, such as useState, useReducer, useEffect or useContext</li>
<li>The component uses a custom hook which uses lifecycle hooks or an internal state</li>
<li>The components needs to be interactive, i.e. when it uses onClick or onChange listeners on DOM elements</li>
<li>If you are still using React class components for some strange reason</li>
</ul>
<p>This may seem like a lot, but remember, a great part of a web applications is normally static and are never changed or interacted with. For example, this whole article is static, it's just text and links.</p>
<p>Server Components aren't just build-time generated static pages. Which we will see later, you can still fetch data from APIs in them, even with dynamic none-cached data. You can read cookies and headers, and they allow you to read sensitive data on the server and to avoid sending huge server responses and JavaScript dependencies to the client.</p>
<p><img src="https://www.perssondennis.com/images/articles/why-server-components-a-brief-history-of-web/node-modules-transportation-meme.webp" alt="node_modules transportation meme">
<em>Don't worry, server has included assembly instructions, Ikea style</em></p>
<h2>Static vs Dynamic Rendering</h2>
<p>As revealed earlier, Server Components can be rendered either at build time (static) or at runtime when a request is coming in (dynamic). This is something you should be aware of, but which unfortunately has many ifs and buts.</p>
<p>Next.js have made an attempt to handle this automatically for you. What they do, is to default to static rendering, and automatically enables dynamic rendering when necessary, or when you manually configure that. Dynamic rendering will be activated when:</p>
<ul>
<li><a href="https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-functions">Dynamic functions</a> are used, which are built-in functions to read cookies, headers or search params</li>
<li>You <a href="https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic-rendering#static-data-fetching-default">disable cache for the built-in fetch function</a></li>
<li>You manually change the behavior with a <a href="https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config">Route Segment Config</a></li>
</ul>
<p>I'm pretty sure you will have to read those links to understand it, this article is already long enough without that. One thing you should note down though, is that the behavior differs when you use Next.js built in functions for data fetching, cookies, headers and search params, compared to when you use custom solutions or external libs.</p>
<p>Next.js will not be able to know when your component must be dynamic if you don't use their built-in features. In that case, you may have to manually configure the cache behavior.</p>
<h2>Pros and Cons With Server Rendering</h2>
<p>As promised a few times throughout the article, we will now look at pros and cons of server side rendering. Server side rendering has a lot of benefits and a few disadvantages. The advantages depends slightly on what type of server rendering which is in use, the advantages of SSG can differ from SSR. The pros and cons taken up here is in general terms for server side rendered content.</p>
<h3>Advantages of Rendering Data Server Side</h3>
<ul>
<li>Servers usually have lower network latency to database than clients, especially if a client's database connection goes through a server</li>
<li>A single or a few servers can utilize catches better than thousand or millions of clients</li>
<li>Parsing JavaScript is a slow operation and one of the biggest reasons to slow websites. Rendering data on a server reduces the JavaScript bundle size sent to the client</li>
<li>Initial page load is faster with server side rendering, which is both good for UX and for SEO</li>
<li>Server side rendering is better for SEO overall, due to less JavaScript involvement which historically have had a long and problematic relationship with web crawlers</li>
<li>You can use secrets like API keys in server side rendered content. Sensitive information like that shall never be used on a client</li>
<li>With server side rendering, you can keep your APIs and databases private and inaccessible on the public internet, since no client depends on it. Without authentication that's more or less impossible to achieve when a client depends on it</li>
<li>When data is fetched on a server, there's no need to show loading spinners or skeletons</li>
<li>When data is fetched on a server, <a href="https://web.dev/cls/">cumulative layout shift</a> will not be an issue</li>
<li>Content rendered on a server is more predictable when an application must support different browsers and devices because the server interprets the JavaScript. On a client, JavaScript can even be disabled</li>
</ul>
<h3>Disadvantages of Rendering Data Server Side</h3>
<ul>
<li>Rendering content on servers leads to a higher server load, which in turn leads to more server expenses</li>
<li>Servers generally has less support for third-party libraries</li>
<li>You don't have access to browser functionality or user's location and device etc. on a server</li>
<li>Loading time for navigation may be slow if data isn't reused and each navigation results in a completely new page. This drawback was more of a problem with traditional server side rendering solutions where rendered content rarely was reused</li>
</ul>
<p><img src="https://www.perssondennis.com/images/articles/why-server-components-a-brief-history-of-web/wish-I-were-Waldo.webp" alt="Waldo disappears meme">
<em>I wonder where Waldo went?</em></p>
<h2>Server Components Come with Additional Benefits</h2>
<p>When it comes to React Server Components, all above listed pros and cons for server side rendering applies, but Server Component also has some additional cool advantages.</p>
<p>One interesting detail is that <a href="https://nextjs.org/docs/getting-started/react-essentials#composing-client-and-server-components">all Server Components are already pre-rendered</a> when the client receives an application. What this means is that conditionally rendered Server Components can be rendered instantly even when they depend on network data. There's no need to wait for a network response and handle the loading state, even in cases where the component is conditionally rendered in response to a user action.</p>
<p>Reading that, you may be worried about bundle size. I can relieve you by informing that your preoccupations are unwarranted. HTML code does not have a great impact on loading times. HTML is cacheable, way faster to parse and run than JavaScript, and just a fraction of the size of images.</p>
<p>And as the icing on the cake, Server Components add zero bundle size for JavaScript dependencies! Even if you would use a none tree-shacked library at 250 kB, the resulting HTML code would still include 0 kB JavaScript.</p>
<h2>Server Components Are Not Perfect</h2>
<p>If Server Components are so amazing, are they really perfect? Answers is of course no. There are some potentially inconvenient drawbacks.</p>
<p>Server Components require new knowledge. The migration from old Next.js Pages Router to the new App Router comes with a complete new way of thinking which most developers aren't used to.</p>
<p>Not only the developers' knowledge have become more outdated, the code has so too. Even though newer versions of Next.js is fully compatible with old Pages Router, code using the Pages Router will become legacy code, just as the React's old class components.</p>
<p>Few other drawbacks also exists with code quality. Sharing code has become more difficult when rendering has been split further into client and server rendering. Code marked with <em>use client</em> and <em>import server-only</em> makes it more cumbersome to write DRY code.</p>
<p>I must also admit, although opinionated, the prop drilling of Server Components in Next.js is not the best solution for readability. In Next.js, Server Components cannot be imported in a Client Component, meaning that Server Components rendered in Client Component must be passed as children props and rendered as such. It works, and it's not a new pattern, but might be a bit cumbersome to adapt to.</p>
<p><img src="https://www.perssondennis.com/images/articles/why-server-components-a-brief-history-of-web/where-is-waldo.webp" alt="Where is Waldo">
<em>Oh, there you are Waldo, on the server!</em></p>
<h2>Conclusion</h2>
<p>Web started out with HTML retrieved from a server with very little use of JavaScript. Time flew by and after many turns back and forth with different rendering solutions such as single page applications (SPA), server side rendering (SSR) and static site generation (SSG), React has now evolved to use Server Components.</p>
<p>Next.js offers a legacy Pages Router which uses the old rendering options together with a very useful incremental static generation (ISR) strategy. With the introduction of Server Components, they now offer a new App Router which allows you to micro-optimize rendering for you web application on a component level with Server Components.</p>
<p>Among all the benefits of Server Components, we have low bundle size, fast page load time, great SEO compatibility and browser support, UX improvements and a possibility to use secrets stored on the server. On top of that, we can get instant rendering for conditionally rendered components without a need to show any loading spinners or skeletons.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Architecture</category>
            <category>Frontend</category>
            <category>JavaScript</category>
            <category>Next.js</category>
            <category>Performance</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/why-server-components-a-brief-history-of-web/why-server-components-a-brief-history-of-web.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Why You Should Not Be a Reactive Developer]]></title>
            <link>https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer</link>
            <guid>https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer</guid>
            <pubDate>Sun, 09 Oct 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Why is being a reactive programmer bad? Reactive vs proactive development explained with React examples and an extensive list of pros and cons.]]></description>
            <content:encoded><![CDATA[<h2>In This Article</h2>
<ol>
<li><a href="https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer#what-is-a-reactive-developer">What Is a Reactive Developer</a></li>
<li><a href="https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer#case-scenario">Case Scenario</a></li>
<li><a href="https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer#the-reactive-developers-solution">The Reactive Developer's Solution</a></li>
<li><a href="https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer#how-to-solve-it-properly">How To Solve It Properly</a></li>
<li><a href="https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer#the-impact-of-reactive-programming">The Impact of Reactive Programming</a></li>
<li><a href="https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer#an-extra-note-about-writing-tests">An Extra Note About Writing Tests</a></li>
<li><a href="https://www.perssondennis.com/articles/why-you-should-not-be-a-reactive-developer#summary">Summary</a></li>
</ol>
<h2>What Is a Reactive Developer?</h2>
<p>Let's start with defining what I mean when I say "reactive developer". I don't refer to the programming paradigm <a href="https://en.wikipedia.org/wiki/Reactive_programming">reactive programming</a>. Neither do I mean a developer who writes React code.</p>
<p>What I really am talking about when I use the term reactive developer, is a trait some developers have when they write code. The way they behave when writing code.</p>
<p>Reactive developers write code as a direct response to the problem they are facing for the moment. This means, if they find a bug, they will solve it hastily without considering alternative solutions. Phrased differently, they will implement the first solution that comes to their mind without thinking of the consequences it implies.</p>
<p>The opposite to a reactive developer, would be a proactive developer, a developer that plans ahead to find the best possible solution. Let's look at an example scenario to see the difference in how a reactive developer solves a problem compared to a proactive developer.</p>
<h2>Case Scenario</h2>
<p>Imagine you have an application where you can receive messages, and messages are marked as read when you read them. Then, when a user has read all its messages, a modal should display.</p>
<p>Imagine that functionality is already implemented with the code below. Unfortunately, it doesn't work, the modal doesn't open when the latest message is read. Maybe you can spot why?</p>
<pre><code class="language-javascript">// The passed in messages has a property named isRead which is
// true if the message has been read.
const MyReactComponent = ({ messages }) => {
  const [modalOpen, setModalOpen] = useState(false)
  const [unreadMessages, setUnreadMessages] = useState(messages)

  useEffect(() => {
    // If there are no unread messages, open the modal.
    if (unreadMessages.length === 0) {
      setModalOpen()
    }

    // Update unreadMessages to only contain unread messages.
    setUnreadMessages(messages.filter(msg => !msg.isRead))
  }, [messages])

  return &#x3C;Modal open={modalOpen} />
}
</code></pre>
<p>I don't know how experienced React developer you are, but the reason the modal isn't opened is because the useEffect has a missing dependency, <em>unreadMessages</em>. It's an honest mistake, developers do such things all the time.</p>
<p>With that said, the person who wrote this code is probably a rather unexperienced or hasty developer, a novice or reactive developer. Especially since this issue could have been caught if the developer used ESLint rules for React hooks, <em>react-hooks/exhaustive-deps</em>, and took notice of the warning it would have inferred about the missing dependency to the useEffect.</p>
<p><img src="https://www.perssondennis.com/images/articles/why-you-should-not-be-a-reactive-developer/eslint-react-exhaustive-deps.webp" alt="ESLint React Exhaustive deps error">
<em>ESLint could have warned us with a "React Hook useEffect has a missing dependency" notice</em></p>
<h2>The Reactive Developer's Solution</h2>
<p>Time to solve the bug in the code above. As mentioned, the issue was that the <em>unreadMessages</em> was missing in the useEffect's dependency list. Our imagined reactive developer figures out that quickly. Just as quickly as he detects the problem, he also comes up with a solution. Quickly he adds the missing dependency and checks the browser result.</p>
<pre><code class="language-javascript">useEffect(() => {
  if (unreadMessages.length === 0) {
    setModalOpen()
  }

  setUnreadMessages(messages.filter(msg => !msg.isRead))

  // The reactive developer added the unreadMessages dependency.
}, [messages, unreadMessages])
</code></pre>
<p>Hmm. Something isn't working... Is Babel failing? Why isn't the application responding? No, that's not it. The browser is stuck in an infinite loop!</p>
<p>When the developer added the missing <em>unreadMessages</em> dependency, the useEffect caused an infinte loop because <em>unreadMessages</em> updates within the effect, which in turn retriggers the effect to run once again. Luckily, this new bug couldn't go by undetected.</p>
<p>The reactive developer is inventive. He instantly figures out another solution. What if we only would invoke setUnreadMessages if the number of unread messages actually has changed? That way, we could bypass the infinte loop. In seconds he has updated the code to look as below.</p>
<pre><code class="language-javascript">const MyReactComponent = ({ messages }) => {
  const [modalOpen, setModalOpen] = useState(false)
  const [unreadMessages, setUnreadMessages] = useState(messages)

  useEffect(() => {
    if (unreadMessages.length === 0) {
      setModalOpen()
    }

    const unreadMsgs = messages.filter(msg => !msg.isRead)

    // If the number of unread messages is the same as last time
    // the effect ran, do not update the state. This way we can
    // avoid the infinite loop, because we only update
    // unreadMessages if we have read some new messages.
    if (unreadMessages?.length !== unreadMsgs.length) {
        setUnreadMessages(unread)
    }
  }, [messages, unreadMessages])

  return &#x3C;Modal open={modalOpen} />
}
</code></pre>
<p>Does the code work well now? Honestly, I haven't even tested it. What I can tell already is that it isn't a good solution. Let's look at a better one.</p>
<h2>How To Solve It Properly</h2>
<p>The initial code was bad to begin with, and when we found out it caused an error, we shouldn't just have solved the bug, we should have reconsidered if there was a better way to implement the same functionality. The current code was obviously flaky already. Any other quick fix would either cause a new bug or contribute to more complex code.</p>
<p>Here's what could have been done.</p>
<pre><code class="language-javascript">const MyReactComponent = ({ messages }) => {
  const unreadMessages = messages.filter(msg => !msg.isRead)
  return &#x3C;Modal open={unreadMessages.length === 0} />
}
</code></pre>
<p>Yeah. That's it. The code does exactly what we wanted it to do. Concise, readable, and no need for the three hooks and two if statements that all could cause some kind of bugs. We could even have turned the complete component into a one-liner, but that would reduce the readability of the code.</p>
<p>Replacing the original solution with this new solution is just as quick as patching the old solution. But instead of increasing complexity, readability and the risk for bugs, we instead made the code more readable and less error-prone.</p>
<h2>The Impact of Reactive Programming</h2>
<p>So, let's rethink what we just experienced and what kind of effects reactive programming results in.</p>
<ul>
<li>The reactive solution ended up with 3-4 times as much code. We definitely don't want our whole code base to grow with a factor 3 or 4. Apart from having to maintain the code base, redundant JavaScript code is also one of the most common causes for web applications to load slowly.</li>
<li>The reactive solution gave birth to a new bug. In this case, it was easy to detect the new bug. We won't always be that lucky.</li>
<li>The reactive developer's code takes a lot more time to read and understand.</li>
<li>The reactive developer's React component will render more times. Doing this for one component isn't an issue, but in large-scale projects, or when dealing with big amount of data, it can make the application terribly slow.</li>
<li>Since the reactive code can be refactored in a better way, all unnecessary code adds up to the project's technical debt.</li>
<li>Developers copy a lot of code. There's a big chance (read risk) that someone copies the code the reactive developer wrote, leading to all the same mistakes in another part of the application.</li>
<li>Unexperienced developers would spend a lot of time testing the longer reactive component. Not only because it's harder to test, but also because it <strong>looks</strong> harder. Many developers try to test internal logic, such as what value a useState has. Please note that you should never do that. Consider each React component as a unit (black box). You have some input and expect an output. What values a useState has is completely irrelevant.</li>
</ul>
<p>I'm sure I missed a bunch of bullet points I could add. But I think you get the point, there's a lot of reasons not to be reactive and go for the fastest possible solution. Try to be proactive, to think of better solutions. It will save you a tremendous amount of time, not only long term, in most cases even short term.</p>
<h2>An Extra Note About Writing Tests</h2>
<p>When working at larger companies, testing is very essential, and it takes time, a lot of time. I would therefore like to add an additional note about testing the components written by the reactive and proactive developers.</p>
<p>Testing the proper proactive solution is a piece of case, one test to check that the modal is open when we have read all messages, and another one to check that it's closed when we have messages which are unread. That will test all scenarios that can occur and all branches of code (possible if-statement branching). We do not need to test that the code works when the unread count changes, because the code does not have an internal state or a useEffect.</p>
<pre><code class="language-javascript">// When the code doesn't include a state or an effect, there's
// no need to update the message prop when testing the component.
const MyReactComponent = ({ messages }) => {
  const unreadMessages = messages.filter(msg => !msg.isRead)
  return &#x3C;Modal open={unreadMessages.length === 0} />
}
</code></pre>
<p>The longer solution written by the reactive developer is more troublesome to test. We could of course use the same two test cases, one for the open state and one for the closed state. Doing that would not test all scenarios that can happen when running the code though, and neither would it cover all code branches. It wouldn't even catch the bug on topic, where the modal doesn't open when the read count changes.</p>
<p>To test the reactive component fully, we would have to trigger a rerender and pass in a new <em>messages</em> prop to test it thoroughly. That is required because we have a useEffect that updates an internal state in the component.</p>
<pre><code class="language-javascript">// To test this component fully, we need to update messages prop
// within a test to see what happens when the useEffect triggers.
// If we don't do that, we cannot know what will happen when we
// get new messages passed in from a parent component.
const MyReactComponent = ({ messages }) => {
  const [modalOpen, setModalOpen] = useState(false)
  const [unreadMessages, setUnreadMessages] = useState(messages)

  useEffect(() => {
    if (unreadMessages.length === 0) {
      setModalOpen()
    }

    const unreadMsgs = messages.filter(msg => !msg.isRead)

    if (unreadMessages?.length !== unreadMsgs.length) {
        setUnreadMessages(unread)
    }
  }, [messages, unreadMessages])

  return &#x3C;Modal open={modalOpen} />
}
</code></pre>
<p>Testing the above component is not very hard, but it can be. If we would test it using Enzyme and trying to do a shallow rendering, we would notice that the <a href="https://stackoverflow.com/questions/59164027/testing-a-component-that-uses-useeffect-using-enzyme-shallow-and-not-mount">useEffect isn't even being triggered</a>. More code always comes with more bugs, more test cases and more use cases that aren't supported by the frameworks we use. The best way to avoid writing a lot of tests is to write better code.</p>
<h2>Summary</h2>
<p>A reactive developer is a programmer which reacts to problems when they occur, and quickly finds a way to solve or mitigate the problem. In this article, we could see how such behavior could lead to writing more code which are both less readable and more prone to errors. We explained how being proactive and writing code with the future in mind could save time both when writing code and writing tests.</p>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Productivity</category>
            <category>SoftSkills</category>
            <category>Testing</category>
            <enclosure url="https://www.perssondennis.com/images/articles/why-you-should-not-be-a-reactive-developer/why-you-should-not-be-a-reactive-developer.webp" length="0" type="image/webp"/>
        </item>
        <item>
            <title><![CDATA[Write SOLID React Hooks]]></title>
            <link>https://www.perssondennis.com/articles/write-solid-react-hooks</link>
            <guid>https://www.perssondennis.com/articles/write-solid-react-hooks</guid>
            <pubDate>Sun, 02 Jun 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[SOLID principles suits surprisingly well with React. This article explains how to implement React hooks to follow the SOLID principles. ✓ React ✓ Hooks ✓ SOLID]]></description>
            <content:encoded><![CDATA[<p>SOLID is one of the more commonly used design patterns. It's commonly used in many languages and frameworks, and there are some articles out there how to use it in React as well.</p>
<p>Each React article about SOLID presents the model in slightly different ways, some applies it on components, other on TypeScript, but very few of them are applying the principles to hooks.</p>
<p>Since hooks are a part of React's foundation, we will here look at how the SOLID principles applies to those.</p>
<h2>Single Responsibility Principle (SRP)</h2>
<p>The first letter in Solid, the S, is the easiest one to understand. In essence it means, let one hook/component do one thing.</p>
<pre><code class="language-markdown">// Single Responsibility Principle

A module should be responsible to one, and only one, actor
</code></pre>
<p>For example, look at the useUser hook below, it fetches a user and todo tasks, and merges the tasks into the user object.</p>
<pre><code class="language-javascript">import { useState } from 'react'
import { getUser, getTodoTasks } from 'somewhere'

const useUser = () => {
  const [user, setUser] = useState()
  const [todoTasks, setTodoTasks] = useState()

  useEffect(() => {
    const userInfo = getUser()
    setUser(userInfo)
  }, [])

  useEffect(() => {
    const tasks = getTodoTasks()
    setTodoTasks(tasks)
  }, [])

  return { ...user, todoTasks }
}
</code></pre>
<p>That hook isn't solid, it doesn't adhere to the single responsibility principle. This is because it both has the responsibility to get user data and todo tasks, that's two things.</p>
<p>Instead, the above code should be split in two different hooks, one to get data about the user, and another one to get the tasks.</p>
<pre><code class="language-javascript">import { useState } from 'react'
import { getUser, getTodoTasks } from 'somewhere'

// useUser hook is no longer responsible for the todo tasks.
const useUser = () => {
  const [user, setUser] = useState()

  useEffect(() => {
    const userInfo = getUser()
    setUser(userInfo)
  }, [])

  return { user }
}

// Todo tasks do now have their own hook.
// The hook should actually be in its own file as well. Only one hook per file!
const useTodoTasks = () => {
  const [todoTasks, setTodoTasks] = useState()

  useEffect(() => {
    const tasks = getTodoTasks()
    setTodoTasks(tasks)
  }, [])

  return { todoTasks }
}
</code></pre>
<p>This principle applies to all hooks and components, they all should only do one thing each. Things to ask yourself are:</p>
<ol>
<li>Is this a component which should show a UI (presentational) or handle data (logical)?</li>
<li>What single type of data should this hook handle?</li>
<li>What layer does this hook/component belong to? Is it handling data storage or is it maybe a part of a UI?</li>
</ol>
<p>If you find yourself building a hook which doesn't have a single answer to each and every of the above questions, then you're breaking the single responsibility principle.</p>
<p>An interesting thing to note here, is question number one. That one actually means, that a component rendering a UI, should not also handle data. This means, to really follow this principle strictly, each React component displaying data should have a hook to handle its logic and data. In other words, data should not be fetched in the same component which displays it.</p>
<h3>Why Use SRP in React?</h3>
<p>This single responsibility principle actually goes very well with React. React follows a component based architecture, meaning that it consists of small components composed together so they all together can build up and form an application. The smaller the components are, the more likely they are to be reusable. This applies to both components and hooks.</p>
<p>For that reason, React is more or less founded on the single responsibility principle. If you don't follow it, you will find yourself always writing new hooks and component and rarely re-use any of them.</p>
<p>Disobeying the single responsibility principle will make your code exhaustive to test. You will often find your test files to have several hundred, maybe up towards 1000, lines of codes, if you don't follow this principle.</p>
<h2>Open/Closed Principle (OCP)</h2>
<p>Let's continue with the Open/Closed principle, after all, it's the next letter in SOLID. OCP is as well as SRP one of the easier principle to understand, at least its definition.</p>
<pre><code class="language-markdown">// Open/Closed Principle

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification 
</code></pre>
<p>In words for dummies who recently have started with React, the sentence can be translated to:</p>
<pre><code class="language-markdown">Write hooks/component which you never will have a reason to touch again, only re-use them in other hooks/components
</code></pre>
<p>Think back at what was said for the single responsibility principle earlier in this article; in React, your are expected to write small components and compose them together. Let's look at why that is helpful.</p>
<pre><code class="language-javascript">import { useState } from 'react'
import { getUser, updateUser } from 'somewhere'

const useUser = ({ userType }) => {
  const [user, setUser] = useState()

  useEffect(() => {
    const userInfo = getUser()
    setUser(userInfo)
  }, [])

  const updateEmail = (newEmail) => {
    if (user &#x26;&#x26; userType === 'admin') {
      updateUser({ ...user, email: newEmail })
    } else {
      console.error('Cannot update email')
    }
  }

  return { user, updateEmail }
}
</code></pre>
<p>The hook above fetches a user and returns it. If the type of the user is an admin, the user is allowed to update its email. A regular user is not allowed to do update its email.</p>
<p>The above code would definitely not get you fired. It would annoy the backend guy in your team though, the dude who reads design pattern books as bedtime stories for his toddlers. Let's call him Pete.</p>
<p>What would Pete complain about? He would ask you to rewrite the component as shown below. To lift out the admin functionalities to it's own useAdmin hook, and leave the useUser hook with no other features than those that should be available for regular users.</p>
<pre><code class="language-javascript">import { useState } from 'react'
import { getUser, updateUser } from 'somewhere'

// useUser does now only return the user, 
// without any function to update its email.
const useUser = () => {
  const [user, setUser] = useState()

  useEffect(() => {
    const userInfo = getUser()
    setUser(userInfo)
  }, [])

  return { user }
}

// A new hook, useAdmin, extends useUser hook,
// with the additional feature to update its email.
const useAdmin = () => {
  const { user } = useUser()

  const updateEmail = (newEmail) => {
    if (user) {
      updateUser({ ...user, email: newEmail })
    } else {
      console.error('Cannot update email')
    }
  }

  return { user, updateEmail }
}
</code></pre>
<p>Why did Pete ask for this update? Because that disrespectful picky prick Pete would rather want you to spend time rewriting that hook now, and come back with a new code review tomorrow, instead of potentially having to update the code with a tiny new if statement in the future, if there ever would be another type of user.</p>
<p>Well, that's the negative way to put it... The optimistic way, is that with this new useAdmin hook, you don't have to change anything in the useUser hook when you intend to implement features that affects admin users only, or when you add new types of users.</p>
<p>When new user types are added, or when useAdmin hook is updated, there's no need to mess with the useUser hook or update any of its tests. Meaning, you don't have to accidentally ship a bug to regular users when you add a new user type, e.g. a fake user. Instead, you just add a new userFakeUser hook and your boss won't call you in at 9 pm on a Friday because customers experience problems with fake data being shown for their bank account on a salary weekend.</p>
<p><img src="https://www.perssondennis.com/images/articles/write-solid-react-hooks/frontend-developer-under-the-bed.webp" alt="Frontend developer under the bed">
<em>Pete's son knows to be careful about spaghetti code developers</em></p>
<h3>Why Use OCP in React?</h3>
<p>It's arguable how many hooks and components a React project should have. Each one of them comes with a cost of renderings. React isn't a Java where 22 design patterns leads to 422 classes for a simple TODO list implementation. That's the beauty of the Wild West Web (www).</p>
<p>However, open/closed principle is clearly a handful pattern to use in React as well. The example with the hooks above was minimal, the hooks didn't do very much. With more substantive hooks and larger projects this principle becomes highly important.</p>
<p>It might cost you some extra hooks, and take slightly longer to implement, but your hooks will become more extendable, meaning that you can re-use them more often. You will have to rewrite the tests less often, making the hooks more solid. And most important, you won't create bugs in old code if you never touch it.</p>
<p><img src="https://www.perssondennis.com/images/articles/write-solid-react-hooks/dont-touch-what-is-not-broken.webp" alt="Don&#x27;t touch what is not broken">
<em>God knows not to touch things which aren't broken</em></p>
<h2>Liskov Substitution Principle (LSP)</h2>
<p>Aaah, the name... Who the hedge is Liskov? And who will substitute her? And the definition, doesn't it even make sense?</p>
<pre><code class="language-markdown">// Liskov Substitution Principle

If S subtypes T, what holds for T holds for S
</code></pre>
<p>This principle is clearly about inheritance, which isn't naturally practiced as much in React or JavaScript as in most of the backend languages. JavaScript didn't even have classes until ES6, that was <a href="https://caniuse.com/?search=class">introduced around 2015/2016</a> as syntactical sugar to prototype based inheritance.</p>
<p>With that in mind, the use cases of this principle really depends on what your code looks like. A principle similar to Liskov's that would make sense in React, could be:</p>
<pre><code class="language-markdown">If a hook/component accepts some props, all hooks and components which extends that hook/component must accept all the props the hook/component it extends accepts. The same goes for return values.
</code></pre>
<p>To illustrate an example of this, we can look at two storage hooks, useLocalStorage and useLocalAndRemoteStorage.</p>
<pre><code class="language-javascript">import { useState } from 'react'
import { 
  getFromLocalStorage, saveToLocalStorage, getFromRemoteStorage 
} from 'somewhere'

// useLocalStorage gets data from local storage.
// When new data is stored, it calls saveToStorage callback.
const useLocalStorage = ({ onDataSaved }) => {
  const [data, setData] = useState()

  useEffect(() => {
    const storageData = getFromLocalStorage()
    setData(storageData)
  }, [])
  
  const saveToStorage = (newData) => {
    saveToLocalStorage(newData)
    onDataSaved(newData)
  }

  return { data, saveToStorage }
}

// useLocalAndRemoteStorage gets data from local and remote storage.
// I doesn't have callback to trigger when data is stored.
const useLocalAndRemoteStorage = () => {
  const [localData, setLocalData] = useState()
  const [remoteData, setRemoteData] = useState()

  useEffect(() => {
    const storageData = getFromLocalStorage()
    setLocalData(storageData)
  }, [])
  
  useEffect(() => {
    const storageData = getFromRemoteStorage()
    setRemoteData(storageData)
  }, [])
  
  const saveToStorage = (newData) => {
    saveToLocalStorage(newData)
  }

  return { localData, remoteData, saveToStorage }
}
</code></pre>
<p>With the hooks above, useLocalAndRemoteStorage can be seen as a subtype of useLocalStorage, since it does the same thing as useLocalStorage (saves to local storage), but also has extended the capability of the useLocalStorage by saving data to an additional place.</p>
<p>The two hooks have some shared props and return values, but useLocalAndRemoteStorage is missing the onDataSaved callback prop which useLocalStorage accepts. The name of the return properties are also named differently, local data is named as data in useLocalStorage but named as localData in useLocalAndRemoteStorage.</p>
<p>If you would ask Liskov, this would have broken her principle. She would be quite furious actually when she would try to update her web application to also persist data server side, just to realize that she cannot simply replace useLocalStorage with useLocalAndRemoteStorage hook, just because some lazy fingered developer never implemented the onDataSaved callback for the useLocalAndRemoteStorage hook.</p>
<p>Liskov would bitterly update the hook to support that. Meanwhile, she would also update the name of the local data in the useLocalStorage hook to match the name of the local data in useLocalAndRemoteStorage.</p>
<pre><code class="language-javascript">import { useState } from 'react'
import { 
  getFromLocalStorage, saveToLocalStorage, getFromRemoteStorage 
} from 'somewhere'

// Liskov has renamed data state variable to localData
// to match the interface (variable name) of useLocalAndRemoteStorage.
const useLocalStorage = ({ onDataSaved }) => {
  const [localData, setLocalData] = useState()

  useEffect(() => {
    const storageData = getFromLocalStorage()
    setLocalData(storageData)
  }, [])
  
  const saveToStorage = (newData) => {
    saveToLocalStorage(newData)
    onDataSaved(newData)
  }

  // This hook does now return "localData" instead of "data".
  return { localData, saveToStorage }
}

// Liskov also added onDataSaved callback to this hook,
// to match the props interface of useLocalStorage.
const useLocalAndRemoteStorage = ({ onDataSaved }) => {
  const [localData, setLocalData] = useState()
  const [remoteData, setRemoteData] = useState()

  useEffect(() => {
    const storageData = getFromLocalStorage()
    setLocalData(storageData)
  }, [])
  
  useEffect(() => {
    const storageData = getFromRemoteStorage()
    setRemoteData(storageData)
  }, [])
  
  const saveToStorage = (newData) => {
    saveToLocalStorage(newData)
    onDataSaved(newData)
  }

  return { localData, remoteData, saveToStorage }
}
</code></pre>
<p>By having common interfaces (ingoing props, outgoing return values) to hooks, they can become very easy to exchange. And if we should follow the Liskov substitution principle, hooks and components which inherits another hook/component should be possible to substitute with the hook or component it inherits.</p>
<p><img src="https://www.perssondennis.com/images/articles/write-solid-react-hooks/worried-liskov.webp" alt="Worried Liskov">
<em>Liskov gets disappointed when developers don't follow her principles</em></p>
<h3>Why Use LSP in React?</h3>
<p>Even though inheritance isn't very prominent in React, it's definitely used behind the scenes. Web applications can often have several similar looking components. Texts, titles, links, icon links and so on are all similar types of components and can benefit of being inherited.</p>
<p>An IconLink component may or may not be wrapping a Link component. Either way, they would benefit from being implemented with the same interface (using the same props). In that way, it's trivial to replace a Link component with an IconLink component anywhere in the application at any time, without having to edit any additional code.</p>
<p>The same goes for hooks. A web application fetches data from servers. They might use local storage as well or a state management system. Those can preferably share props to make them interchangeable.</p>
<p>An application might fetch users, tasks, products or any other data from backend servers. Functions like that might as well share interfaces, making it easier to re-use code and tests.</p>
<h2>Interface Segregation Principle (ISP)</h2>
<p>Another bit more clear principle, is the Interface Segregation Principle. The definition is quite short.</p>
<pre><code class="language-markdown">// Interface Segregation Principle

No code should be forced to depend on methods it does not use
</code></pre>
<p>As its name tells, it has to do with interfaces, basically meaning that functions and classes should only implement interfaces it explicitly use. That is easiest achieved by keeping interfaces neat and letting classes pick a few of them to implement instead of being forced to implement one big interface with several methods it doesn't care about.</p>
<p>For instance, a class representing a person who owns a website should be implementing two interfaces, one interface called Person describing the details about the person, and another interface for the Website with metadata about the Website it owns.</p>
<pre><code class="language-typescript">interface Person {
  firstname: string
  familyName: string
  age: number
}

interface Website {
  domain: string
  type: string
}
</code></pre>
<p>If one instead, would create a single interface Website, including both information about the owner and the website, that would disobey the interface segregation principle.</p>
<pre><code class="language-typescript">interface Website {
  ownerFirstname: string
  ownerFamilyName: number
  domain: string
  type: string
}
</code></pre>
<p>You may wonder, what is the problem with the interface above? The problem with it is that it makes the interface less usable. Think about it, what would you do if the company wasn't a human, instead a company. A company doesn't really have a family name. Would you then modify the interface to make it usable for both a human and a company? Or would you create a new interface CompanyOwnedWebsite?</p>
<p>You would then end up with an interface with many optional attributes, or respectively, two interfaces called PersonWebsite and CompanyWebsite. Neither of these solutions are optimal.</p>
<pre><code class="language-typescript">// Alternative 1

// This interface has the problem that it includes 
// optional attributes, even though the attributes 
// are mandatory for some consumers of the interface.
interface Website {
  companyName?: string
  ownerFirstname?: string
  ownerFamilyName?: number
  domain: string
  type: string
}

// Alternative 2

// This is the original Website interface renamed for a person.
// Which means, we had to update old code and tests and 
// potentially introduce some bugs.
interface PersonWebsite {
  ownerFirstname: string
  ownerFamilyName: number
  domain: string
  type: string
}

// This is a new interface to work for a company.
interface CompanyOwnedWebsite {
  companyName: string
  domain: string
  type: string
}
</code></pre>
<p>The solution which would follow the ISP, would look like this.</p>
<pre><code class="language-typescript">interface Person {
  firstname: string
  familyName: string
  age: number
}

interface Company {
  companyName: string
}

interface Website {
  domain: string
  type: string
}
</code></pre>
<p>With the proper interfaces above, a class representing a company website could implement the interfaces Company and Website, but would not need to consider the firstname and familyName properties from the Person interface.</p>
<h3>Is ISP Used in React?</h3>
<p>So, this principle obviously applies to interfaces, meaning that it should only be relevant if you are writing React code using TypeScript, shouldn't it?</p>
<p>Of course not! Not typing interfaces doesn't mean they aren't there. There are there all over the place, it's just that you don't type them explicitly.</p>
<p>In React, each component and hook has two main interfaces, it's input and its output.</p>
<pre><code class="language-javascript">// The input interface to a hook is its props.
const useMyHook = ({ prop1, prop2 }) => {
  
  // ...

  // The output interface of a hook is its return values.
  return { value1, value2, callback1 }
}
</code></pre>
<p>With TypeScript, you normally type the input interface, but the output interface is often skipped, since it is optional.</p>
<pre><code class="language-typescript">// Input interface.
interface MyHookProps { 
  prop1: string
  prop2: number
}

// Output interface.
interface MyHookOutput { 
  value1: string
  value2: number
  callback1: () => void
}

const useMyHook = ({ prop1, prop2 }: MyHookProps): MyHookOutput => {
  
  // ...

  return { value1, value2, callback1 }
}
</code></pre>
<p>If the hook wouldn't use prop2 for anything, then it should not be a part of its props. For a single prop, it would be easy to remove it from the props list and interface. But what if prop2 would be of an object type, for instance the improper Website interface example from the previous chapter?</p>
<pre><code class="language-typescript">interface Website {
  companyName?: string
  ownerFirstname?: string
  ownerFamilyName?: number
  domain: string
  type: string
}

interface MyHookProps { 
  prop1: string
  website: Website
}

const useMyCompanyWebsite = ({ prop1, website }: MyHookProps) => {
  
  // This hook uses domain, type and companyName,
  // but not ownerFirstname or ownerFamilyName.

  return { value1, value2, callback1 }
}
</code></pre>
<p>Now we have a useMyCompanyWebsite hook, which has a website prop. If parts of the Website interface is used in the hook, we cannot simple remove the whole website prop. We have to keep the website prop, and thereby also keep the interface props for ownerFirstname and ownerFamiliyName. Which also means, that this hook intended for a company could be used by a human owned website owner, even though this hook likely wouldn't work appropriately for that usage.</p>
<h3>Why Use ISP in React?</h3>
<p>We have now seen what ISP means, and how it applies to React, even without the usage of TypeScript. Just by looking at the trivial examples above, we have seen some of the problems with not following the ISP as well.</p>
<p>In more complex projects, readability is of the greatest matter. One of the purpose of the interface segregation principle is to avoid cluttering, the existence of unnecessary code which only are there to disrupt readability. And not to forget about, testability. Should you care about the test coverage of props you are not actually using?</p>
<p>Implementing large interfaces also forces you to make props optional. Leading to more if statements to check presences and potential misusages of functions because it appears on the interface that the function would handle such properties.</p>
<h2>Dependency Inversion Principle (DIP)</h2>
<p>The last principle, the DIP, includes some terms which are quite misunderstood out there. The confusions are much about what the difference is between dependency inversion, dependency injection and inversion of control. So let's just declare those first.</p>
<p><strong>Dependency Inversion</strong></p>
<p>Dependency Inversion Principle (DIP) says that high-level modules should not import anything from low-level modules, both should depend on abstractions. What this means, is that any high level module, which naturally could be dependent on implementation details of modules it uses, shouldn't have that dependency.</p>
<p>The high and low-level modules, should be written in a way so they both can be used without knowing any details about the other module's internal implementation. Each module should be replaceable with an alternative implementation of it as long as the interface to it stays the same.</p>
<p><strong>Inversion of Control</strong></p>
<p>Inversion of Control (IoC) is a principle used to address the dependency inversion problem. It states that dependencies of a module should be provided by an external entity or framework. That way, the module itself only has to use the dependency, it never has to create the dependency or manage it in any way.</p>
<p><strong>Dependency Injection</strong></p>
<p>Dependency injection (DI) is one common way to implement IoC. It provides dependencies to modules by injecting them through constructors or setter methods. In that way, the module can use a dependency without being responsible of creating it, which would live up to the IoC principle. Worth to mention, is that dependency injection isn't the only way to achieve inversion of control.</p>
<h3>Is DIP Used in React?</h3>
<p>With the terms clarified, and knowing that the DIP principle is about dependency inversion, we can look at how that definition looks again.</p>
<pre><code class="language-markdown">// Dependency Inversion Principle 

High-level modules should not import anything from low-level modules. Both should depend on abstractions
</code></pre>
<p>How does that apply to React? React isn't a library which normally is associated with dependency injection, so how can we then solve the problem of dependency inversion?</p>
<p>The most common solution to this problem spells hooks. Hooks cannot be counted as dependency injection, because they are hardcoded into components and it's not possible to replace a hook with another without changing the implementation of the component. The same hook will be there, using the same instance of the hook until a developer updates the code.</p>
<p>But remember, dependency injection is not the only way to achieve dependency inversion. Hooks, could be seen as an external dependency to a React component, with an interface (its props) which abstracts away the code within the hook. In that way, a hook kind of implements the principle of dependency inversion, since the component depends on an abstract interface without needing to know any details about the hook.</p>
<p>Another more intuitive implementations of DIP in React which actually uses dependency injection are the usage of HOCs and contexts. Look at the withAuth HOC below.</p>
<pre><code class="language-javascript">const withAuth = (Component) => {
  return (props) => {
    const { user } = useContext(AuthContext)

    if (!user) {
      return &#x3C;LoginComponent>
    }

    return &#x3C;Component {...props} user={user} />
  }
}

const Profile = () => { // Profile component... }

// Use the withAuth HOC to inject user to Profile component.
const ProfileWithAuth = withAuth(Profile)
</code></pre>
<p>The withAuth HOC shown above provides a user to the Profile component using dependency injection. The interesting thing about this example is that it not only shows one usage of dependency injection, it actually contains two dependency injections.</p>
<p>The injection of the user to the Profile component isn't the only injection in this example. The withAuth hook does in fact also get the user by dependency injection, through the useContext hook. Somewhere in the code, someone has declared a provider which injects the user into the context. That user instance can even be changed in runtime by updating the user in the context.</p>
<h3>Why Use DIP in React?</h3>
<p>Even though dependency injection isn't a pattern commonly associated with React, it is actually there with HOCs and contexts. And hooks, which has taken a lot of market share from both HOCs and contexts, does also confirm well with the dependency inversion principle.</p>
<p>DIP is therefore already built into the React library itself and should of course be utilized. It's both easy to use and provides advantages such as loose coupling between modules, hook and component reusability and testability. It also makes it easier to implement other design patterns such as the Single Responsibility Principle.</p>
<p>What I would discourage from, is trying to implement smart solutions and overusing the pattern when there really is much simpler solutions available. I have seen suggestions on the web and in books to use React contexts for the sole purpose of implementing dependency injection. Something like below.</p>
<pre><code class="language-javascript">const User = () => { 
  const { role } = useContext(RoleContext)

  return &#x3C;div>{`User has role ${role}`}&#x3C;/div>
}

const AdminUser = ({ children }) => {
  return (
    &#x3C;RoleContext.Provider value={{ role: 'admin' }}>
      {children}
    &#x3C;/RoleContext.Provider>
  )
}

const NormalUser = ({ children }) => {
  return (
    &#x3C;RoleContext.Provider value={{ role: 'normal' }}>
      {children}
    &#x3C;/RoleContext.Provider>
  )
}
</code></pre>
<p>Although the above example does inject a role into the User component, it's purely overkill to use a context for it. React contexts should be used when appropriate, when the context itself serves a purpose. In this very case, a simple prop would have been a better solution.</p>
<pre><code class="language-javascript">const User = ({ role }) => { 
  return &#x3C;div>{`User has role ${role}`}&#x3C;/div>
}

const AdminUser = () => &#x3C;User role='admin' />

const NormalUser = () => &#x3C;User role='normal' />
</code></pre>
]]></content:encoded>
            <author>dennis@perssondennis.com (Dennis Persson)</author>
            <category>Architecture</category>
            <category>Frontend</category>
            <category>JavaScript</category>
            <category>React</category>
            <enclosure url="https://www.perssondennis.com/images/articles/write-solid-react-hooks/write-solid-react-hooks.webp" length="0" type="image/webp"/>
        </item>
    </channel>
</rss>