<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michał Pietraszko</title>
    <description>The latest articles on DEV Community by Michał Pietraszko (@pietmichal).</description>
    <link>https://dev.to/pietmichal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F51140%2Ff590ac3d-76e1-48a3-bef4-4fc6b96be101.jpg</url>
      <title>DEV Community: Michał Pietraszko</title>
      <link>https://dev.to/pietmichal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pietmichal"/>
    <language>en</language>
    <item>
      <title>How To Structure Your App In a Way That Scales.</title>
      <dc:creator>Michał Pietraszko</dc:creator>
      <pubDate>Sun, 27 Jun 2021 19:50:07 +0000</pubDate>
      <link>https://dev.to/pietmichal/how-to-structure-your-app-in-a-way-that-scales-bkf</link>
      <guid>https://dev.to/pietmichal/how-to-structure-your-app-in-a-way-that-scales-bkf</guid>
      <description>&lt;p&gt;The best codebases I found myself working on had their folders structured around the features the app provides. &lt;/p&gt;

&lt;p&gt;Some folks might tell that it is very close to the Domain-Driven Design's principle of &lt;a href="https://martinfowler.com/bliki/BoundedContext.html"&gt;bounded contexts&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  The App We Will Structure
&lt;/h2&gt;

&lt;p&gt;Thinking of application as a feature that contains features creates a robust mental model that can be easily mapped to the folder structure of your project.&lt;/p&gt;

&lt;p&gt;The following example will refer to a Single-Page Application written in JavaScript that consists of the following building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Routes - root components displayed when an URL is used,&lt;/li&gt;
&lt;li&gt;Components - logical units handling state and rendering,&lt;/li&gt;
&lt;li&gt;Queries - functions calling an HTTP API,&lt;/li&gt;
&lt;li&gt;Styles - CSS bound to the specific component they are named after,&lt;/li&gt;
&lt;li&gt;Services - logical units handling overarching problems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember, this pattern can be applied to any programming language, framework, and problem domain. &lt;/p&gt;

&lt;p&gt;For example, a game could use shaders, prefabs, entities, and systems as its own building blocks instead.&lt;/p&gt;

&lt;p&gt;My goal here is to present the idea in an easy-to-digest way. For this reason, I'll make a few simplifications when we go through the evolutionary steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Genesis
&lt;/h2&gt;

&lt;p&gt;Our app will start with login and register features. &lt;/p&gt;

&lt;p&gt;It should be able to take input data and communicate with the API. &lt;/p&gt;

&lt;p&gt;When a user is logged in, then they will be able to see some kind of message that they have an active session.&lt;/p&gt;

&lt;p&gt;The simplest way to start is with one file. From this point, we will take a few steps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├─ index.js
├─ style.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The features are apparent when someone opens the &lt;code&gt;index.js&lt;/code&gt; file. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Buckets
&lt;/h2&gt;

&lt;p&gt;Now, imagine the business wants the app to do more. They say, that after the user logs in, they should see the dashboard with charts representing important data.&lt;/p&gt;

&lt;p&gt;You start writing code and at one point the sense of guilt ensues... the &lt;code&gt;index.js&lt;/code&gt; file became too large and you think that as a good engineer you should organize your code better.&lt;/p&gt;

&lt;p&gt;Usually, people organize the code in what I like to refer to as &lt;em&gt;buckets&lt;/em&gt; and end up with something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├─ services/
│  ├─ session.service.js
├─ components/
│  ├─ button.component.js
│  ├─ input.component.js
│  ├─ piechart.component.js
│  ├─ linechart.component.js
├─ routes/
│  ├─ login.route.js
│  ├─ register.route.js
│  ├─ dashboard.route.js
├─ styles/
│  ├─ input.component.css
│  ├─ button.component.css
│  ├─ piechart.component.css
│  ├─ linechart.component.css
│  ├─ dashboard.route.css
│  ├─ login.route.css
│  ├─ register.route.css
├─ queries/
│  ├─ login.query.js
│  ├─ register.query.js
│  ├─ dashboard.query.js
├─ index.js
├─ style.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is there an objective problem, at this point, with this? No. Things might feel alright because every concept has its own bucket. There is not much functionality, but as it grows - your feelings might change.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Features
&lt;/h2&gt;

&lt;p&gt;Now, the business says that we should add some reports that will allow users to see critical information - for example, how much money they've gained and how much money they've lost. These are expected to include tabular data and charts.&lt;/p&gt;

&lt;p&gt;Let's add more to the buckets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├─ services/
│  ├─ session.service.js
├─ components/
│  ├─ button.component.js
│  ├─ input.component.js
│  ├─ data-table.component.js
│  ├─ piechart.component.js
│  ├─ linechart.component.js
│  ├─ barchart.component.js
├─ routes/
│  ├─ login.route.js
│  ├─ register.route.js
│  ├─ dashboard.route.js
│  ├─ loses-report.route.js
│  ├─ gains-report.route.js
├─ styles/
│  ├─ input.component.css
│  ├─ button.component.css
│  ├─ data-table.component.css
│  ├─ piechart.component.css
│  ├─ linechart.component.css
│  ├─ barchart.component.css
│  ├─ dashboard.route.css
│  ├─ login.route.css
│  ├─ register.route.css
│  ├─ loses-report.route.css
│  ├─ gains-report.route.css
├─ queries/
│  ├─ login.query.js
│  ├─ register.query.js
│  ├─ dashboard.query.js
│  ├─ gains-report.query.js
│  ├─ loses-report.query.js
├─ index.js
├─ style.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a lot of files scattered around. &lt;/p&gt;

&lt;p&gt;Ask yourself the following questions. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it immediately obvious to you what features the app consists of?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it clear what features are dependent on each other?&lt;/strong&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Feature-driven Folder Structure
&lt;/h2&gt;

&lt;p&gt;Let's take a step back and write down what features and areas of concern the app covers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login

&lt;ul&gt;
&lt;li&gt;Receives data input&lt;/li&gt;
&lt;li&gt;Cares about current session&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Registration

&lt;ul&gt;
&lt;li&gt;Receives data input&lt;/li&gt;
&lt;li&gt;Cares about current session&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Dashboard

&lt;ul&gt;
&lt;li&gt;Visualization via charts&lt;/li&gt;
&lt;li&gt;Cares about current session&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Loses Reporting

&lt;ul&gt;
&lt;li&gt;Visualization via data table&lt;/li&gt;
&lt;li&gt;Visualization via charts&lt;/li&gt;
&lt;li&gt;Cares about current session&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Gains Reporting

&lt;ul&gt;
&lt;li&gt;Visualization via data table&lt;/li&gt;
&lt;li&gt;Visualization via charts&lt;/li&gt;
&lt;li&gt;Cares about current session&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think about the whole app as a feature. &lt;/p&gt;

&lt;p&gt;Also, think about each bullet point as a separate feature. &lt;/p&gt;

&lt;p&gt;Each feature is specialized in one problem domain. &lt;/p&gt;

&lt;p&gt;Some features &lt;em&gt;are shared&lt;/em&gt; between features.&lt;/p&gt;

&lt;p&gt;Let's map this to the folder structure. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Please keep in mind that structure might differ depending on a person and the team working on the codebase!&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├─ shared/
│  ├─ session/
│  │  ├─ session.service.js
│  ├─ data-table/
│  │  ├─ data-table.component.js
│  │  ├─ data-table.component.css
│  ├─ data-input/
│  │  ├─ button.component.js
│  │  ├─ button.component.css/
│  │  ├─ input.component.js/
│  │  ├─ input.component.css
│  ├─ charts/
│  │  ├─ piechart.component.js
│  │  ├─ piechart.component.css
│  │  ├─ linechart.component.js
│  │  ├─ linechart.component.css
│  │  ├─ barchart.component.js
│  │  ├─ barchart.component.css
├─ login/
│  ├─ login.route.js
│  ├─ login.route.css
│  ├─ login.query.js
├─ register/
│  ├─ register.route.js
│  ├─ register.route.css
│  ├─ register.service.js
│  ├─ register.query.js
├─ dashboard/
│  ├─ dashboard.route.js
│  ├─ dashboard.route.css
│  ├─ dashboard.query.js
├─ gains-report/
│  ├─ gains-report.route.js
│  ├─ gains-report.route.css
│  ├─ gains-report.query.js
├─ loses-report/
│  ├─ loses-report.route.js
│  ├─ loses-report.route.css
│  ├─ loses-report.query.js
├─ style.css
├─ index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask yourself the following questions, &lt;strong&gt;again&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it immediately obvious to you what features the app consists of?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it clear what features are dependent on each other?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;From my experience, a developer can immediately tell what features the app has and where they have to go if they have the task of modifying the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature of Features... of Features?
&lt;/h2&gt;

&lt;p&gt;The problem I've experienced when applying this pattern was the shared program expanding to unmanageable size creating a similar problem to "the buckets" approach.&lt;/p&gt;

&lt;p&gt;There is one trick to deal with this. &lt;/p&gt;

&lt;p&gt;Take a look at the structure above and try to tell what shared features are not related to everything? &lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;charts&lt;/strong&gt; and *&lt;em&gt;data table&lt;/em&gt; features.&lt;/p&gt;

&lt;p&gt;The important thing to remember is that the feature-driven pattern has no limit to how deep the structure can go.&lt;/p&gt;

&lt;p&gt;It should go as deep or as flat to ensure comfort &lt;em&gt;which is subjective&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Check the following example of how the structure can be made to represent the relationship between features even better.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├─ shared/
│  ├─ session/
│  │  ├─ session.service.js
│  ├─ data-input/
│  │  ├─ button.component.js
│  │  ├─ button.component.css/
│  │  ├─ input.component.js/
│  │  ├─ input.component.css
├─ login/
│  ├─ login.route.js
│  ├─ login.route.css
│  ├─ login.query.js
├─ register/
│  ├─ register.route.js
│  ├─ register.route.css
│  ├─ register.service.js
│  ├─ register.query.js
├─ reporting/ 
│  ├─ data-table/
│  │  ├─ data-table.component.js
│  │  ├─ data-table.component.css
│  ├─ charts/
│  │  ├─ piechart.component.js
│  │  ├─ piechart.component.css
│  │  ├─ linechart.component.js
│  │  ├─ linechart.component.css
│  │  ├─ barchart.component.js
│  │  ├─ barchart.component.css
│  ├─ dashboard/
│  │  ├─ dashboard.route.js
│  │  ├─ dashboard.route.css
│  │  ├─ dashboard.query.js
│  ├─ gains-report/
│  │  ├─ gains-report.route.js
│  │  ├─ gains-report.route.css
│  │  ├─ gains-report.query.js
│  ├─ loses-report/
│  │  ├─ loses-report.route.js
│  │  ├─ loses-report.route.css
│  │  ├─ loses-report.query.js
├─ style.css
├─ index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you traverse the codebase, you can clearly see what you are looking at and what are the dependencies that you take into consideration.&lt;/p&gt;

&lt;p&gt;This way you can add as many features as you need and the structural complexity should be proportional to the actual problem the app tries to solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;Keep in mind that there is a lot of space when it comes to organizing code in a feature-driven way and people can come up with different structures.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There is no objectively correct structure.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can also mix "the bucket" and feature-driven approaches. &lt;/p&gt;

&lt;p&gt;This is because sometimes it might be easier for the eyes to just put shared single components into components folder to avoid many single file folders.&lt;/p&gt;

&lt;p&gt;The important thing is to define your own rules of thumb and stick to them. &lt;/p&gt;

&lt;p&gt;You can always reflect back and refactor the structure as the codebase evolves.&lt;/p&gt;

</description>
      <category>react</category>
      <category>architecture</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>React Hooks Factories</title>
      <dc:creator>Michał Pietraszko</dc:creator>
      <pubDate>Sun, 07 Mar 2021 14:38:45 +0000</pubDate>
      <link>https://dev.to/pietmichal/react-hooks-factories-48bi</link>
      <guid>https://dev.to/pietmichal/react-hooks-factories-48bi</guid>
      <description>&lt;p&gt;Factory pattern with React Hooks is not mentioned often enough however, it is often used in popular libraries to push composition to its limits.&lt;/p&gt;

&lt;p&gt;It can also be used to simplify, in some cases optimise, sharing state across the React app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Factory Pattern Crash Course
&lt;/h2&gt;

&lt;p&gt;Factory pattern is used to bring an ability to create objects on the runtime.&lt;/p&gt;

&lt;p&gt;It usually looks like this. Bear in mind that these are simple examples to paint a picture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Factory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// { name: "Bob" }&lt;/span&gt;

&lt;span class="c1"&gt;// Alternatively, without classes&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// { name: "Bob" }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  First Hook Factory
&lt;/h2&gt;

&lt;p&gt;It will be a custom hook wrapping &lt;code&gt;useState&lt;/code&gt; but it will set a default value provided at the time of creation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Factory function that returns a new function that uses Hooks API.&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useHook&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create the hook.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useHook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;some initial value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Use the hook in the component.&lt;/span&gt;
&lt;span class="c1"&gt;// The component will output: "State is: some initial value"&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useHook&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      State is: &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Hook Factory With Custom Logic
&lt;/h2&gt;

&lt;p&gt;Factories unlock the next level of composition.&lt;br&gt;
For example, a factory can produce a hook that can be given custom logic at the time of creation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Factory function that returns a new function that uses Hooks API.&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createMappedState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;// Define a custom setter applying custom logic.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// return a tuple to make API similar to React.useState&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// You can create as many custom hooks you need&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useUppercasedString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createMappedState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useLowercasedString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createMappedState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;// Use the hook in the component.&lt;/span&gt;
&lt;span class="c1"&gt;// The component will output:&lt;/span&gt;
&lt;span class="c1"&gt;// `&lt;/span&gt;
&lt;span class="c1"&gt;// String is: SOME VALUE&lt;/span&gt;
&lt;span class="c1"&gt;// String is: some value&lt;/span&gt;
&lt;span class="c1"&gt;// `&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;string1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setString1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useUppercasedString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Some Value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;string2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setString2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLowercasedString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Some Value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      String1 is: &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;string1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;br&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      String2 is: &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;string2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sharing state across hooks to create context without Context API
&lt;/h2&gt;

&lt;p&gt;Factories get interesting when you realize that the new function has access to the scope of the factory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createSharedStateHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sharedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;

  &lt;span class="c1"&gt;// An array in a shared scope.&lt;/span&gt;
  &lt;span class="c1"&gt;// Produced hook will always refer to it.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stateSetters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="c1"&gt;// This function will update all components&lt;/span&gt;
  &lt;span class="c1"&gt;// that use the hook created by the factory.&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setAllStates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;sharedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="nx"&gt;stateSetters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useSharedState&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// On mount, add the setter to shared array.&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stateSetters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// On unmount, remove the setter.&lt;/span&gt;
        &lt;span class="nx"&gt;stateSetters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="c1"&gt;// The trick is to have the hook to return the same instance of `setAllStates`&lt;/span&gt;
    &lt;span class="c1"&gt;// at all times so the update will propagate through all components using the produced hook.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAllStates&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useSharedState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createSharedStateHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;initial&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useAnotherSharedState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createSharedStateHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;another initial&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// `useSharedState` and `useAnotherSharedState` do not share the same state&lt;/span&gt;
&lt;span class="c1"&gt;// because returned hooks have access to different scopes.&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useSharedState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      Shared state is: &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;AnotherComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useAnotherSharedState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      Another shared state is: &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSharedState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useSharedState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setSharedState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;br&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AnotherComponent&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;br&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;br&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modifier&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, this hook provides a shared state without having to wrap an app with a Context Provider.&lt;/p&gt;

&lt;p&gt;Not having to wrap a large section of the tree brings an alternative way to optimise re-renders without having to resort to more advanced APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Is Using This Pattern?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://material-ui.com/"&gt;Material-UI&lt;/a&gt;'s &lt;a href="https://material-ui.com/styles/advanced/#makestyles"&gt;&lt;code&gt;makeStyles&lt;/code&gt;&lt;/a&gt; function allows to create styles for specific components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/astoilkov/use-local-storage-state"&gt;use-local-storage-state&lt;/a&gt; - the prime example that inspired me to write this blog post.&lt;/p&gt;

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

&lt;p&gt;React Hooks are a great way to compose functionality in the ecosystem. Adding a factory pattern on top of it opens the door to more interesting ways to solve problems beyond stitching hooks together.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Web apps are too complex. This is how we can simplify them.</title>
      <dc:creator>Michał Pietraszko</dc:creator>
      <pubDate>Sun, 10 Jan 2021 19:54:32 +0000</pubDate>
      <link>https://dev.to/pietmichal/web-apps-are-too-complex-this-is-how-we-can-simplify-them-3ala</link>
      <guid>https://dev.to/pietmichal/web-apps-are-too-complex-this-is-how-we-can-simplify-them-3ala</guid>
      <description>&lt;p&gt;I believe that we can do a better job of managing the complexity of our apps.&lt;/p&gt;

&lt;p&gt;Not many of us realize how many second-order effects our decisions have caused.&lt;/p&gt;

&lt;p&gt;Let's see how complexity had grown over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Static era
&lt;/h2&gt;

&lt;p&gt;Simple times. We had a MySQL database, business logic and HTML + CSS views.&lt;/p&gt;

&lt;p&gt;All content was static, the browser's job was to display content, navigate and submit forms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6i0fx778jj4u69x2kkmc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6i0fx778jj4u69x2kkmc.png" alt="Simple web app architecture diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I like to think about test effort as a benchmark for simplicity. There were 3 layers.&lt;/p&gt;

&lt;p&gt;Business logic and persistence layer can be easily integrated and view layer can be browser tested.&lt;/p&gt;

&lt;p&gt;You may need a tester, developer, and a designer to maintain something like this. It is realistic to have one person responsible for all of this.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AJAX era
&lt;/h2&gt;

&lt;p&gt;JavaScript opened a door for more considerations in user experience. Adding a dynamic menu, forms, or calendar to a WordPress website was the coolest thing you could do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpbp4dpy1b2jicgd2rqoy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpbp4dpy1b2jicgd2rqoy.png" alt="web app with javascript architecture diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have a complexity spike on the client-side.&lt;/p&gt;

&lt;p&gt;Many browsers differed in JS implementation, which required jQuery to come into existence.&lt;/p&gt;

&lt;p&gt;This gave a lot of power to designers and has moved more engineering effort into the front end. JavaScript made the browser extensible.&lt;/p&gt;

&lt;p&gt;Did the testing complexity increase? Yes. Each new JavaScript bit could only be tested in a browser.&lt;/p&gt;

&lt;p&gt;This requires testing, backend programming, JavaScript, and design expertise in your team. Jumping between server-side and client-side languages became frustrating. There was a trend to have different people responsible for each side.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Single-page era
&lt;/h2&gt;

&lt;p&gt;Remember the first example of the Angular.js app? The input field that automatically updated the content of the div? Good times.&lt;/p&gt;

&lt;p&gt;Welcome to the single-page era where front-end development became even more complex than back-end development - mostly due to relevant logic moving to the client. As a result, the divide has increased and &lt;a href="https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4" rel="noopener noreferrer"&gt;JavaScript fatigue&lt;/a&gt; became a thing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3k6calmaslod3oub31cv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3k6calmaslod3oub31cv.png" alt="single-page application architecture diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have ended up with two apps that are tightly coupled.&lt;/p&gt;

&lt;p&gt;To maintain this, you need at least someone experienced in testing, backend, frontend development (extensive framework, tooling, and browser knowledge), and design.&lt;/p&gt;

&lt;p&gt;Now, two apps have to be maintained, and there is much more code than ever. You have to maintain unit, integration, and end to end tests on both sides. Now business logic is not directly accessible due to security concerns.&lt;br&gt;
Frontend and backend now have to maintain layers that are responsible for communication.&lt;/p&gt;

&lt;p&gt;Client code needs lots of API mocks to be tested on lower levels - DOM tests are resource-heavy.&lt;/p&gt;

&lt;p&gt;Orchestration becomes difficult because you have to make sure that deployments are synchronized. It is even more difficult if you have separate teams for the backend and frontend.&lt;/p&gt;

&lt;p&gt;Don't forget about browser testing that also can have a lot of overlap with client-side integration tests. Even more, things to consider in terms of complexity and trade-offs.&lt;/p&gt;

&lt;p&gt;That resulted in more code, which contributed to - again - increased complexity.&lt;/p&gt;

&lt;p&gt;SEO became problematic, but thankfully this problem has been addressed by the ecosystem through &lt;a href="https://reactjs.org/docs/react-dom-server.html" rel="noopener noreferrer"&gt;server-side rendering&lt;/a&gt; and &lt;a href="https://reactjs.org/docs/react-dom.html#hydrate" rel="noopener noreferrer"&gt;hydration&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Good patterns have emerged too. UX became better and more creative. We are finally capable of defining client-side logic in a manageable and scalable way.&lt;/p&gt;

&lt;p&gt;We all know now that we want to have components and avoid excessive side effects, together with uncontrollable state mutation.&lt;/p&gt;

&lt;p&gt;React de facto became a standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplicity renaissance
&lt;/h2&gt;

&lt;p&gt;The remedy to complexity is embracing the coupling and making the developer experience unified.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Simplicity through innovation in older frameworks.
&lt;/h3&gt;

&lt;p&gt;Ruby on Rails and Laravel are relevant.&lt;/p&gt;

&lt;p&gt;Consider them. Their maturity will allow you to move very fast.&lt;/p&gt;

&lt;p&gt;They have recently innovated in many interesting ways.&lt;/p&gt;

&lt;p&gt;Take a look at &lt;a href="https://laravel.com/docs/8.x/blade#components" rel="noopener noreferrer"&gt;Laravel's components&lt;/a&gt; or RoR's &lt;a href="https://hotwire.dev/" rel="noopener noreferrer"&gt;Hotwire&lt;/a&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  Next generation of JavaScript frameworks
&lt;/h3&gt;

&lt;p&gt;People who want to stay in JavaScript land should consider the following.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; started a good trend by putting React and server logic next to each other.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blitzjs.com/" rel="noopener noreferrer"&gt;Blitz.js&lt;/a&gt;, which is based on Next, is a good ruby on rails equivalent. It brings the right amount of abstraction that makes you treat your app as a unified whole. Using it sometimes feels like cheating - in a good way. It inspired me to talk about the complexity issue in our ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://remix.run/" rel="noopener noreferrer"&gt;Remix&lt;/a&gt; with a fresh take on the problem domain and bringing a lot of good and forgotten patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  React's Server Components to make everything even better.
&lt;/h3&gt;

&lt;p&gt;Recently, the React team has presented a new idea that can make our component-driven world better.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html" rel="noopener noreferrer"&gt;Consider reading the article and watching their presentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When they are released, then we will end up in the best-case scenario where web apps are only dynamic in&lt;br&gt;
places that require it without having to jump between server-side and client-side paradigms.&lt;/p&gt;

&lt;p&gt;All of the frameworks above will benefit from them.&lt;/p&gt;

&lt;h2&gt;
  
  
  In conclusion
&lt;/h2&gt;

&lt;p&gt;We should start asking ourselves if our standard approach is something we still want to maintain.&lt;/p&gt;

&lt;p&gt;Suggested frameworks reduce complexity and allow us to experience the simplicity of older approaches while having the benefits of the modern approach.&lt;/p&gt;

&lt;p&gt;They embrace the fact that both backend and frontend are tightly coupled and make the developer experience unified.&lt;/p&gt;

&lt;p&gt;This is an opportunity to write less code, spend less time testing, simplify orchestration, spend less money on more people having to maintain the complexity, and put more effort into products we are trying to create.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to post on DEV and still own your content effortlessly.</title>
      <dc:creator>Michał Pietraszko</dc:creator>
      <pubDate>Wed, 30 Dec 2020 20:22:03 +0000</pubDate>
      <link>https://dev.to/pietmichal/how-to-post-on-dev-and-still-own-your-content-effortlessly-1amc</link>
      <guid>https://dev.to/pietmichal/how-to-post-on-dev-and-still-own-your-content-effortlessly-1amc</guid>
      <description>&lt;p&gt;DEV is a great platform to start blogging but it doesn't give a straightforward way of owning your content. Some bloggers are asking how to set up a custom domain on DEV which unfortunately is not possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does owning content mean and why would I want to do it?
&lt;/h2&gt;

&lt;p&gt;It means that your content isn't bound to a specific platform.&lt;/p&gt;

&lt;p&gt;If DEV becomes irrelevant then for any reason, you shouldn't be affected by it. Your content should accessible no matter what and you are the one deciding what happens to it. Locking yourself to a specific platform will set you back if you want to become independent at one point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why to post on DEV if you want to own your content?
&lt;/h2&gt;

&lt;p&gt;The community. You can reach more people if you make your content visible in as many places as possible. Also, DEV enables interaction via comments. Don't forget the SEO it has.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to post on DEV and still own my content? What is the secret?
&lt;/h2&gt;

&lt;p&gt;Fortunately, there is a way to benefit from posting on DEV and content ownership.&lt;/p&gt;

&lt;p&gt;You can achieve it effortlessly by using Netlify with Gatsby Starter Blog and making sure that canonical tags are properly maintained.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Gatsby starter blog?
&lt;/h2&gt;

&lt;p&gt;It gives you a very good foundation for a personal blog that is very well optimised. Also, both DEV and Gatsby blog starter use markdown for content creation which boils down maintenance to copying markdown files and adjusting the front matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I do it?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Before you start.
&lt;/h3&gt;

&lt;p&gt;Create a GitHub account if you don't have one already.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up a personal blog.
&lt;/h3&gt;

&lt;p&gt;Open gatsby blog starter repo which is available &lt;a href="https://github.com/gatsbyjs/gatsby-starter-blog"&gt;here&lt;/a&gt; and click on &lt;a href="https://app.netlify.com/start/deploy?repository=https://github.com/gatsbyjs/gatsby-starter-blog"&gt;"Deploy to Netlify"&lt;/a&gt; button which is at the bottom of the page.&lt;/p&gt;

&lt;p&gt;Follow all of the steps and tada 🎉 you have a Gatsby blog!&lt;/p&gt;

&lt;h3&gt;
  
  
  Buying and setting up a domain
&lt;/h3&gt;

&lt;p&gt;It is not mandatory, but I strongly recommend doing it straight away. You'll avoid the pain of having to move content to a new domain if you decide to set it up later.&lt;/p&gt;

&lt;p&gt;Follow the guide from Netlify which you can access &lt;a href="https://docs.netlify.com/domains-https/netlify-dns/domain-registration/#register-a-new-domain"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modifying your Gatsby blog.
&lt;/h3&gt;

&lt;p&gt;Pull your repository via your favourite GIT client.&lt;/p&gt;

&lt;p&gt;Update &lt;code&gt;siteUrl&lt;/code&gt; entry in &lt;code&gt;gatsby-config.js&lt;/code&gt; file so it has your domain. This will ensure that all URLs are generated properly.&lt;/p&gt;

&lt;p&gt;Delete all files from &lt;code&gt;content/blog&lt;/code&gt; directory. You don't need example posts in your blog.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding canonical tags to your blog.
&lt;/h3&gt;

&lt;p&gt;Now, the critical part. You have to update the site so it applies a canonical tag for each page. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without it, Google will punish you for duplicating content.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The canonical tag tells Google which URL is the source.&lt;/p&gt;

&lt;p&gt;Gatsby has a plugin for that, follow &lt;a href="https://www.gatsbyjs.com/plugins/gatsby-plugin-canonical-urls/"&gt;this guide&lt;/a&gt; to implement them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing your content.
&lt;/h3&gt;

&lt;p&gt;What I am doing at the moment is the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write my post on DEV.&lt;/li&gt;
&lt;li&gt;Update the front matter with &lt;code&gt;canonical_url&lt;/code&gt;. In case of this post it looks like this: &lt;code&gt;canonical_url: https://michalpietraszko.com/how-to-post-on-dev-and-still-own-your-content-effortlessly&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Copy the content to a markdown file in my repo. 
In my case it goes to &lt;code&gt;content/blog/how-to-post-on-dev-and-still-won-your-content-effortlessly/index.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add entries to the front matter that are specific to my blog such as &lt;code&gt;description&lt;/code&gt; or &lt;code&gt;date&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Push changes to my repo.&lt;/li&gt;
&lt;li&gt;Publish my post on DEV.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rinse and repeat and enjoy the benefits of owning your content and DEV!&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to make an accurate estimate? You don't.</title>
      <dc:creator>Michał Pietraszko</dc:creator>
      <pubDate>Sat, 26 Dec 2020 12:38:13 +0000</pubDate>
      <link>https://dev.to/pietmichal/how-to-make-an-accurate-estimate-you-don-t-13f5</link>
      <guid>https://dev.to/pietmichal/how-to-make-an-accurate-estimate-you-don-t-13f5</guid>
      <description>&lt;p&gt;A recent popular tweet made me worry because people might agree with it for the wrong reason.&lt;/p&gt;

&lt;p&gt;Without calling out people, all of it boils down to this quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't trust developer estimates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;People saying it and agreeing with it is a sign of the problem. It paints a picture of a developer being a person you cannot trust and makes less experienced folks feel bad.&lt;/p&gt;

&lt;p&gt;The issue spans beyond twitter. Many books and engineers talk about it a lot. I bet somebody gave you the advice to double or triple your estimates as a rule of thumb.&lt;/p&gt;

&lt;p&gt;Everyone involved in software projects has to stop ignoring the fact that an &lt;strong&gt;estimate implies uncertainty&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dealing with uncertainty.
&lt;/h2&gt;

&lt;p&gt;Reality changes every day. What worked a month ago is not guaranteed to bring the same results this month - especially in the modern world.&lt;/p&gt;

&lt;p&gt;What we do carries a risk. We should embrace the fact that we cannot eradicate it and focus on reducing it instead.&lt;/p&gt;

&lt;p&gt;If the estimation is uncertain, then it does not reflect reality - be it story points or actual hours. Why would you want to bet on it then?&lt;/p&gt;

&lt;p&gt;Focus on the objective. I don't mean finishing user story A, B, and C. &lt;strong&gt;Don't confuse it with a task.&lt;/strong&gt; Think of it more like &lt;strong&gt;the outcome&lt;/strong&gt; you want to reach. You might want to improve conversion in a specific channel, help customers do X, or assess the viability of a technology.&lt;/p&gt;

&lt;p&gt;If your measurements had proven that something you do is not working as expected, then it is time to take learnings, apply them, and continue what you are doing or pivot.&lt;/p&gt;

&lt;p&gt;Rinse and repeat until you achieve your desired outcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dealing with time.
&lt;/h2&gt;

&lt;p&gt;Time exists, we can't deny that, but estimate still means nothing when it comes to delivering actual value.&lt;/p&gt;

&lt;p&gt;I am not saying that you should always take your sweet time. You still have to impose limits on yourself.&lt;/p&gt;

&lt;p&gt;Give yourself a time frame for contribution. Be it a two-week sprint goal or a quarterly objective measured by key results.&lt;/p&gt;

&lt;p&gt;You still have to take your organization's and team's values into consideration. Some might find unpolished look acceptable. Others might not.&lt;/p&gt;

&lt;p&gt;Combining the limits with clear objectives and values can yield results faster. They might not be what you have expected, but it is better to learn about it sooner than later.&lt;/p&gt;

&lt;p&gt;Some might say that they need a time estimate so they can put pressure on themselves or their team. More sensible people consider the unpredictable nature of estimation and double, or triple, them just in case.&lt;/p&gt;

&lt;p&gt;There is a problem with this mindset. It switches the focus from delivering value to getting specific things done on time. Time spent is not directly proportional to the value.&lt;/p&gt;

&lt;p&gt;You don't reduce risk by increasing the estimated time. You are reducing risk by validating your assumptions often instead.&lt;/p&gt;

&lt;p&gt;If you are worried about how much time work will take, focus on reducing the friction in your team instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if they still expect you to give an estimate.
&lt;/h2&gt;

&lt;p&gt;If you agree with the organization's reasoning or are willing to accept it, then go for it.&lt;/p&gt;

&lt;p&gt;If you are not, then you can try influencing people around you - which is a great skill to learn - and be good friends with them or consider looking for new opportunities.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>agile</category>
      <category>career</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
