<?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>Forem: Mykola Harmash</title>
    <description>The latest articles on Forem by Mykola Harmash (@mykolaharmash).</description>
    <link>https://forem.com/mykolaharmash</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%2F427112%2Fdf4e0f60-8610-4737-8e65-ecd8e702cfc4.jpeg</url>
      <title>Forem: Mykola Harmash</title>
      <link>https://forem.com/mykolaharmash</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mykolaharmash"/>
    <language>en</language>
    <item>
      <title>SwiftUI State Management Fundamentals</title>
      <dc:creator>Mykola Harmash</dc:creator>
      <pubDate>Wed, 29 Mar 2023 10:20:10 +0000</pubDate>
      <link>https://forem.com/mykolaharmash/swiftui-state-management-fundamentals-5220</link>
      <guid>https://forem.com/mykolaharmash/swiftui-state-management-fundamentals-5220</guid>
      <description>&lt;p&gt;This article is an attempt to help beginners, like myself, understand fundamental things about SwiftUI. This is the type of article I wish existed when I was just starting. Hope it’ll save you some time and struggle.&lt;/p&gt;

&lt;p&gt;Feel free to leave a comment with corrections or general feedback.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;In order to really understand state management in SwiftUI, and in order to follow along with this article, you need to know a couple of things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Difference between value type and reference type&lt;/li&gt;
&lt;li&gt;What property wrappers are and roughly how they work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don’t feel confident enough about those topics, please take a moment to read these documents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/classesandstructures/"&gt;Structures and Classes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties#Property-Wrappers"&gt;Property Wrappers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Otherwise, let’s dive in.&lt;/p&gt;




&lt;h2&gt;
  
  
  Application Pipeline
&lt;/h2&gt;

&lt;p&gt;On a very high level, every app is a pipeline that takes some event as an input (user gesture, system notification, timer, etc.) and produces an output, most often by drawing something on the screen.&lt;/p&gt;

&lt;p&gt;Different frameworks have different intermediate steps between input and output. In SwiftUI, the pipeline looks roughly like this:&lt;/p&gt;

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




&lt;h2&gt;
  
  
  Ephemeral Views
&lt;/h2&gt;

&lt;p&gt;Take a look at the &lt;em&gt;Re-create Views&lt;/em&gt; step in the pipeline. By Views, I mean our custom &lt;code&gt;structs&lt;/code&gt; with the &lt;code&gt;body&lt;/code&gt; property, just to be clear.&lt;/p&gt;

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

&lt;p&gt;It’s one of the crucial points when it comes to understanding the application state in SwiftUI. A lot of other concepts are direct consequences of this fact:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Views are disposed of and re-created every time an event occurs and the observed state changes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This means we cannot reliably keep any data within our views. We need some other (external) place to store the application state.&lt;/p&gt;

&lt;p&gt;Luckily, SwiftUI has built-in storage outside of the view hierarchy which we can use: SwiftUI State. This state is managed entirely by the framework, and we access it only through the provided API.&lt;/p&gt;




&lt;h2&gt;
  
  
  Triggering View Re-creation
&lt;/h2&gt;

&lt;p&gt;From the pipeline, you can also see that the only way to make SwiftUI re-create our views and, eventually, to re-render the screen is to update the observed data.&lt;/p&gt;

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

&lt;p&gt;This means that we, somehow, need to tell SwiftUI to look for changes in some properties of our view and when they occur — re-create the view.&lt;/p&gt;




&lt;h2&gt;
  
  
  @State
&lt;/h2&gt;

&lt;p&gt;So, to recap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We need a way to put data in SwiftUI state which lives outside of our views&lt;/li&gt;
&lt;li&gt;We need to tell SwiftUI to observe changes in some properties, so the framework knows when to re-create views and re-render&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;@State&lt;/code&gt; property wrapper solves both problems at once. Let’s look at the simple app and its state layout.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;@State&lt;/code&gt; creates an observable container for our property and puts it outside of the view. SwiftUI now keeps the connection between our view and the observed data. So that next time this view is re-created, it can inject the data into the corresponding property of the view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/QfLI_Xh8GeI"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;a href="https://gist.github.com/mykolaharmash/06fe28006cfa1588c41b19e386846bf2"&gt;Source code of the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that &lt;code&gt;Counter&lt;/code&gt; view has &lt;code&gt;init()&lt;/code&gt; with &lt;code&gt;print()&lt;/code&gt; inside.&lt;/p&gt;

&lt;p&gt;Every time the &lt;em&gt;Random&lt;/em&gt; button is pressed you see a message in the XCode console, meaning the &lt;code&gt;Counter&lt;/code&gt; view was re-created, but the &lt;code&gt;count&lt;/code&gt; keeps the same number because it’s stored outside of the view and injected every time the view is created.&lt;/p&gt;


&lt;h2&gt;
  
  
  View Re-creation vs. View Disappearance
&lt;/h2&gt;

&lt;p&gt;It’s worth mentioning the distinction between SwiftUI disposing of an old version of a view before creating a new one and your code intentionally excluding a view from rendering.&lt;/p&gt;

&lt;p&gt;In the latter case, SwiftUI will notice that the view is not a part of the rendered screen anymore and will release all the values it kept for this view in the state. The next time your code decides to show the view again, its properties will be put back in the state with their initial values.&lt;/p&gt;

&lt;p&gt;Here is a demo of this effect.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Rgtu1GAtZbM"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;a href="https://gist.github.com/mykolaharmash/bc2608096cc48a6e0b418a0178a89151"&gt;Source code of the example&lt;/a&gt;&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;shameless plug&lt;/strong&gt;&lt;br&gt;
I try to regularly post useful dev content on &lt;a href="https://twitter.com/mykolaharmash"&gt;my Twitter&lt;/a&gt;, feel free to follow me there 😉&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  @State With Reference Types
&lt;/h2&gt;

&lt;p&gt;A common misconception is that you cannot use &lt;code&gt;@State&lt;/code&gt; with reference types like classes. You definitely can, there is no technical limitation to do it.&lt;/p&gt;

&lt;p&gt;You just need to keep in mind that the property you wrap with &lt;code&gt;@State&lt;/code&gt; will hold a reference, and a reference will be the only thing SwiftUI will store in the state and observe for changes.&lt;/p&gt;

&lt;p&gt;Remember that if you update a property of a reference type, its reference does not change. So to SwiftUI, it will look like nothing happened.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;@State&lt;/code&gt; does not care what to wrap with an observable container and put in the state, it’ll do it just the same way it does for value types.&lt;/p&gt;

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

&lt;p&gt;If you try to run this code you’ll see that it does not work.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/HWuFBD2sPTk"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;a href="https://gist.github.com/mykolaharmash/a47b109bbdbdc613693dcc1673a6cc08"&gt;Source code of the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, I’m updating the &lt;code&gt;count&lt;/code&gt; property by using &lt;code&gt;increment()&lt;/code&gt; and it updates as it should. The only thing is that reference that lives in SwiftUI state does not ever change, so the view is never re-created, and the screen is never updated.&lt;/p&gt;

&lt;p&gt;Logically, to fix this example we need to update the reference every time we hit the button.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/jOw1lG35xrk"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;a href="https://gist.github.com/mykolaharmash/a9929ed3e9704db66c18b76d4945f14f"&gt;Source code of the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This works, but in most cases, it’s not quite the solution we really want. Re-creating an instance every time might be wasteful in a lot of cases, not to mention that code written this way does not communicate the intent really well. We want to increment the count on a counter, not a brand new counter every time.&lt;/p&gt;


&lt;h2&gt;
  
  
  ObservableObject, @ObservedObject and @Published
&lt;/h2&gt;

&lt;p&gt;These three play together to give us a way to change individual properties of a reference type and still communicate changes to SwiftUI, so it knows to re-render.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ObservableObject&lt;/code&gt; is a protocol you adopt on your reference type and &lt;code&gt;@ObservedObject&lt;/code&gt; is a property wrapper for a view property, which holds a reference.&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;@ObservedObject&lt;/code&gt; on a property, you are basically saying to SwiftUI to go and look inside the object that the property holds a reference to. Look inside and subscribe to changes from properties that are marked with &lt;code&gt;@Published&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@Published&lt;/code&gt; wraps a property on a reference type with the observable container, just like &lt;code&gt;@State&lt;/code&gt; does it for view properties.&lt;/p&gt;

&lt;p&gt;This is how it looks in the code of the Counter app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TsrMvjL_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xisn9lijllk53vimloa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TsrMvjL_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xisn9lijllk53vimloa.png" alt="Image description" width="880" height="593"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://gist.github.com/mykolaharmash/f91d636a2079b443b5f788f12f9009eb"&gt;Source code of the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it works with just calling &lt;code&gt;increment()&lt;/code&gt;, without re-creating the counter every time.&lt;/p&gt;

&lt;p&gt;Unfortunately, this approach has a flaw and you can see it in the image above. SwiftUI State is empty. &lt;code&gt;@ObservedObject&lt;/code&gt; does not put data outside of the view as &lt;code&gt;@State&lt;/code&gt; does. And in case an object is created within a view, every time the view is re-created the object will be re-created as well.&lt;/p&gt;

&lt;p&gt;Here is a demo of this effect.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/jnRKpbiaKGI"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;a href="https://gist.github.com/mykolaharmash/915f9252d655b860f040a36983a3d8d1"&gt;Source code of the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice how the counter at the top resets every time the Random button is pressed. When we update the &lt;code&gt;random&lt;/code&gt; property, SwiftUI executes the body of the &lt;code&gt;ContentView&lt;/code&gt; and re-creates &lt;code&gt;CounterView&lt;/code&gt; along the way. The newly created &lt;code&gt;CounterView&lt;/code&gt; ends up with a fresh instance of the &lt;code&gt;Counter&lt;/code&gt; every single time.&lt;/p&gt;


&lt;h2&gt;
  
  
  @StateObject
&lt;/h2&gt;

&lt;p&gt;This is where &lt;code&gt;@StateObject&lt;/code&gt; can help us out. It does all the same things as &lt;code&gt;@ObservedObject&lt;/code&gt; but additionally puts observed properties into the state outside of the view hierarchy.&lt;/p&gt;

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

&lt;p&gt;Below, watch a demo with the &lt;em&gt;Random&lt;/em&gt; button, where it uses the &lt;code&gt;@StateObject&lt;/code&gt; on the &lt;code&gt;counter&lt;/code&gt; property this time.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/8MBExUZk2wQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  When to use @ObservedObject instead of @StateObject?
&lt;/h2&gt;

&lt;p&gt;It might seem that we just need to use &lt;code&gt;@StateObject&lt;/code&gt; all the time and forget about &lt;code&gt;@ObservedObject&lt;/code&gt;. But there is a very good use case when you need both.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;@StateObject&lt;/code&gt; in the view which creates an object. Use &lt;code&gt;@ObservedObject&lt;/code&gt; when the view receives objects from outside.&lt;/p&gt;

&lt;p&gt;Consider this example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H9fN2pKk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bbswcftf2bmt8zl8edjj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H9fN2pKk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bbswcftf2bmt8zl8edjj.png" alt="Image description" width="880" height="673"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://gist.github.com/mykolaharmash/87e4733423b08e787ee797b6a5570999"&gt;Source code of the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that even though two views reference and observe at the same &lt;code&gt;Counter&lt;/code&gt; instance, SwiftUI state keeps only one value for the &lt;code&gt;count&lt;/code&gt; property. This is because we’ve used &lt;code&gt;@ObservedObject&lt;/code&gt; on the &lt;code&gt;CounterView&lt;/code&gt;, which does not put anything into the state.&lt;/p&gt;




&lt;p&gt;Thank you for reading, I hope it was helpful! 🙌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/mykolaharmash"&gt;My Twitter&lt;/a&gt; in case you'd like to reach out.&lt;/p&gt;

</description>
      <category>swiftui</category>
      <category>swift</category>
      <category>ios</category>
      <category>mobile</category>
    </item>
    <item>
      <title>3 Tools and 2 Commands to Improve Your Git Workflow</title>
      <dc:creator>Mykola Harmash</dc:creator>
      <pubDate>Sat, 12 Sep 2020 18:38:05 +0000</pubDate>
      <link>https://forem.com/mykolaharmash/3-tools-and-2-commands-to-improve-your-git-workflow-483m</link>
      <guid>https://forem.com/mykolaharmash/3-tools-and-2-commands-to-improve-your-git-workflow-483m</guid>
      <description>&lt;p&gt;Let's start with tools. Takes only a couple of minutes to set them up and soon it will be painful to use Git without them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://micro-editor.github.io"&gt;Micro&lt;/a&gt; as Default Editor
&lt;/h2&gt;

&lt;p&gt;Unless you're using Vim as your main IDE, you need something that resembles your GUI editor but on the command line, with standard navigation, mouse support, and syntax highlighting. &lt;a href="https://micro-editor.github.io"&gt;Micro&lt;/a&gt; is exactly that.&lt;/p&gt;

&lt;p&gt;Install and set it as your Git editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; core.editor micro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Td8oV1fX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kwn62r36kaqm9wrmykk9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Td8oV1fX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kwn62r36kaqm9wrmykk9.png" alt="micro@2x" width="880" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/so-fancy/diff-so-fancy"&gt;diff-so-fancy&lt;/a&gt; Instead of Default Diff
&lt;/h2&gt;

&lt;p&gt;Standard diff is fine, but with minimal effort, it can be even better. Take a look, left - standard, right - &lt;a href="https://github.com/so-fancy/diff-so-fancy"&gt;diff-so-fancy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sH1ssyOm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jso3buzxns35nli0ct9n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sH1ssyOm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jso3buzxns35nli0ct9n.jpg" alt="diff-so-fancy@2x" width="880" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Less clutter and more information. Install it and modify the config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; core.pager &lt;span class="s2"&gt;"diff-so-fancy | less --tabs=4 -RFX"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;a href="https://github.com/mykolaharmash/git-jump"&gt;git jump&lt;/a&gt; for Better Experience With Branches
&lt;/h2&gt;

&lt;p&gt;I've built this tool to fulfill my own need, but the feedback confirmed that other people have the same issues when it comes to dealing with a large number of Git branches.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mykolaharmash/git-jump"&gt;git-jump&lt;/a&gt; puts recently used branches on top of the list, has fuzzy-search, and interactive UI among other things.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tAoQkp8O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bahhnc8h3f8nr61dwx3o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tAoQkp8O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bahhnc8h3f8nr61dwx3o.gif" alt="git-jump" width="563" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No setup required, just install and use.&lt;/p&gt;




&lt;p&gt;Now to the commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get a Single File From a Different Branch or Commit
&lt;/h2&gt;

&lt;p&gt;Messed up a file? No need to go to GitHub or stash changes to look it up in a different branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git restore &lt;span class="nt"&gt;--source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;commit or branch&amp;gt; &amp;lt;file path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fixup and Squash
&lt;/h2&gt;

&lt;p&gt;This one requires some habits adjustments, but it's worth it.&lt;/p&gt;

&lt;p&gt;While doing code-reviews this is a very common workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Push changes in a single commit with a nice message&lt;/li&gt;
&lt;li&gt;Collect feedback from teammates&lt;/li&gt;
&lt;li&gt;Create a bunch of other commits with messages like "fix", "review", etc.&lt;/li&gt;
&lt;li&gt;Squash all commits into the first one with the clean message&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, on step 3, use &lt;code&gt;git commit --fixup=HEAD&lt;/code&gt;. This will re-use commit message from the previous commit and add &lt;code&gt;fixup!&lt;/code&gt; prefix to it.&lt;/p&gt;

&lt;p&gt;Next, on step 4, use &lt;code&gt;git rebase -i --autosquash &amp;lt;rebase target&amp;gt;&lt;/code&gt;. &lt;code&gt;--autosquash&lt;/code&gt; flag will mark &lt;code&gt;fixup!&lt;/code&gt; commits to be squashed automatically. You just need to save and quit rebase editor.&lt;/p&gt;

&lt;p&gt;And sure, set up your own shortcut aliases. Real time-saver.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0V0zmLkF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z7mda0plvdq5hj6swcnr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0V0zmLkF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z7mda0plvdq5hj6swcnr.png" alt="fixup" width="880" height="671"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Hope you've picked something for yourself. Please leave a comment with your personal Git tweaks. 👋 &lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/mykolaharmash"&gt;Follow me on Twitter&lt;/a&gt;, I post there useful dev stuff.&lt;/p&gt;

</description>
      <category>git</category>
      <category>tooling</category>
      <category>workflow</category>
    </item>
    <item>
      <title>React Hook for Handling Boolean State</title>
      <dc:creator>Mykola Harmash</dc:creator>
      <pubDate>Wed, 08 Jul 2020 19:00:33 +0000</pubDate>
      <link>https://forem.com/mykolaharmash/react-hook-for-handling-boolean-state-4kfk</link>
      <guid>https://forem.com/mykolaharmash/react-hook-for-handling-boolean-state-4kfk</guid>
      <description>&lt;p&gt;&lt;code&gt;useBoolean&lt;/code&gt; hook. &lt;a href="https://github.com/mykolaharmash/use-boolean"&gt;Check out the source&lt;/a&gt;, it does exactly the thing you would be doing yourself when dealing with the visibility of pop-ups, dropdowns and alike. No more no less.&lt;/p&gt;

&lt;p&gt;Just a small convenience which I use in my code, made it into a standalone package in order to avoid duplication across projects.&lt;/p&gt;

&lt;p&gt;And here is a live example.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/summer-sun-44zj2?view=editor"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mykolaharmash/use-boolean"&gt;useBoolean on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/mykola_harmash"&gt;My Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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