<?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: Riccardo Coppola</title>
    <description>The latest articles on DEV Community by Riccardo Coppola (@ricca509).</description>
    <link>https://dev.to/ricca509</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%2F350420%2F4b581efc-d9e5-4710-8ec2-2335fa83d95b.jpeg</url>
      <title>DEV Community: Riccardo Coppola</title>
      <link>https://dev.to/ricca509</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ricca509"/>
    <language>en</language>
    <item>
      <title>Build feature flags in React using the Context API: how to</title>
      <dc:creator>Riccardo Coppola</dc:creator>
      <pubDate>Mon, 30 Mar 2020 09:27:00 +0000</pubDate>
      <link>https://dev.to/ricca509/build-feature-flags-in-react-using-the-context-api-how-to-4dgj</link>
      <guid>https://dev.to/ricca509/build-feature-flags-in-react-using-the-context-api-how-to-4dgj</guid>
      <description>&lt;p&gt;&lt;em&gt;One of the tenets of lean development is "deliver fast, deliver often".&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now, this can become tricky when you have to add new, big features to an application that is already live, or you have to delay a release to a specific day (e.g. changing the landing page for a big sale).&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;How can we build (and leverage) &lt;a href="https://martinfowler.com/articles/feature-toggles.html"&gt;feature flags (or feature toggles)&lt;/a&gt; to improve both the development/release workflow and the user experience?&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The case for releasing features "in the dark"
&lt;/h1&gt;

&lt;p&gt;Suppose you have a successful, high traffic blog built in React and you want to add a list of featured posts at the top. The first step would be to break this feature or epic down into smaller stories with your team. &lt;/p&gt;

&lt;p&gt;Let's assume that these are the stories you come up with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create an empty container for the featured posts&lt;/li&gt;
&lt;li&gt;display a list of unstyled posts&lt;/li&gt;
&lt;li&gt;add style to the list of posts&lt;/li&gt;
&lt;li&gt;add UX behaviour to the list of posts, such as a link to the post page and author page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can expect to have other work ongoing in parallel, like maintaining the blog, making small UI changes etc so how do you handle this big feature release? You definitely cannot go live with an empty container at the top of the page, or with a list of unstyled text that has no behaviour.&lt;/p&gt;

&lt;p&gt;One solution may be to create a long-living branch that you rebase on to master as often as you manage to remember (and fix all the conflicts every time), and build the whole feature there, then do a big-bang release of all the code. I don't need to go on to explain why this is a bad decision on so many levels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Another solution is to use feature flags to wrap your new feature so that you release the code to production as often as you want, following your usual development/release workflow, you just don't display it to the user.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Following is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This configuration can come from wherever you prefer:&lt;/span&gt;
&lt;span class="c1"&gt;// a config file, a mongo database, etc&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;features&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;featuredPosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;span class="c1"&gt;// In your react component&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FeaturedPosts&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./featured-posts&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;HomePage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;features&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;// ... other content&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;features&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;featuredPosts&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FeaturedPosts&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;// ... other content&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/article&lt;/span&gt;&lt;span class="err"&gt;&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;So the idea behind feature flags is to ship code "in the dark", without the user seeing it.&lt;br&gt;
This way you can keep your big feature within your normal development/delivery flow, just hidden from the final users.&lt;/p&gt;
&lt;h1&gt;
  
  
  React implementation
&lt;/h1&gt;

&lt;p&gt;I want to create a small component to wrap content with so that I can decide whether or not to render it based on the value of a feature flag. &lt;/p&gt;

&lt;p&gt;To keep this as simple as possible, the following is the way I see this component being used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FeaturedPosts&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./featured-posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Feature&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;featuredPosts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FeaturedPosts&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Feature&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a very declarative, React-like way of consuming features.&lt;/p&gt;

&lt;p&gt;Where do I get the features' list from, though? And what a possible implementation may look like?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reactjs.org/docs/context.html"&gt;React Context&lt;/a&gt; can help inject a list of features into the application and retrieve it later, as for the component implementation, let's have a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&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;FeaturesContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FeaturesProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;FeaturesContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Feature&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;children&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FeaturesContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;children&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="kc"&gt;null&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;flags&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="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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;First of all, I am creating a &lt;code&gt;FeaturesContext&lt;/code&gt; to be used later to wrap my app.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Feature&lt;/code&gt; component then takes the feature's name and the children and based on the boolean state of the feature, it'll either render the children (if the feature is enabled) or &lt;code&gt;null&lt;/code&gt;. It can do it because it's got access to the list of feature flags from the context.&lt;/p&gt;

&lt;p&gt;Following is a usage example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FeaturedPosts&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./featured-posts&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;HomePage&lt;/span&gt; &lt;span class="o"&gt;=&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="cm"&gt;/* other content */&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Feature&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;featuredPosts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FeaturedPosts&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Feature&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="cm"&gt;/* other content */&lt;/span&gt;    
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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;const&lt;/span&gt; &lt;span class="nx"&gt;features&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;featuredPosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;App&lt;/span&gt; &lt;span class="o"&gt;=&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FeaturesProvider&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;features&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HomePage&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/FeaturesProvider&lt;/span&gt;&lt;span class="err"&gt;&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;h1&gt;
  
  
  Adding MVT (MultiVariate Testing) support
&lt;/h1&gt;

&lt;p&gt;The use case for MVT is when you want to try out different variations of the same feature (e.g. trying out three different colors for call to action buttons) to see which one is the best performer.&lt;/p&gt;

&lt;p&gt;We can easily extend the &lt;code&gt;Feature&lt;/code&gt; component to support MVT by adding a &lt;code&gt;variation&lt;/code&gt; property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Feature&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;variation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FeaturesContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;variation&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;flags&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="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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;flags&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="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;variation&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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;In the code above, if we don't receive a &lt;code&gt;variation&lt;/code&gt;, we treat the flag as a &lt;code&gt;Boolean&lt;/code&gt; otherwise we only render the correct variation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/react-ff?" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Thoughts on deployment environments
&lt;/h1&gt;

&lt;p&gt;Many projects are deployed through a series of environments (dev, staging, pre-prod, &lt;em&gt;add your name here&lt;/em&gt;) before being released to production.&lt;/p&gt;

&lt;p&gt;This can allow for additional levels of testing, usually E2E tests, to be carried out. You can fully test the code behind a feature flag by having different settings for different environments: one of the practices that I'd use is to have all features enabled on a staging environment and run all level of tests against them, then have them turned off in pre-prod and prod. &lt;/p&gt;

&lt;p&gt;This way you have the confidence of having well-tested features and the ability to keep them hidden until it's release time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Feature flags and technical debt
&lt;/h1&gt;

&lt;p&gt;Technical debt is a reality in every application we build. It can be kept under control, but real-life scenarios call for technical debt to be created in order to deliver faster in some periods or accommodate for temporary business requirements. &lt;/p&gt;

&lt;p&gt;It is like a loan: you need it, but you also need to have a plan in place to pay it back.&lt;/p&gt;

&lt;p&gt;Feature flags add to technical debt because they are part of the code only for a short amount of time and need to be removed afterwards, without actually being a user feature. &lt;/p&gt;

&lt;p&gt;This doesn't mean they shouldn't be used, the opposite actually, but there must be a plan in place to clean up the code: every time you use them, make sure your stories include points about removing the feature flag wrapping your code and update the tests to reflect the presence of the feature, plus anything else you may have to do.&lt;/p&gt;

&lt;p&gt;Enjoy your improved workflow!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Replace Redux with Hooks and the Context API: how to</title>
      <dc:creator>Riccardo Coppola</dc:creator>
      <pubDate>Mon, 16 Mar 2020 10:31:00 +0000</pubDate>
      <link>https://dev.to/ricca509/replace-redux-with-hooks-and-the-context-api-how-to-4m77</link>
      <guid>https://dev.to/ricca509/replace-redux-with-hooks-and-the-context-api-how-to-4m77</guid>
      <description>&lt;p&gt;&lt;em&gt;Is it possible to use the new React Context API and hooks to completely replace Redux? Is it worth it? Does it yield the same results and is the solution as easy to use as Redux + React-redux?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With the advent of the new &lt;a href="https://reactjs.org/docs/context.html"&gt;React Context API&lt;/a&gt;, passing data deep down in an application became easier and with the new &lt;a href="https://reactjs.org/docs/hooks-intro.html"&gt;hooks&lt;/a&gt;, I started to see a lot of posts advertising that replacing Redux was possible. I wanted to find out for myself, so I started looking closer at the React docs and try to build my own Redux.&lt;/p&gt;

&lt;p&gt;The following is what I found out and what I came up with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context API
&lt;/h2&gt;

&lt;p&gt;One of the challenges of React is how to pass props to components deep down the tree; props that are "global" to the application, that many components may want to use and usually represent configuration, UI theme, translations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Context provides a way to pass data through the component tree without having to pass props down manually at every level.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How to use it
&lt;/h3&gt;

&lt;p&gt;To start building a Redux-like library, I want to make available a &lt;code&gt;state&lt;/code&gt; object and a &lt;code&gt;dispatch&lt;/code&gt; function to the whole application, so let's build an example that takes advantage of the Context API and does just that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create a context with a default value&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StateContext&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;createContext&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="na"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;:&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="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentUsingContext&lt;/span&gt; &lt;span class="o"&gt;=&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// Wrap the component using the value with the context consumer&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StateContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Consumer&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;state&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&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;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/StateContext.Consumer&lt;/span&gt;&lt;span class="err"&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="c1"&gt;// Wrap your component with the provider and pass a value &lt;/span&gt;
&lt;span class="c1"&gt;// if you don't want to use the default&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StateContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;counter&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="na"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dispatch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ComponentUsingContext&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/StateContext.Provider&lt;/span&gt;&lt;span class="err"&gt;&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;The above is a quick look at how you can use the Context to send data down the components' tree, and it doesn't look very different from the React Redux Provider that you use to wrap your app with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note how you create a &lt;code&gt;Context&lt;/code&gt; first, then use the &lt;code&gt;Context.Provider&lt;/code&gt; to send data down into the tree and &lt;code&gt;Context.Consumer&lt;/code&gt; to use that data at any nesting level.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The part using the &lt;code&gt;Context.Consumer&lt;/code&gt; looks a bit more complex than I'd like, but there is a hook that makes it look at lot cleaner (more on this in a sec).&lt;/p&gt;

&lt;p&gt;Now that we have a way to "inject" data into an app, let's see how we can leverage hooks to build the additional features required to replace Redux.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hooks
&lt;/h2&gt;

&lt;p&gt;Hooks were introduced in React 16.8.0 to tackle different classes of problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Making it easier to reuse stateful logic between components &lt;/li&gt;
&lt;li&gt;Move away from classes, their inherent verbosity and the use of this&lt;/li&gt;
&lt;li&gt;Making more use of ahead-of-time compilation to create optimised code (and classes can encourage patterns that make it difficult)&lt;/li&gt;
&lt;li&gt;Probably other reasons, which I am not aware of 😇&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among all the hooks that come with React, &lt;code&gt;useContext&lt;/code&gt; and &lt;code&gt;useReducer&lt;/code&gt; are the ones that can help build a Redux-like library in React.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;useContext&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;const value = useContext(MyContext);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It is an alternative to using the &lt;code&gt;Context.Consumer&lt;/code&gt; pattern (and makes the code looks more readable in my opinion).&lt;/p&gt;

&lt;p&gt;Let's see it applied to the previous Context example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&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;StateContext&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;createContext&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="na"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;:&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="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentUsingContext&lt;/span&gt; &lt;span class="o"&gt;=&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="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;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;StateContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;---&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&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;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&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;App&lt;/span&gt; &lt;span class="o"&gt;=&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StateContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;counter&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="na"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dispatch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ComponentUsingContext&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/StateContext.Provider&lt;/span&gt;&lt;span class="err"&gt;&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;You still have to use the &lt;code&gt;Context.Provider&lt;/code&gt;, but retrieving the values from the context looks a lot better now.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;useReducer&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;const [state, dispatch] = useReducer(reducer, initialArg, init);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;useReducer&lt;/code&gt; hook accepts a reducer (same as you'd write for Redux) and an initial state and return the new state with a dispatch method.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;state&lt;/code&gt; and &lt;code&gt;dispatch&lt;/code&gt; are exactly what I need to pass down the application through the &lt;code&gt;React.Context&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trying to put things together
&lt;/h2&gt;

&lt;p&gt;The API of my Redux-like library should include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;code&gt;Provider&lt;/code&gt; to wrap the app and inject the state and dispatch method&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;useStore&lt;/code&gt; method to create a store (containing the state and dispatch method) to pass to the Provider&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;connect&lt;/code&gt; method to hook a component to the state&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Provider
&lt;/h3&gt;

&lt;p&gt;The provider would simply be a &lt;code&gt;Context.Provider&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Context&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;createContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// No default needed here&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  connect
&lt;/h3&gt;

&lt;p&gt;A very basic &lt;code&gt;connect&lt;/code&gt; would accept a &lt;code&gt;Component&lt;/code&gt;, then make use of the &lt;code&gt;useContext&lt;/code&gt; to get the &lt;code&gt;state&lt;/code&gt; and &lt;code&gt;dispatch&lt;/code&gt; and then pass them to it.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&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="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;dispatch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Context&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;props&lt;/span&gt; &lt;span class="o"&gt;=&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;dispatch&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&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;This is of course a very basic version, that passes the whole state to the component: not exactly what I want.&lt;/p&gt;
&lt;h3&gt;
  
  
  Introducing &lt;code&gt;mapStateToProps&lt;/code&gt; and &lt;code&gt;mapDispatchToProps&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The Redux &lt;code&gt;connect&lt;/code&gt; method makes use of &lt;code&gt;mapStateToProps&lt;/code&gt; to map the whole state to the props that the component needs.&lt;/p&gt;

&lt;p&gt;It also uses &lt;code&gt;mapDispatchToProps&lt;/code&gt; to pass actions wrapped by the dispatch method as props to the component.&lt;/p&gt;

&lt;p&gt;I wanted to support those methods too, so this is an improved version, that also supports the component's own props:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt; &lt;span class="o"&gt;=&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;mapDispatchToProps&lt;/span&gt; &lt;span class="o"&gt;=&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="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ownProps&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;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Context&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;stateProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;ownProps&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;dispatchProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ownProps&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;props&lt;/span&gt; &lt;span class="o"&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;ownProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;stateProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;dispatchProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatch&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&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;So here I added support for &lt;code&gt;mapStateToProps&lt;/code&gt; and &lt;code&gt;mapDispatchToProps&lt;/code&gt;, providing a default value that returns an empty object in case those arguments are not provided. I then added the &lt;code&gt;dispatch&lt;/code&gt; method so that the component can use it to dispatch actions.&lt;/p&gt;
&lt;h3&gt;
  
  
  useStore
&lt;/h3&gt;

&lt;p&gt;This is just a utility hook that uses &lt;code&gt;useReducer&lt;/code&gt; to create a store and returns it, pretty much like &lt;code&gt;createStore&lt;/code&gt; in Redux. It also creates a &lt;code&gt;getState&lt;/code&gt; function that returns the state.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&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="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;dispatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialState&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;getState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&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;getState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatch&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;The following snippet puts it all together in the same file to make it easier to read and understand:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h2&gt;
  
  
  A working example
&lt;/h2&gt;

&lt;p&gt;Here's your usual counter example using the code I just discussed (notice my CSS skills):&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/redux-no-redux-example?" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  An important note about re-renders
&lt;/h2&gt;

&lt;p&gt;You may wonder how the application re-renders since I am never using &lt;code&gt;setState&lt;/code&gt;, which is a requirement to trigger a re-render in React.&lt;/p&gt;

&lt;p&gt;In Redux, the connect method triggers a &lt;code&gt;forceUpdate&lt;/code&gt; when the store changes, but here?&lt;/p&gt;

&lt;p&gt;The solution lies in how the &lt;code&gt;useContext&lt;/code&gt; hook works:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A component calling &lt;code&gt;useContext&lt;/code&gt; will always re-render when the context value changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More on this in the &lt;a href="https://reactjs.org/docs/hooks-reference.html#usecontext"&gt;React docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to now?
&lt;/h2&gt;

&lt;p&gt;Of course, this example is not nearly as powerful as Redux is, but it proves that Redux can be replaced by Context + Hooks.&lt;/p&gt;

&lt;p&gt;Is it the right thing to do, though? Is it the right pattern to package these new React features into a Redux-like library?&lt;/p&gt;

&lt;p&gt;I believe that these new tools give us an opportunity to find new patterns and leverage the reusability provided by hooks to find better ways to share and access application state at any nesting level. &lt;/p&gt;

&lt;p&gt;We'll find the "right way" iteration after iteration, in true agile spirit.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://www.onefiniteloop.io/replace-redux-with-react-hooks-and-context-api/"&gt;onefiniteloop.io&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>10 tips for working with distributed teams</title>
      <dc:creator>Riccardo Coppola</dc:creator>
      <pubDate>Sat, 14 Mar 2020 20:21:14 +0000</pubDate>
      <link>https://dev.to/ricca509/embrace-distributed-teams-and-be-happy-mkb</link>
      <guid>https://dev.to/ricca509/embrace-distributed-teams-and-be-happy-mkb</guid>
      <description>&lt;p&gt;Remote teams have become the norm, rather than the exception, for many companies requiring software engineering services (and not only). &lt;/p&gt;

&lt;p&gt;They used to be just a small addition to the core, in-house team, but it is not uncommon for them to now represent the bulk of the development force. &lt;/p&gt;

&lt;p&gt;It's not always the case of a company hiring a third party to do the job, sometimes it's just having to coordinate multiple teams of the same company, operating from different locations with different time zones.&lt;br&gt;
There are multiple reasons for this choice: cost, multiple company locations to manage, strong talents availability in less competitive markets, strategic choices and so on.&lt;/p&gt;

&lt;p&gt;Hewlett-Packard (HP) uses these teams to meet the demands of local economies across the world, and as an HP executive states &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We are very dependent on working across the world. It’s our survival, the key to our success. We cannot be a U.S.-centric organization… It’s very common for us to have one project team made up of folks from all of our regions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;“No Borders” 2005, p. 37&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While having remote teams usually brings down the cost considerably, it comes with its own set of everyday challenges that can outweigh the benefits if not properly handled.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Distributed teams are the subject of active &lt;a href="https://pdfs.semanticscholar.org/e3b9/57e8c1f6a286ce3b8876c12701a073a8f0c5.pdf"&gt;research&lt;/a&gt; that questions the extent to which face-to-face and in-person communication is necessary for distributed teams to function effectively and why: empirical tests show that the answer may depend on which team processes and outcomes one is exploring and how distance is measured (Geographical? Cultural? Time zone?). &lt;/p&gt;

&lt;p&gt;Essentially, the challenges of distributed teams fall in one of the following categories: &lt;em&gt;degree of virtuality, degree of distribution, history of the team, degree of (im)permanence, degree of task complexity.&lt;/em&gt; Following are a few points that I found helpful in my experience with working with multinational multicultural (MNMC) distributed teams and that directly or indirectly address the aforementioned categories.&lt;/p&gt;
&lt;h2&gt;
  
  
  Listen, listen, listen. Then act
&lt;/h2&gt;

&lt;p&gt;Communication in a co-located team happens as a result of people sharing the same room at the same time: a side effect of sitting together is feeling more comfortable in sharing ideas and raising issues. &lt;/p&gt;

&lt;p&gt;Working from the same office means ignoring a whole set of issues around distributed communications that can bring productivity to a halt when working with people in different locations.&lt;/p&gt;

&lt;p&gt;The key point in this scenario is to make everyone feel empowered to report problems that would otherwise affect everyone. One way of doing it is to show how serious we are in tackling those issues: &lt;strong&gt;listen carefully, then act effectively&lt;/strong&gt;. Showing care builds trust.&lt;/p&gt;

&lt;p&gt;If the microphone is not working during a meeting and it is being reported by the people on the call, stop and fix it, change it, or change room. Do not resume the discussion until the problem is fixed: losing input from a whole part of the team is much worse than stopping the meeting for a few minutes (or even moving it to a different time).&lt;/p&gt;
&lt;h2&gt;
  
  
  Choose your communication tools wisely
&lt;/h2&gt;

&lt;p&gt;The first step in setting up to work within a distributed environment is to have the right tools in place.&lt;/p&gt;

&lt;p&gt;It is vital to make it easy for people to communicate: you don't want to add any additional barrier to those already created by the distance.&lt;/p&gt;

&lt;p&gt;Whether people sit in the same office or not, &lt;strong&gt;you need a tool to organise and track the work&lt;/strong&gt;: &lt;a href="https://www.atlassian.com/software/jira"&gt;Jira&lt;/a&gt; and &lt;a href="https://trello.com/"&gt;Trello&lt;/a&gt; are the most widely used solutions nowadays, pick the one you and your team like the most, no big deals here. I love physical boards and sticky notes, but they are just not practical with distributed teams.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://slack.com/"&gt;Slack&lt;/a&gt;, &lt;a href="https://teams.microsoft.com/start"&gt;Teams&lt;/a&gt;, &lt;a href="https://www.skype.com/"&gt;Skype&lt;/a&gt; are all valid &lt;strong&gt;chat/conference call tools&lt;/strong&gt; that given a good internet connection, will do their job: it's just a matter of preference. &lt;strong&gt;Choose only one tool&lt;/strong&gt; though, so the chances of discussions getting lost are minimised.&lt;/p&gt;

&lt;p&gt;Make sure you invest in &lt;strong&gt;good headsets&lt;/strong&gt;: I found Sennheiser PC 5 CHAT to be cheap and work perfectly for internet calls. &lt;/p&gt;

&lt;p&gt;Buy the &lt;strong&gt;right hardware for your meeting rooms&lt;/strong&gt;: if you work with Macs, I found Apple TV to be very helpful when it comes to sharing your screen/audio during a call. Another option may be to use Chromecast. Also related to setting up your rooms, having a &lt;strong&gt;conference speakerphone&lt;/strong&gt; can really make a difference when many people are sat around a table and far from the laptop: Jabra Speak 410 proved to be effective for this in my experience. And don't forget a good 1080p webcam!&lt;/p&gt;

&lt;p&gt;In my experience, I found that meetings with everyone in the same room sitting around a microphone are not as effective as meetings when everyone dials in from his/her desk with their headset on: you always end up having issues with people sitting too far from the table and not being heard. My suggestion is for everyone to dial in from their desk, regardless of how many people are involved in the call.&lt;/p&gt;

&lt;p&gt;If your employees are not co-located, then treat every meeting as remote and strive for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;frequent communication&lt;/em&gt;: frequent, spontaneous communications mitigate the effect of distribution on both interpersonal and task conflict and are also linked to highest trust&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;face-to-face communication&lt;/em&gt;: perceived as critical early on in a team’s development and seen as a behaviour that will enhance MNMC team effectiveness (although as time goes on and team members become more familiar with each other, non-face-to-face communication don't seem to hinder team's dynamics)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Communicate early, communicate often
&lt;/h2&gt;

&lt;p&gt;With distributed teams, it is important to learn the value of &lt;strong&gt;over-communicating&lt;/strong&gt;: when decisions are made, they need to be communicated immediately to everyone, along with the reason behind the decision. It's important that everyone has a vision of what is going on in the organisation and the role they can play in making that vision become a reality.&lt;/p&gt;

&lt;p&gt;The risk of teams around the globe working on outdated/wrong information is too high to delay the communication process: make sure everyone always have the latest updates and can adjust their job based on that.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hire a developer advocate
&lt;/h2&gt;

&lt;p&gt;A developer advocate is someone who makes other developers' lives easier: too often developers are busy shipping feature and can't spend time improving their development experience, that's when a developer advocate comes in.&lt;/p&gt;

&lt;p&gt;They can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automate tedious tasks&lt;/li&gt;
&lt;li&gt;prepare "Getting started" guides for new hires&lt;/li&gt;
&lt;li&gt;prepare guidelines for bug reports and troubleshooting how-tos&lt;/li&gt;
&lt;li&gt;help with the definition of Done and Ready&lt;/li&gt;
&lt;li&gt;structure code reviews&lt;/li&gt;
&lt;li&gt;define coding standards and find tools to enforce them&lt;/li&gt;
&lt;li&gt;improve the deployment process&lt;/li&gt;
&lt;li&gt;the list goes on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this with the aim of increasing productivity and improving the developers' lives (which leads to better retention, btw).&lt;/p&gt;

&lt;p&gt;The above points become much more important with distributed teams: given that fast communication is not always possible, having tools and guides in place can make the difference between getting stuck for a day or being able to progress to the next task.&lt;/p&gt;

&lt;p&gt;In general, embrace simplicity and automate whatever possible: the simpler your projects are and the easier it is to work with them, the more productive developers will be. You want to keep the &lt;a href="https://en.wikipedia.org/wiki/Cognitive_load"&gt;cognitive load&lt;/a&gt; as low as possible: co-locate documentation with code, create standards for all teams to follow, enforce and document them and let everyone know, organise workshops and "sell" these concepts to everyone.&lt;/p&gt;
&lt;h2&gt;
  
  
  Clearly define and document roles
&lt;/h2&gt;

&lt;p&gt;You can expect people from different teams to have never worked together before so it is important that everyone in every team know exactly the complete hierarchy with names, photos and ways of getting in touch. This way everyone will always know who to get in touch with depending on the issue they're having or the information they're seeking.&lt;/p&gt;

&lt;p&gt;This diagram would also outline a clear escalation path if an issue arises.&lt;/p&gt;
&lt;h2&gt;
  
  
  Write everything down, always
&lt;/h2&gt;

&lt;p&gt;This is a rule that everyone should follow, whatever the team nature, but it becomes vital when people are not co-located.&lt;/p&gt;

&lt;p&gt;Important discussions don't (can't) always happen during conference calls, decisions are made during a quick lunch, ideas have the tendency to reveal themselves to us at the most peculiar times, but we need all the team to be involved and everyone to know: that is why comments in Jira/Trello are so important as they give everyone visibility over the work that's being done.&lt;/p&gt;

&lt;p&gt;Use the comments, update stories/cards often and use your product management tool as a source of truth for everyone.&lt;/p&gt;
&lt;h2&gt;
  
  
  Enjoy the pleasures and pains of time zone differences
&lt;/h2&gt;

&lt;p&gt;Multinational multicultural distributed teams present opportunities and challenges to organisations: having teams working in different time zones is usually seen as a problem because people have a hard time organising meetings where everyone can attend and issues are resolved slowly because of lack of quick communication.&lt;/p&gt;

&lt;p&gt;Although this definitely represents a challenge, it can also represent an opportunity to prolong the work cycle and increase velocity. In such an environment, blockers can be passed to a fresh pair of eyes at the end of the day and possibly get resolved by next morning, something that would be impossible when following the same working hours.&lt;/p&gt;

&lt;p&gt;Of course, it all comes at a cost, and teams situated in different time zones require more preparation.&lt;/p&gt;

&lt;p&gt;To remove all possible issues and blockers, make sure you: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;spend time during your day (and before their day start) to organise work and detail everything to limit the unknowns and make every team a self-sufficient unit&lt;/li&gt;
&lt;li&gt;review code or designs as soon as possible&lt;/li&gt;
&lt;li&gt;leave actionable feedback in the comments&lt;/li&gt;
&lt;li&gt;ensure they can be as independent as possible during their day and always plan more work in advance so if anything comes up they can progress to another task without getting blocked&lt;/li&gt;
&lt;li&gt;find the golden time when everyone is online and move stand up to that time. If the time difference is really relevant, you may only have a small window of time: use it to make everyone meet and have at least standup all together&lt;/li&gt;
&lt;li&gt;structure your teams as if the whole team was remote: there are not first-class citizens working in a central location, everyone is a remote worker&lt;/li&gt;
&lt;li&gt;Alternate time zones: if you need to have meetings at inconvenient times, make sure you make it "inconvenient" for a different team each month&lt;/li&gt;
&lt;li&gt;have people from different teams having informal 1:1 once a week: this helps to build relationships and trust, making it easier in the future for everyone to communicate issues and blockers without fear. Make a rule to not cancel them because of a "more" important meeting&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Respect and embrace cultural differences
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Globally distributed teams will be effective vehicles for knowledge sharing in an organisation as long as individuals learn the cultural logic of others’ divergent beliefs. If not, culture is constructed as something which divides individuals.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://pdfs.semanticscholar.org/e3b9/57e8c1f6a286ce3b8876c12701a073a8f0c5.pdf"&gt;&lt;em&gt;Multinational and Multicultural Distributed Teams: A Review and Future Agenda&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When working with people living in other parts of the world, there is so much more than a cold colleague-to-colleague relationship to be experienced: I am always impressed by the differences in the way of working and living that I get to experience whenever I work with a new team. &lt;/p&gt;

&lt;p&gt;I always make it a priority to get to know and experience their culture as much as possible: be it food, architecture, history. Every country has something peculiar that can spark my interest and that enriches not only me as a person but gives me a common ground to create a better environment at work. Just by looking at specific traits of a country can reveal so much about the people I am working with and, needless to say, helps a lot with the daily work relationships.&lt;/p&gt;

&lt;p&gt;Knowing people personalities, habits and needs will help you with the daily organisation of work in a way that can improve productivity and boost team morale: people that see their culture respected will inevitably be happier when working with you. This may mean adjusting your communication patterns to use/avoid words or phrases that may be offensive, moving meetings to avoid specific parts of their day.&lt;/p&gt;

&lt;p&gt;If you're interested in finding out more, &lt;a href="https://www.infoq.com/articles/culture-distributed-team/"&gt;Managing Cultural Differences in Your Distributed Team&lt;/a&gt; is a good read.&lt;/p&gt;
&lt;h2&gt;
  
  
  Experience their culture in person whenever you can, aka invest in airfare
&lt;/h2&gt;

&lt;p&gt;There is something unique in meeting someone in person and breaking that electronic barrier.&lt;/p&gt;

&lt;p&gt;Interactions that happen when working in the same office are impossible to reproduce when teams are distributed, so you should try to get all your teams together as often as possible, not only to talk about work, but (mainly) to have fun and get to know each other: common experiences are the building block of trust and the return you get from it far outweighs the airfare to get everyone in the same place (well, maybe not for big companies).&lt;/p&gt;

&lt;p&gt;The simple act of tapping someone on the shoulder &lt;a href="https://www.healthline.com/health/hugging-benefits"&gt;releases oxytocin&lt;/a&gt; and improve a person's feelings (reduced stress, increased happiness, improved communication).&lt;/p&gt;

&lt;p&gt;Make sure to budget for travel and you'll experience increased productivity from day one.&lt;/p&gt;
&lt;h2&gt;
  
  
  It's not all about work
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href="https://www.linkedin.com/in/hugoraymond/"&gt;Hugo Raymond&lt;/a&gt; for the help on this paragraph.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Think about all the micro-interactions you have on a day-to-day basis that make where you work an enjoyable place to spend the best part of your day: how do you replicate these when working with distributed teams?&lt;/p&gt;

&lt;p&gt;The first, obvious answer is to try and spend time together, in person, but this is seldom achievable for companies with multiple teams.&lt;/p&gt;

&lt;p&gt;Another way, that can work every day and build lasting rapports is to use your communication tool (Slack, Teams, whatever) and create a safe place that everyone can access: create a "Fun" channel and let people create sub-channels with things that interest them. It could be a book club, where every week people from around the globe share the book they're reading, review previous ones and give suggestions to other people. It could be a photography channel where photos are shared and commented, the latest gears discussed, tips are given. There could be weekly or monthly assignments like "Still life" or "Autumn leaves" where people from around all the offices share their pics: a wonderful way to show the diversity and beauty of different countries.&lt;/p&gt;

&lt;p&gt;To some this may seem like "organised fun" but you only need a few passionate champions for those who are interested in the social part, to engage, for it to then become a success. &lt;/p&gt;
&lt;h2&gt;
  
  
  If you read until here, may as well watch this!
&lt;/h2&gt;

&lt;p&gt;Jilanna Wilson keeps the love light burning for a team that is spread across 5 continents and 8 time zones and shares some of her knowledge in this video from the DesignOps Summit 2019:&lt;/p&gt;

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

&lt;p&gt;Good luck, and ❤️ your remote teams, they're good for you!&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/agile/teams/remote-teams"&gt;https://www.atlassian.com/agile/teams/remote-teams&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://djangostars.com/blog/how-to-manage-a-software-development-team-across-time-zones/"&gt;https://djangostars.com/blog/how-to-manage-a-software-development-team-across-time-zones/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pdfs.semanticscholar.org/e3b9/57e8c1f6a286ce3b8876c12701a073a8f0c5.pdf"&gt;https://pdfs.semanticscholar.org/e3b9/57e8c1f6a286ce3b8876c12701a073a8f0c5.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.452.8295&amp;amp;rep=rep1&amp;amp;type=pdf#page=239"&gt;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.452.8295&amp;amp;rep=rep1&amp;amp;type=pdf#page=239&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onlinelibrary.wiley.com/doi/epdf/10.1002/j.1681-4835.2002.tb00040.x"&gt;https://onlinelibrary.wiley.com/doi/epdf/10.1002/j.1681-4835.2002.tb00040.x&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ineer.org/Events/ICEE2004/Proceedings/Papers/430_ICEE_2004_final_(1).pdf"&gt;http://www.ineer.org/Events/ICEE2004/Proceedings/Papers/430_ICEE_2004_final_(1).pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://www.onefiniteloop.io/embrace-distributed-teams-and-be-happy/"&gt;onefiniteloop.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>agile</category>
      <category>leadership</category>
      <category>management</category>
    </item>
  </channel>
</rss>
