<?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ł Kardyś</title>
    <description>The latest articles on DEV Community by Michał Kardyś (@kardysm).</description>
    <link>https://dev.to/kardysm</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F617174%2Fb07492f6-5fd6-4b44-bacc-0447574f3843.jpeg</url>
      <title>DEV Community: Michał Kardyś</title>
      <link>https://dev.to/kardysm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kardysm"/>
    <language>en</language>
    <item>
      <title>Singleton-like Context for shared components managent</title>
      <dc:creator>Michał Kardyś</dc:creator>
      <pubDate>Thu, 22 Apr 2021 09:33:44 +0000</pubDate>
      <link>https://dev.to/kardysm/singleton-like-context-for-shared-components-managent-4112</link>
      <guid>https://dev.to/kardysm/singleton-like-context-for-shared-components-managent-4112</guid>
      <description>&lt;p&gt;(story originally appeared at &lt;a href="//kardys.dev"&gt;kardys.dev&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Are you handling external modules or shared config in your React projects?&lt;/p&gt;

&lt;p&gt;React Context, when overused, can become hell. On the other hand, Setting up shared modules/config with Context can be helpful.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to handle shared config?
&lt;/h2&gt;

&lt;p&gt;Regular Context is hidden by Provider down the render tree.&lt;/p&gt;

&lt;p&gt;What if we... make a singleton?&lt;/p&gt;

&lt;p&gt;Single place for your settings is helpful. You have easy go-to place if you need to update your config. Yet, with increasing modularity of your code it becomes harder and harder.&lt;/p&gt;

&lt;p&gt;So, should you setup Redux workflow?&lt;/p&gt;

&lt;p&gt;If the app is not big/complex Redux is not goto. It's like shooting a pigeon with a cannon. Overkill.&lt;/p&gt;

&lt;p&gt;What then?&lt;/p&gt;

&lt;p&gt;Single source of truth would be helpful. A singleton.&lt;/p&gt;

&lt;p&gt;How to do it?&lt;/p&gt;

&lt;p&gt;Let's inverse our context! Let's prevent providers down the tree. Let's...&lt;/p&gt;

&lt;h2&gt;
  
  
  Create context singleton
&lt;/h2&gt;

&lt;p&gt;Simplest implementation for singleton-like context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const NOT_INSTANTIATED = 'NOT_INSTANTIATED';

const Context = React.createContext(NOT_INSTANTIATED);

function SingletonContext(props){
  const value = React.useContext(Context)

  if(value === NOT_INSTANTIATED){
    return &amp;lt;Context.Provider {...props}/&amp;gt;
  }

  return &amp;lt;React.Fragment {...props}/&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens here?&lt;/p&gt;

&lt;p&gt;You create React context with defaul "NOT_INSTATIATED" value. So, if use consume the context and no provider is rendered above - you get the default value.&lt;/p&gt;

&lt;p&gt;Next is wrapper.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SingletonContext&lt;/code&gt; does following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Consumes provider&lt;/li&gt;
&lt;li&gt;If it hasn't been instatiated earlier create provider&lt;/li&gt;
&lt;li&gt;Otherwise return Fragment&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Singleton in action
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Display = () =&amp;gt; {
  const value = React.useContext(Context)

  return &amp;lt;div&amp;gt;{value}&amp;lt;/div&amp;gt;;
};

const App = () =&amp;gt; {
  return &amp;lt;React.Fragment&amp;gt;
    &amp;lt;SingletonContext value={'first'}&amp;gt;
      &amp;lt;SingletonContext value={'second'}&amp;gt;
        &amp;lt;Display/&amp;gt;
      &amp;lt;/SingletonContext&amp;gt;
    &amp;lt;/SingletonContext&amp;gt;
  &amp;lt;/React.Fragment&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we create 2 SingletonContext components, the former Context.Provider is created&lt;/p&gt;

&lt;p&gt;Result is:&lt;br&gt;
&lt;code&gt;first&lt;/code&gt; is passed to &lt;code&gt;Display&lt;/code&gt; consumer&lt;/p&gt;

&lt;p&gt;What if we create parallel Provider?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const App = () =&amp;gt; {
  return &amp;lt;React.Fragment&amp;gt;
    &amp;lt;SingletonContext value={'first'}&amp;gt;
      &amp;lt;SingletonContext value={'second'}&amp;gt;
        &amp;lt;Display/&amp;gt;
      &amp;lt;/SingletonContext&amp;gt;
    &amp;lt;/SingletonContext&amp;gt;

    &amp;lt;SingletonContext value={'separate render tree'}&amp;gt;
      &amp;lt;Display/&amp;gt;
    &amp;lt;/SingletonContext&amp;gt;
  &amp;lt;/React.Fragment&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have, as expected, 2 results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;first&lt;/li&gt;
&lt;li&gt;separate render tree&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That why it's not fully singleton (unless you put it in app root).&lt;/p&gt;

&lt;h2&gt;
  
  
  Use cases
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Config shared between many apps&lt;/li&gt;
&lt;li&gt;Redux singleton (we can render redux provider similar way)&lt;/li&gt;
&lt;li&gt;Many components loosely scattered

&lt;ul&gt;
&lt;li&gt;each needing a common theme provider or so&lt;/li&gt;
&lt;li&gt;this way we can 'safeguard provider' and render it if not present&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is, of course, not 'the only right way' to do things.&lt;/p&gt;

&lt;p&gt;For external modules you might want &lt;a href="https://www.kardys.dev/2021/04/external-modules-in-react-context/"&gt;&lt;strong&gt;this method from my previous post&lt;/strong&gt;&lt;/a&gt;, too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you manage your configs?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;See code in action:&lt;br&gt;
&lt;a href="https://codepen.io/Drak29/pen/gOgBJqO"&gt;codepen&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>dependencies</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Setup external modules with React Context</title>
      <dc:creator>Michał Kardyś</dc:creator>
      <pubDate>Thu, 22 Apr 2021 09:29:35 +0000</pubDate>
      <link>https://dev.to/kardysm/setup-external-modules-with-react-context-3bhl</link>
      <guid>https://dev.to/kardysm/setup-external-modules-with-react-context-3bhl</guid>
      <description>&lt;p&gt;(story originally appeared at &lt;a href="//kardys.dev"&gt;kardys.dev&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;A pattern that is helpful when you use external modules in your app.&lt;/p&gt;

&lt;p&gt;Some time ago Dan Abramov posted this tweet:&lt;br&gt;
&lt;a href="https://twitter.com/dan_abramov/status/1363134687250636800"&gt;Dan Abramov's tweet&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Context.Provider value={&amp;lt;RenderedComponent /&amp;gt;}&amp;gt;
  &amp;lt;Something /&amp;gt;
&amp;lt;/Context.Provider&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern is neither necessary nor common, yet it is useful at certain times.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are use cases?
&lt;/h2&gt;

&lt;p&gt;The pattern is helpful when external modules arise. What exactly do I mean by external module?&lt;/p&gt;

&lt;p&gt;See, chat. Let's assume you have SPA and you want to add Intercom-like chat to your app.&lt;/p&gt;

&lt;p&gt;Should you setup it somewhere down in your render-tree? &lt;/p&gt;

&lt;p&gt;It is an option.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FloatingButton.jsx
//...
&amp;lt;Chat
    prop1={prop1}
    flag
    anotherFlag
    /&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Yet,&lt;/p&gt;

&lt;h2&gt;
  
  
  What if you need a change?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You might need it in 2+ places:

&lt;ul&gt;
&lt;li&gt;under a floating button&lt;/li&gt;
&lt;li&gt;or when user selects 'help' section&lt;/li&gt;
&lt;li&gt;so, you instantiate 2 some components 2 times?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;You might want to keep all external configs in one place

&lt;ul&gt;
&lt;li&gt;to have an eye on dependencies&lt;/li&gt;
&lt;li&gt;to slowly replace all externals with your internal code&lt;/li&gt;
&lt;li&gt;would looking for all of these usages be simple? It might&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;...but there's another way&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup external component with context
&lt;/h2&gt;

&lt;p&gt;What if instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FloatingButton.jsx
//...
&amp;lt;Chat
    prop1={prop1}
    flag
    anotherFlag
    /&amp;gt;

HelpSection.jsx
//...
&amp;lt;Chat
    prop1={prop1}
    flag
    anotherFlag
    /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ExternalModules
export const ExternalChatProvider = (props) =&amp;gt; &amp;lt;Context.Provider value={&amp;lt;Chat
    prop1={prop1}
    flag
    anotherFlag
    /&amp;gt;}
    {...props}
    /&amp;gt;
export const ExternalChatConsumer = (props) =&amp;gt; &amp;lt;Context.Consumer {...props}/&amp;gt;

Main
//...
&amp;lt;ExternalChatProvider&amp;gt;
    &amp;lt;SPA/&amp;gt;
&amp;lt;/ExternalChatProvider&amp;gt;

FloatingButton
//...
&amp;lt;ExternalChatConsumer/&amp;gt;

HelpSection
//...
&amp;lt;ExternalChatConsumer/&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;has single point of config&lt;/li&gt;
&lt;li&gt;follows DRY rule&lt;/li&gt;
&lt;li&gt;clearly signals that module is external (read: possibly unsafe)&lt;/li&gt;
&lt;li&gt;rendered once&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've simplified code, but you could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add memoization,&lt;/li&gt;
&lt;li&gt;parametrize it,&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This technique is useful not only for external modules, but for using shared components in general.&lt;/p&gt;

&lt;p&gt;A word of caution: do not overuse&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;context is additional component,&lt;/li&gt;
&lt;li&gt;it causes jumps in logic and&lt;/li&gt;
&lt;li&gt;it is harder to read app flow with to many contexts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How do you manage external components?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>context</category>
      <category>frontend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Safer (and fast) refactoring in React</title>
      <dc:creator>Michał Kardyś</dc:creator>
      <pubDate>Thu, 22 Apr 2021 09:26:14 +0000</pubDate>
      <link>https://dev.to/kardysm/safer-and-fast-refactoring-in-react-https-www-kardys-dev-2021-04-safer-refactoring-in-react-230m</link>
      <guid>https://dev.to/kardysm/safer-and-fast-refactoring-in-react-https-www-kardys-dev-2021-04-safer-refactoring-in-react-230m</guid>
      <description>&lt;p&gt;(story originally appeared at &lt;a href="//kardys.dev"&gt;kardys.dev&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;How snapshot testing is great for refactoring&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple process
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Snapshots work for things like data structures (as regular tests).&lt;/li&gt;
&lt;li&gt;Refactoring is another great use case.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here, I'm talking about refactoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  To refactor, you need stability.
&lt;/h2&gt;

&lt;p&gt;You work on SaaS app's frontend. New features flow in. You (or your teammates) develop new pieces of code.&lt;/p&gt;

&lt;p&gt;What comes next?&lt;/p&gt;

&lt;p&gt;At one point you need to refactor "little piece of code". And here you feel like you go through gates of hell.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you edit &lt;code&gt;X&lt;/code&gt; - component &lt;code&gt;A&lt;/code&gt; breaks down&lt;/li&gt;
&lt;li&gt;you fix it, &lt;code&gt;A&lt;/code&gt; works now - but suddenly &lt;code&gt;Y&lt;/code&gt; fails&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The deeper you go, the more problems arise. Even, when you try to edit just "one thing".&lt;/p&gt;

&lt;p&gt;Does it often has to be like this?&lt;/p&gt;

&lt;p&gt;Yes, I've exarregated situation (have I?).&lt;/p&gt;

&lt;p&gt;Yet, we need to be sure if our refactoring works as before.&lt;/p&gt;

&lt;p&gt;Otherwise we blow up part of the system and we are not aware of that.&lt;/p&gt;

&lt;p&gt;How to refactor code safely without too much hassle?&lt;/p&gt;

&lt;h2&gt;
  
  
  Snapshot testing stabilize your code
&lt;/h2&gt;

&lt;p&gt;Snapshots have had its 5 minutes.&lt;/p&gt;

&lt;p&gt;When these arised, I've seen articles about snaps everywhere. People praising simplicity were most common.&lt;/p&gt;

&lt;p&gt;The simplicity came with its' hidden cost. At one point I've made the same mistake.&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;too many snapshat tests.&lt;/li&gt;
&lt;li&gt;too many and too fragile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tests have indicated changes in structure. Most often the change was meaningless (for instance, autogenerated class name change).&lt;/p&gt;

&lt;p&gt;It builds insensitivity to further warnings. A good reason to avoid these.&lt;/p&gt;

&lt;p&gt;But, there's great use case for snapshot testing which I learned some time ago.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Refactoring with snapshot tests
&lt;/h2&gt;

&lt;p&gt;The process is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You make snapshot of a component you want to refactor. (don't commit these)&lt;/li&gt;
&lt;li&gt;You refactor the code&lt;/li&gt;
&lt;li&gt;If snapshot test passes after refactor, delete test.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Test is temporary. You don't have to push it anywhere.&lt;/p&gt;

&lt;p&gt;It is just your helper, so you are certain that after refactoring, result looks exactly the same&lt;/p&gt;

&lt;h2&gt;
  
  
  Check it out.
&lt;/h2&gt;

&lt;p&gt;It's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;simple&lt;/li&gt;
&lt;li&gt;fast&lt;/li&gt;
&lt;li&gt;easy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How do you refactor your code?&lt;/strong&gt;&lt;/p&gt;

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