<?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: David Leuliette 🤖</title>
    <description>The latest articles on Forem by David Leuliette 🤖 (@flexbox).</description>
    <link>https://forem.com/flexbox</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%2F144932%2Fe84d6afd-5db2-4c80-9543-4114ed90077e.jpg</url>
      <title>Forem: David Leuliette 🤖</title>
      <link>https://forem.com/flexbox</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/flexbox"/>
    <language>en</language>
    <item>
      <title>5 simple steps to use pricmic.io with Nx and Next.js</title>
      <dc:creator>David Leuliette 🤖</dc:creator>
      <pubDate>Thu, 13 Oct 2022 20:10:14 +0000</pubDate>
      <link>https://forem.com/flexbox/5-simple-steps-to-use-pricmicio-with-nx-and-nextjs-1jki</link>
      <guid>https://forem.com/flexbox/5-simple-steps-to-use-pricmicio-with-nx-and-nextjs-1jki</guid>
      <description>&lt;p&gt;For my &lt;a href="https://weshipit.today/"&gt;brand new website&lt;/a&gt; I wanted to use prismic as I do on my &lt;a href="https://davidl.fr/blog"&gt;personal website&lt;/a&gt;. Both are Next.js project, the prismic documentation is pretty neat, so what could go wrong?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NtJZc22Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Anjsn4MFA_XzM4wbMCKWw5Q.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NtJZc22Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Anjsn4MFA_XzM4wbMCKWw5Q.jpeg" alt="" width="880" height="586"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A rare picture of a monorepo by @clembazard on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt; I am using Nx — &lt;em&gt;an awesome tool for handling monorepo complexity&lt;/em&gt; — and the folders architecture is not really what expect the new slicemachine feature from prismic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# What I have

./apps/weshipit/next-*.files
./node_modules/
./package.json

# What slicemachine want

./next-*.files
./node_modules/
./package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are 5 simple steps to solve this problem.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create manually the types on Prismic
&lt;/h4&gt;

&lt;p&gt;As I said using slicemachine is tricky in a monorepo. I am not the only one who &lt;a href="https://community.prismic.io/t/slicemachine-in-monorepo/10579"&gt;is struggling with that&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If I use npm run slicemachine —after the setup— at the root level. I encountered issues.&lt;/p&gt;

&lt;p&gt;If I use npm run slicemachine —after the setup— at project level. I encountered issues.&lt;/p&gt;

&lt;p&gt;So I decided to…&lt;/p&gt;

&lt;p&gt;🥁&lt;/p&gt;

&lt;p&gt;Create new repository with “another framework” — because slicemachine does not plays well with Nx architecture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VktSjBrQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2A33fqAPnLyn0bch4rPErPnw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VktSjBrQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2A33fqAPnLyn0bch4rPErPnw.png" alt="add a framework on prismic.io" width="880" height="220"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;add a framework on prismic.io&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And choose plain React.&lt;/p&gt;

&lt;p&gt;Don’t panic we are going to use SRR feature from Next.js later in this article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sXXvHFAo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AOktrUiIGX1C6n1gGp-FSIA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sXXvHFAo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AOktrUiIGX1C6n1gGp-FSIA.png" alt="Select React.js" width="880" height="273"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Select React.js&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Finally, manually create your new type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oZVmNmef--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2ANUU_1H0kOQHBEZ1vD6rLKw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oZVmNmef--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2ANUU_1H0kOQHBEZ1vD6rLKw.png" alt="" width="880" height="716"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Install Prismic to your Nx monorepo
&lt;/h4&gt;

&lt;p&gt;Run this command in your terminal to install the Prismic React integration and client library&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @prismicio/react @prismicio/client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create your API client&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ./apps/weshipit/pages/api/prismic.ts

import * as prismic from '@prismicio/client';

// Fill in your repository name
export const repositoryName = 'weshipit';

export const client = prismic.createClient(repositoryName, {
  routes: [
    {
      type: 'client',
      path: '/',
    },
  ],
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We want to have the PrismicProvider component available in our entire project by updating _app.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ./apps/weshipit/pages/_app.tsx 

import { AppProps } from 'next/app';
import Head from 'next/head';

import { PrismicProvider } from '@prismicio/react';
import { client } from '../prismic';

function CustomApp({ Component, pageProps }: AppProps) {
  return (
    &amp;lt;PrismicProvider client={client}&amp;gt; &amp;lt;------- add this
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;weshipit.today — React Native Experts&amp;lt;/title&amp;gt;
      &amp;lt;/Head&amp;gt;
      &amp;lt;main&amp;gt;
        &amp;lt;Component {...pageProps} /&amp;gt;
      &amp;lt;/main&amp;gt;
    &amp;lt;/PrismicProvider&amp;gt;
  );
}

export default CustomApp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create a local /api
&lt;/h4&gt;

&lt;p&gt;Following Next.js the documentation&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Any file inside the folder pages/api is mapped to /api/ and will be treated as an API endpoint instead of a page.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s what I created to get my data to render the list of my clients.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// apps/weshipit/pages/api/client.ts

import { client as prismicClient } from './prismic';

export async function getAllClients() {
  try {
    const clients = await prismicClient.getAllByType('client');

    return {
      clients: clients ? clients : [],
    };
  } catch (error) {
    console.error('getAllClients -&amp;gt; error', error);
    return error;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  getInitialProps and render data to your page
&lt;/h4&gt;

&lt;p&gt;I can pull the data to render &lt;a href="https://weshipit.today/clients"&gt;my clients page&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;// apps/weshipit/pages/clients.ts

export default function ClientsPage({ clients }: clientsPageProps) {
  return (
    &amp;lt;div&amp;gt;
      {clients.map((client) =&amp;gt; (
        &amp;lt;div key={client.id}&amp;gt;
          &amp;lt;Text&amp;gt;{client.data.name}&amp;lt;/Text&amp;gt;
        &amp;lt;/div&amp;gt;
      ))}
    &amp;lt;/div&amp;gt;
  );
}

ClientsPage.getInitialProps = async function () {
  const clients = await getAllClients();
  return clients;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Release to prod
&lt;/h4&gt;

&lt;p&gt;The last step is releasing to production. Using vercel on the project settings page you will need to override build settings.&lt;/p&gt;

&lt;p&gt;Build command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx nx build weshipit --prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dist/apps/weshipit/.next
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zpYmHCk5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AwsPM0srbvqBpbNj940tEFg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zpYmHCk5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AwsPM0srbvqBpbNj940tEFg.png" alt="" width="880" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not perfect, but it’s working and &lt;a href="https://weshipit.today/"&gt;weshipit.today&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vercel</category>
      <category>react</category>
      <category>development</category>
      <category>technology</category>
    </item>
    <item>
      <title>Spotify Mixtapes For Coding</title>
      <dc:creator>David Leuliette 🤖</dc:creator>
      <pubDate>Sun, 25 Apr 2021 13:14:58 +0000</pubDate>
      <link>https://forem.com/flexbox/spotify-mixtapes-for-coding-4p5b</link>
      <guid>https://forem.com/flexbox/spotify-mixtapes-for-coding-4p5b</guid>
      <description>&lt;h2&gt;
  
  
  Curated mixtapes
&lt;/h2&gt;

&lt;p&gt;Last year, I published my &lt;a href="https://dev.to/flexbox/how-to-get-4000-followers-on-spotify-2kla"&gt;growth hack technique&lt;/a&gt; to get some followers on Spotify.&lt;/p&gt;

&lt;p&gt;I reached 12 playlists and I hope it will help some of you to get "into the zone" and release amazing products to production!&lt;/p&gt;

&lt;h2&gt;
  
  
   The List
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/0Jt2JW0NTIL6MvV9dSOnqZ?si=2f09e2def13f4704"&gt;HACKER #1: Mixtape for coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/3LdxHInEvlJZqtqeRmtiGv?si=8accab0a704941c6"&gt;HACKER #2: Rock for coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/59h0570gNwpTrqiD4KFt9c?si=1a0b2eaf51154914"&gt;HACKER #2.11: Aggressive mixtape for programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/0pf103tVqmwkF060LHk0RG?si=218d1fbed3dd4292"&gt;HACKER #3.0: Movies Mixtape for coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/6IZ1Mh2grWaxgdQnK9xIAO?si=285875d545294822"&gt;HACKER #3.1: OST Mixtape for coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/301Kl8b7hslXbV8wxk3SrV?si=dc78f2f4ea8544c5"&gt;HACKER #3.2: Gaming Mixtape for coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/6Zmw201xJGrD7LuGwF2Ph0?si=5a019dd3d1e04cb8"&gt;HACKER #4: Electro Mixtape for coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/2Adv3s73yJNLm3z1BwK9rP?si=0837002aac384e46"&gt;HACKER #5: Chill Mixtape for coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/26yEmL1emKzN9Xpt1dyhPm?si=09aaee200ded4f3d"&gt;HACKER #6: Mixtape for laser-focus at work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/3FYezFABeZdD13RMQiff0G?si=88d85f4cda414ebc"&gt;HACKER #7: Summer of code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/5PDDbk2cvJiiqBT37iHs9S?si=0eb0d79dfafb468f"&gt;HACKER #8: Retro Mixtape for Coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/5rR8hKi3BWEx3rnHPD7M72?si=d1066285f44049a2"&gt;HACKER #9: DJ Mixtape for Coders&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/0yuappB07Oz6xj0xBhH2Y3?si=53e53272732f4ca9"&gt;HACKER #10: Stress free Mixtape for programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/1iQK1OHiOgpF2DlOaz0Xow?si=6b1f5a9a371b4cf8"&gt;HACKER #11: HipHop Coders Krew&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/playlist/6D6P1XCXeuyOlKPPSObfLG?si=418cf5e342944d7e"&gt;HACKER #12: Discovered from an apple watch —the mixtape&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;👉 Discover all my curated &lt;a href="https://davidl.fr/music"&gt;playlists for programming&lt;/a&gt;&lt;/p&gt;

</description>
      <category>music</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Supporting Huawei store for Android application</title>
      <dc:creator>David Leuliette 🤖</dc:creator>
      <pubDate>Thu, 15 Oct 2020 16:15:37 +0000</pubDate>
      <link>https://forem.com/flexbox/supporting-huawei-store-for-android-application-3mo</link>
      <guid>https://forem.com/flexbox/supporting-huawei-store-for-android-application-3mo</guid>
      <description>&lt;p&gt;I am a Freelance React Native developer, I noticed a weird bug on the phone of my client —a Huawei P30— the app seams not getting the updates from the Google Play Store 🤔&lt;/p&gt;

&lt;p&gt;Apparently you can open a developer account on &lt;a href="https://developer.huawei.com/"&gt;https://developer.huawei.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Supporting 2 stores (Google Play and Apple Store) is already a big task in terms of bugs and deployment infrastructure.&lt;/p&gt;

&lt;p&gt;I am just looking for some inputs from the community about this, &lt;strong&gt;as a mobile developer would you support third part stores&lt;/strong&gt; ?&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;And in the near future probably the Epic store and the others&lt;/em&gt;)&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>reactnative</category>
      <category>android</category>
    </item>
    <item>
      <title>How to get 4000+ followers on Spotify</title>
      <dc:creator>David Leuliette 🤖</dc:creator>
      <pubDate>Mon, 27 Apr 2020 08:29:49 +0000</pubDate>
      <link>https://forem.com/flexbox/how-to-get-4000-followers-on-spotify-2kla</link>
      <guid>https://forem.com/flexbox/how-to-get-4000-followers-on-spotify-2kla</guid>
      <description>&lt;p&gt;If you know me personally, you may have noticed that I have a passion for music. I am always keen on going to music festivals to see live gigs.&lt;/p&gt;

&lt;p&gt;That’s why I am a paid Spotify user since day one.&lt;/p&gt;

&lt;p&gt;When I am working, I am always listening to some music for getting in the zone.&lt;/p&gt;

&lt;p&gt;I started to create some playlist for focusing on my work during my coding sessions. During the process, I followed a growth strategy.&lt;/p&gt;

&lt;p&gt;Nowadays, I am contacted by artists themselves to add some music, &lt;a href="https://davidl.fr/featured"&gt;was interview&lt;/a&gt; on specialized websites and even getting paid to promote artists on my playlists.&lt;/p&gt;

&lt;h2&gt;
  
  
  SEO growth hack on Spotify
&lt;/h2&gt;

&lt;p&gt;First of all, I choose a keyword:  &lt;strong&gt;Mixtape&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Second keyword:  &lt;strong&gt;coding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;when you hit 50 sounds, create a new playlist by adding a new keyword.&lt;/p&gt;

&lt;p&gt;On my case I have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mixtape for coding&lt;/li&gt;
&lt;li&gt;Rock Mixtape for coding&lt;/li&gt;
&lt;li&gt;Movies Mixtape for coding&lt;/li&gt;
&lt;li&gt;Electro Mixtape for coding&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple right?&lt;/p&gt;

&lt;p&gt;All my playlists are available on my website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://davidl.fr/music"&gt;Curated music for focused work&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Design template for your playlists
&lt;/h2&gt;

&lt;p&gt;Famous Youtubers spend hours to create the thumbnails of their videos.&lt;/p&gt;

&lt;p&gt;In my case, I used Figma with nice colored gradients.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lbCt7fgU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AuzNwtUQB31GOc7nezIMdmw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lbCt7fgU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AuzNwtUQB31GOc7nezIMdmw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the Figma Template. If you want to use it, feel free to duplicate&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.figma.com/community/file/831886749337476100/Spotify-Playlists-Template"&gt;Figma - Spotify Playlists Template&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;That’s it for today.&lt;br&gt;&lt;br&gt;
Don’t forget to send me your playlists, I am always looking for new sounds.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>growthhacking</category>
      <category>music</category>
      <category>growth</category>
    </item>
    <item>
      <title>How to build DIY ergonomic desk for less than 99€</title>
      <dc:creator>David Leuliette 🤖</dc:creator>
      <pubDate>Sun, 05 Jan 2020 14:16:45 +0000</pubDate>
      <link>https://forem.com/flexbox/how-to-build-diy-ergonomic-desk-for-less-than-99-1p43</link>
      <guid>https://forem.com/flexbox/how-to-build-diy-ergonomic-desk-for-less-than-99-1p43</guid>
      <description>&lt;h1&gt;
  
  
  Improve productivity and health.
&lt;/h1&gt;

&lt;p&gt;As a freelance React Native developer, My weekly routine is working 4 days per week for a client based in London, and one day per week — on-site — in for a French client. Since I am &lt;strong&gt;working remotely mostly from home&lt;/strong&gt; , I needed to have a decent office.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can design your perfect productive environment&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I had 2 constraints: &lt;em&gt;budget&lt;/em&gt; and &lt;em&gt;space&lt;/em&gt;. There is tons of &lt;a href="https://www.opendesk.cc/"&gt;affordable desk available&lt;/a&gt; on the internet but they are not working on my case because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I am super tall &lt;em&gt;(1m98)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;I just moved back to France into my girlfriend’s flat and I don’t have a dedicated room to work.&lt;/li&gt;
&lt;li&gt;I need to fix my desk on one wall.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: Collect materials
&lt;/h2&gt;

&lt;p&gt;If you want to make your own DIY desk, just start by taking the measurement for the woods boards. In my case, &lt;strong&gt;space is a big requirement&lt;/strong&gt; , so I choose to have only one big metal adjustable foot. I &lt;a href="https://www.ikea.com/fr/fr/p/gerton-pied-reglable-chrome-60261626/"&gt;found the GERTON one on IKEA&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I cheated a little bit at this point, because my parents are living in the countryside. They helped me with the painting and cutting the wood boards. And they have all the tools whereas in my flat in the city I don’t have a garage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Iyrzy2ZO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2Ak8vAcF_rid0t3BKF12MSmQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Iyrzy2ZO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2Ak8vAcF_rid0t3BKF12MSmQ.jpeg" alt="Painting in progress"&gt;&lt;/a&gt;Painting in progress&lt;/p&gt;

&lt;p&gt;As a design Engineer, I didn’t forget to add an Apple-style curve to one of the edges. Back home, I had everything ready to fix on the wall.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hgf-mgbM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2ArZrGdCkxf3rvoqQLqqpdBQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hgf-mgbM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2ArZrGdCkxf3rvoqQLqqpdBQ.png" alt="Need to find the prefect wall for this"&gt;&lt;/a&gt;Need to find the prefect wall for this&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Recap:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 wood boards&lt;/li&gt;
&lt;li&gt;2 wood rails&lt;/li&gt;
&lt;li&gt;2 metal&lt;/li&gt;
&lt;li&gt;8 ankles for plaster&lt;/li&gt;
&lt;li&gt;1 adjustable metal foot&lt;/li&gt;
&lt;li&gt;(optional) White painting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All theses materials should cost less than 99€, my biggest expense was the ajustable metal foot 39€.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Ergonomic metrics
&lt;/h2&gt;

&lt;p&gt;Do you know there are rules for ergonomics desks? I worked for ages in different companies in an open space where &lt;strong&gt;these rules are simply ignored&lt;/strong&gt;. I understand that at scale, people in charge of furniture are using excels spreadsheets to calculate budgets. And they often choose the less expensive solution who’s going to work for most of the people.&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://www.blitzresults.com/en/ergonomic/"&gt;this ergonomic calculator&lt;/a&gt; website, with a height of 198cm, my desk should be 80cm high, and my chair should be 53cm high (distance from the floor to seat).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Desk height: 80cm&lt;/li&gt;
&lt;li&gt;Height of chair: 53cm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zj8haKdg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AUafCpy1wkhYFJg_Ni228Ew.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zj8haKdg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AUafCpy1wkhYFJg_Ni228Ew.jpeg" alt="Just found the perfect wall"&gt;&lt;/a&gt;Just found the perfect wall&lt;/p&gt;

&lt;p&gt;After fixing the ankles and the 2 wood rails you are ready for the last step: fixing the adjustable foot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B9kZmcWh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2Aq1VcCBiCorYryEhI9SwI-g.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B9kZmcWh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2Aq1VcCBiCorYryEhI9SwI-g.jpeg" alt="Et voila"&gt;&lt;/a&gt;Et voila&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Pro-tip *&lt;/em&gt; : Don’t forget to cut one edge for the cables when you have all the tools available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8n02VSX9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AOEwabGk6-Ud5xXZypuvO1g.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8n02VSX9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AOEwabGk6-Ud5xXZypuvO1g.jpeg" alt="Always have a swiss army knife at home"&gt;&lt;/a&gt;Always have a swiss army knife at home&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Add a Giant Screen &lt;em&gt;(not included in the price)&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;You are now ready to work, just add a giant screen, a timer and some cables.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z1ORWBh_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AR2zRuZ9bzfOt4MUZXQaUsA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z1ORWBh_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AR2zRuZ9bzfOt4MUZXQaUsA.jpeg" alt=""&gt;&lt;/a&gt;32 inches screen fits almost perfectly&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus Step: Find the perfect chair
&lt;/h2&gt;

&lt;p&gt;This article is for people who don’t want to spend a lot of money &lt;strong&gt;BUT&lt;/strong&gt; you need a decent chair because you are going to spend a lot of time in front of your screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C5ttjqZM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2Ard8LEl3i_MG6alyLbaVO2w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C5ttjqZM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2Ard8LEl3i_MG6alyLbaVO2w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I spend some time searching for chairs on eBay and &lt;a href="https://www.ebay.fr/itm/Chaise-de-bureau-sport-fauteuil-gamer-ergonomique-simili-cuir-F1/223535070897"&gt;I found the perfect one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It cost me 120 €&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the things I like being a freelance working remote is that you can design your perfect productive environment.&lt;/p&gt;

&lt;p&gt;For my next office, I will definitely invest in a standing/walking desk if I have space. Working remotely is great because you don’t lose your time on commuting but you are living like a kind of a hermit. Don’t forget to go out for some exercice or even better go to the gym.&lt;/p&gt;

&lt;p&gt;Your health is more important than your job.&lt;/p&gt;

</description>
      <category>freelancing</category>
      <category>life</category>
      <category>productivity</category>
      <category>remoteworking</category>
    </item>
    <item>
      <title>What I learned at React Finland Workshop with Nik Graf</title>
      <dc:creator>David Leuliette 🤖</dc:creator>
      <pubDate>Wed, 08 May 2019 09:50:01 +0000</pubDate>
      <link>https://forem.com/flexbox/what-i-learned-at-react-finland-workshop-with-nik-graf-30oe</link>
      <guid>https://forem.com/flexbox/what-i-learned-at-react-finland-workshop-with-nik-graf-30oe</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hdk8atTu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AbT6jmte7_xz_IjPnTeTWmg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hdk8atTu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AbT6jmte7_xz_IjPnTeTWmg.jpeg" alt=""&gt;&lt;/a&gt;Is that a hook we are looking at? (&lt;a href="http://nicktulinen.com"&gt;Nick Tulinen&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Advanced React — Suspense, Time Slicing, Hooks, and more&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you are not yet familiar with &lt;a href="https://react-finland.fi"&gt;React Finland&lt;/a&gt;, you should. Let me tell why: It’s like a summer camp. Each year, you can see familiar faces who are really excited to share their knowledge with the community. I like the format: one workshop day and two days of conference on a single track.&lt;/p&gt;

&lt;p&gt;In this article, I am going to cover the workshop of Nik Graf: &lt;strong&gt;Advanced React with all the new buzzwords&lt;/strong&gt;!&lt;/p&gt;

&lt;h4&gt;
  
  
  React — Reinvented
&lt;/h4&gt;

&lt;p&gt;In the last months, React has changed a lot with some new features (not all are in a public release yet):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New lifecycle methods&lt;/li&gt;
&lt;li&gt;Suspense and Time Slicing — Upcoming feature&lt;/li&gt;
&lt;li&gt;Hooks&lt;/li&gt;
&lt;li&gt;And more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this context, &lt;a href="https://medium.com/u/ff3f225e7f5c"&gt;Nik Graf&lt;/a&gt; ran a workshop for intermediate and experienced React developers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All the materials can be downloaded on the &lt;a href="https://github.com/nikgraf/2019-react-finland-workshop"&gt;GitHub repo 2019-react-finland-workshop&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ls9IX6-E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AuSjSv-_UCTWkJfK64_UZbw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ls9IX6-E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AuSjSv-_UCTWkJfK64_UZbw.jpeg" alt=""&gt;&lt;/a&gt;Sketchnote with React Hooks and Performance in React (&lt;a href="https://davidl.fr"&gt;David Leuliette&lt;/a&gt;)&lt;/p&gt;

&lt;h4&gt;
  
  
  React Hooks
&lt;/h4&gt;

&lt;p&gt;Hooks are everywhere. Since React 16.8 was released, it’s a hot topic in the react community. Things like &lt;em&gt;class component&lt;/em&gt; and &lt;em&gt;functional component&lt;/em&gt; are a thing from the past, long live &lt;strong&gt;function based components&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There are literally &lt;a href="https://www.youtube.com/watch?v=G-aO5hzo1aw"&gt;millions on content available&lt;/a&gt; on the internet to introduce react hooks but during this day &lt;a href="https://github.com/flexbox/2019-react-finland-workshop/commit/543a040c37c1a97171fa3f8ddea8e93b86b1d087"&gt;this is what I learned&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;useEffect can have 2 arguments. The first one is a function that contains imperative. The second can take an array of values that the effect depends on.&lt;/li&gt;
&lt;li&gt;You can create &lt;a href="https://github.com/flexbox/2019-react-finland-workshop/commit/fc0df85d734a37d618f53696254e1e9956076b1f"&gt;custom hooks to share code&lt;/a&gt;, but try to follow a convention like useMyhook to be explicit.&lt;/li&gt;
&lt;li&gt;useLayoutEffect for synchronous operations, but use it with caution because it’s blocking rendering and expensive operations can lead to a bad experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nZNgpPe2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/445/1%2AaUegfx5bsqZic-JOFFrvwQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nZNgpPe2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/445/1%2AaUegfx5bsqZic-JOFFrvwQ.gif" alt=""&gt;&lt;/a&gt;&lt;em&gt;useLayoutEffect is perfect for auto-height textarea&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Pro tip:&lt;/strong&gt; Don’t put hooks in loops or if…else. To avoid mistakes there is &lt;a href="https://www.npmjs.com/package/eslint-plugin-react-hooks"&gt;eslint-plugin-react-hooks&lt;/a&gt; for that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want to dig on custom hooks &lt;a href="https://medium.com/u/ff3f225e7f5c"&gt;Nik Graf&lt;/a&gt; built this cool website to collect all of them:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nikgraf.github.io/react-hooks/"&gt;Collection of React Hooks&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Performance
&lt;/h4&gt;

&lt;p&gt;As in video games, we want a slick experience with 60 frames per seconds and 15 ms delay. When I am writing this article the react-devtool profiler is not the best for that. The Google Chrome profiler (&lt;em&gt;console&lt;/em&gt; &amp;gt; &lt;em&gt;performance&lt;/em&gt;) is better in this scenario.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e0mmiOZz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AL41HwaDJC1yDSZoXdlaY4A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e0mmiOZz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AL41HwaDJC1yDSZoXdlaY4A.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, we found our performance enemy: the function sometimesSlowCalculation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Pro tip:&lt;/strong&gt; When you start to dig on performance start your journey by measuring what you are doing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--78Eri7rN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AN_98xbNXO-iuzWJLGiv8uw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--78Eri7rN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2AN_98xbNXO-iuzWJLGiv8uw.jpeg" alt=""&gt;&lt;/a&gt;Sketchnote with Time Slicing, Suspense, and Context&lt;/p&gt;

&lt;h4&gt;
  
  
  Async React
&lt;/h4&gt;

&lt;p&gt;In the second part of the workshop, we played with some unstable API. If you want to follow this path, repeat after me 3 times the next sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I will not use time slicing in production&lt;br&gt;&lt;br&gt;
— First rule of the React Club&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Time Slicing
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oHuu9OMV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2A08fYfKRwrGCUutnuDfY_rg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oHuu9OMV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2A08fYfKRwrGCUutnuDfY_rg.png" alt=""&gt;&lt;/a&gt;Awesome react markdown preview application&lt;/p&gt;

&lt;p&gt;Imagine you need to create a CMS application. 2 column layout and you want a nice writing experience with real-time feedback for the user.&lt;/p&gt;

&lt;p&gt;On the left, you can edit markdown content and on the right, we have the preview in real time. For the  we need to have a fast experience. On the other hand, we can delay the preview because it’s gonna be slow with huge content.&lt;/p&gt;

&lt;p&gt;First, we need to create a new function &lt;strong&gt;deferredPreviewUpdate&lt;/strong&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;TextArea
  value={text}
  onChange={value =&amp;gt; {
    setText(value);
**deferredPreviewUpdate(value);**
  }}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling the function with unstable_LowPriority allows the rendering part to have a small delay. Just remember, this code is experimental for now, but it was a great introduction to the concept of time slicing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function deferredPreviewUpdate(text) {
  **unstable\_runWithPriority(unstable\_LowPriority, function() {**
    **unstable\_scheduleCallback(unstable\_LowPriority, function() {**
      const content = markdownToReact(text);
      setPreview(content);
    **});  
  });**  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the full example in part &lt;a href="https://github.com/nikgraf/2019-react-finland-workshop/blob/master/5-time-slicing/solution/src/App.js"&gt;5-time-slicing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to dig more on how scheduling in User Interfaces, I recommend this article by &lt;a href="https://medium.com/u/7b3a1e6bc118"&gt;Philipp Spiess&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://philippspiess.com/scheduling-in-react/"&gt;Scheduling in React&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  React.lazy and React.Suspense
&lt;/h4&gt;

&lt;p&gt;The Suspense API allows components to “wait” for something before rendering. When I am writing this article Suspense works only with one scenario: &lt;a href="https://reactjs.org/docs/code-splitting.html#reactlazy"&gt;loading components dynamically with&lt;/a&gt;&lt;a href="https://reactjs.org/docs/code-splitting.html#reactlazy"&gt;React.lazy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In the future, Suspense will support other use cases like data fetching.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On this exercise, I used react-apollo-hooks and it looks promising. Instead of using this classic loading state to display the loading like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (loading) {
  return &amp;lt;div&amp;gt;Loading …&amp;lt;/div&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can 2 things. First, add another param to you GraphQL query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { data, error } = useQuery(profileQuery **, { suspend: true }** );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second, add a fallback loading component:&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;React.Suspense **fallback={&amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;}** &amp;gt;
  &amp;lt;Profile /&amp;gt;
&amp;lt;/React.Suspense&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can check the diff on the exercise on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/flexbox/2019-react-finland-workshop/commit/63ddbbc084a97cf689afd6a684c486a0cb8152ea"&gt;Add Suspense · flexbox/2019-react-finland-workshop@63ddbbc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cy_n-T_4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/295/1%2A-ptecCNTf4gZBrKqD3pQLQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cy_n-T_4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/295/1%2A-ptecCNTf4gZBrKqD3pQLQ.gif" alt=""&gt;&lt;/a&gt;Cascading loading experience&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Pro tip:&lt;/strong&gt; This feature is not yet available for server-side rendering.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Code Splitting
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Code splitting your app can help you “lazy-load” just the things that are currently needed by the user, which can dramatically improve the performance of your app.&lt;br&gt;&lt;br&gt;
— extracted from&lt;/em&gt; &lt;a href="https://reactjs.org/docs/code-splitting.html"&gt;https://reactjs.org/docs/code-splitting.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this exercise, we used the code splitting feature to reduce the size of the bundle of our app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YVAC1VzM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2Aw6CsWeO_HD2fagH-AVVUng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YVAC1VzM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/proxy/1%2Aw6CsWeO_HD2fagH-AVVUng.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Pro tip:&lt;/strong&gt; You don’t need to code split everything. Sometimes a single HTTP request with one big file is enough.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Context
&lt;/h4&gt;

&lt;p&gt;The context API can be used as your global store, aka you don’t need Redux for everything. That said use best to learn the pros and cons before jumping ship.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://youtu.be/c9YtmMi-5rM?t=450"&gt;Check what Nik is saying about it at React Finland.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Take the example of a profile page. For a currently authenticated user, the avatar is not often updated. It’s a perfect use case for using context because it solves the classic problem of props trilling.&lt;/p&gt;

&lt;p&gt;In the context exercise, we worked on theming React applications. First, you need to create a context like &lt;strong&gt;ThemeContext&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//ThemeContext.js

import React, { **createContext** } from "react";

export const themes = {
  dark: {
    foreground: "#fff",
    background: "#666"
  },
  light: {
    foreground: "#222",
    background: "#eee"
  }
};

**const ThemeContext = createContext({**
  theme: themes.dark,
  toggleTheme: () =&amp;gt; {}
**});**

export default ThemeContext;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, in this example, we are using hooks to use the context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Toolbar.js

import React, { **useContext** } from "react";
import Button from "./Button";
import ThemeContext from "./ThemeContext";

function Toolbar() {
  **const { toggleTheme } = useContext(ThemeContext);**

return (
    &amp;lt;&amp;gt;
      &amp;lt;Button onClick={ **toggleTheme** }&amp;gt;Toggle Theme&amp;lt;/Button&amp;gt;
    &amp;lt;/&amp;gt;
  );
}
export default Toolbar;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Pro tip:&lt;/strong&gt; Remember that when using &lt;strong&gt;useContext&lt;/strong&gt; , every change in the context store will trigger a re-render of all the components where it’s used.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x_XrORgR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AgrO0wWbtWOBhaVtxyI3pCA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x_XrORgR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AgrO0wWbtWOBhaVtxyI3pCA.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I really enjoyed all the different exercises. It was a great workshop and now I am more confident with the usage of Hooks in React.&lt;/p&gt;

&lt;p&gt;As a recap, here is the list of the exercises:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;useEffect&lt;/strong&gt; and &lt;strong&gt;useRef&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;custom hooks and &lt;strong&gt;useDebugValue&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;useLayoutEffect&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Performance
&lt;/li&gt;
&lt;li&gt;Time slicing
&lt;/li&gt;
&lt;li&gt;Suspense
&lt;/li&gt;
&lt;li&gt;Code splitting
&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can clone the repo &lt;a href="https://github.com/nikgraf/2019-react-finland-workshop"&gt;https://github.com/nikgraf/2019-react-finland-workshop&lt;/a&gt; to do your homework. 🙂&lt;/p&gt;

&lt;p&gt;If you are interested to level up your knowledge in the React ecosystem, &lt;a href="https://react-finland.fi"&gt;subscribe to the newsletter to receive pre-sales early-bird access for the next edition&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👋 See you next year!&lt;/p&gt;
&lt;/blockquote&gt;




</description>
      <category>workshop</category>
      <category>hooks</category>
      <category>react</category>
      <category>native</category>
    </item>
    <item>
      <title>Kondo your Mac</title>
      <dc:creator>David Leuliette 🤖</dc:creator>
      <pubDate>Tue, 26 Feb 2019 00:30:05 +0000</pubDate>
      <link>https://forem.com/flexbox/kondo-your-mac-41dp</link>
      <guid>https://forem.com/flexbox/kondo-your-mac-41dp</guid>
      <description>&lt;h4&gt;
  
  
  How to setup a distraction free macOS to focus on shipping code
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kfRqPw-l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A4k5ibuLtmD_KWTpLBKoPPw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kfRqPw-l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A4k5ibuLtmD_KWTpLBKoPPw.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last week, I was chilling on Netflix and I found one famous TV Show with Marie Kondo. She’s a Japanese organising consultant and author. Organising… Consultant… Wow! We are really living in exciting times…&lt;/p&gt;

&lt;p&gt;And then I found this great article by &lt;a href="https://medium.com/u/d7ca111e7984"&gt;Rubens Cantuni&lt;/a&gt; &lt;a href="https://uxdesign.cc/marie-kondo-your-sketch-files-with-these-plugins-bcbe9321ea8e"&gt;about organizing your sketch files&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
I got hoocked.&lt;/p&gt;

&lt;p&gt;Before opening &lt;a href="https://konmari.com/pages/consultants"&gt;my own agency of cleaning consultant&lt;/a&gt;, I decided to share with you my best hacks to tidy your Mac and transform your developer life.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your real life begins after putting your house in order.&lt;br&gt;&lt;br&gt;
– Marie Kondo&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Spark joy in your terminal
&lt;/h3&gt;

&lt;p&gt;As a developer, I spend around 1h / day in the terminal. That’s literally my remote control for everything. My awesome and well-organized naming framework for my coding projects is this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/workspace/\&amp;lt;CLIENT\&amp;gt;/\&amp;lt;PROJECT\_NAME\&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am using iTerm2 to split, and navigate across projects and files. And if you are using the script &lt;a href="https://github.com/rupa/z"&gt;z — jump around&lt;/a&gt;, you are literally 125% more effective than people using the keyboard + mouse combo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6QxiPRQy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A3Eem2GiSeJtsffTgItZypA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6QxiPRQy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A3Eem2GiSeJtsffTgItZypA.png" alt=""&gt;&lt;/a&gt;refined theme for iTerm2&lt;/p&gt;

&lt;p&gt;I have plenty of shortcuts thanks to &lt;strong&gt;oh-my-zsh&lt;/strong&gt; –with this clean theme called refined– to be super efficient. If I need to &lt;strong&gt;keep only one productivity hack&lt;/strong&gt; , I would definitely choose this: &lt;strong&gt;Launch your editor form the terminal&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Sublime Text
st .

// Atom
atom .

// VSCode
code .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install &lt;a href="https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins/sublime"&gt;sublime plugin for oh-my-zsh&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install &lt;a href="https://flight-manual.atom.io/getting-started/sections/installing-atom/#installing-atom-on-mac"&gt;atom and apm on Mac&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install code &lt;a href="https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line"&gt;command in PATH for VSCode&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Everything has its place in your Finder
&lt;/h3&gt;

&lt;p&gt;Let’s face it, the proportion of mess on your machine is exponential. If you don’t set some rules at the beginning, after 1 month your &lt;a href="https://youtu.be/IUSaZ1EvHeg?t=21"&gt;new shiny computer is full of crap&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/IUSaZ1EvHeg?t=21"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y-4xgO7M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/998/1%2A2Xyx4vrmdjI4x7mE2NBCXg.png" alt=""&gt;&lt;/a&gt;Your computer is infected&lt;/p&gt;

&lt;p&gt;Here is my Shinto Workflow for cleaning and organizing files properly:&lt;/p&gt;

&lt;h4&gt;
  
  
  Add Favourites
&lt;/h4&gt;

&lt;p&gt;Open your terminal and write &lt;code&gt;open .&lt;/code&gt; to open the finder. Remove all the distractions links and add the favourites ones like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bIqRFgoD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/882/1%2AXejnb5rTkb6R6e3jmvNpOA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bIqRFgoD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/882/1%2AXejnb5rTkb6R6e3jmvNpOA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a screenshot folder
&lt;/h4&gt;

&lt;p&gt;By default, all your screenshot are saved on your desktop. I changed that for another folder called… &lt;code&gt;Screenshots&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Save screenshots to the Screenshot (or elsewhere)
defaults write com.apple.screencapture location ${HOME}/Screenshots
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Store vertically
&lt;/h3&gt;

&lt;p&gt;You can’t do 2 things at the same time. So why are you keeping the dock with all the applications available on your Mac? You can launch them with your keyboard thanks to spotlight and the shortcut &lt;code&gt;⌘&lt;/code&gt; + &lt;code&gt;space&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Marie Rondo says storing vertically will save space and allow your belongings to become more eye-catching. Let’s &lt;strong&gt;hide our dock&lt;/strong&gt; when we don’t need it with a left vertical position.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9E5CsM_L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2APOLl8IbLSoSryt89Shd9mw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9E5CsM_L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2APOLl8IbLSoSryt89Shd9mw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Window Organizer
&lt;/h3&gt;

&lt;p&gt;Windows users are going to love this one: you can tilling and organise your applications since a long time with &lt;code&gt;windows&lt;/code&gt; + &lt;code&gt;→&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On macOS we have the fullscreen mode. But it’s not really powerfull, and it’s complicated to assign keyboard shortcuts to be effective.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Eieh31W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/366/1%2AV-eZWobtmXdmtX0SbVuBaQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Eieh31W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/366/1%2AV-eZWobtmXdmtX0SbVuBaQ.png" alt=""&gt;&lt;/a&gt;Split your screen&lt;/p&gt;

&lt;p&gt;I am using Divvy since ages to fix this issue, I can split my screens and I have differents shortcuts for my needs: full screen, half-left, top-right... You can pick-up any windows manager to “Hikidashi” your working days.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mizage.com/divvy/"&gt;Mizage - Divvy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.spectacleapp.com/"&gt;Spectacle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://koekeishiya.github.io/chunkwm/index.html"&gt;$ chunkwm - tiling wm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Clean your menu bar icons
&lt;/h3&gt;

&lt;p&gt;Everything you own needs his own designated space. Dozer is a little application to hide icons on your menu bar. With this hack you can finally get rid of the spotlight icon! The easiest way to install it is with &lt;code&gt;brew&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew cask install dozer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can check on &lt;a href="https://dev.to/scottw/dozer-k1f-temp-slug-6358636"&gt;GitHub the installation notes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lUij0YYB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/565/1%2AxqKaGG6TfWHLfxHzq8_pxQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lUij0YYB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/565/1%2AxqKaGG6TfWHLfxHzq8_pxQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nX4Ni3OG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/571/1%2Ah-FtnbUW9fBWrVe9uru16Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nX4Ni3OG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/571/1%2Ah-FtnbUW9fBWrVe9uru16Q.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Tidy by category&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Yes! I am looking at you modern full stack developer! I know you have the hype and can solve the cancert problem with JavaScript, but in my opinion, &lt;strong&gt;you have too many tabs opened&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
That means a lack of focus and we are going to be late for the mars missions because you are not focus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1xk6byth--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A6XE8pjxrUjzplgIMhenpGw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1xk6byth--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A6XE8pjxrUjzplgIMhenpGw.png" alt=""&gt;&lt;/a&gt;soooooooooooooooooooooooooooooooo many tabs opened&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can pin tabs&lt;/strong&gt; if you want to keep something, and try to organise your &lt;strong&gt;browsing experience by category&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google Chrome:&lt;/strong&gt; Work emails and backlog in ZenHub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safari:&lt;/strong&gt; React Native releases on app Store and play store&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Chrome Canary:&lt;/strong&gt; Personal emails and youtube&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firefox developer Edition:&lt;/strong&gt; Main browser for everything else&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8_Spck5o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AU_uzjZ7T3gtexA9yZfbYIw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8_Spck5o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AU_uzjZ7T3gtexA9yZfbYIw.png" alt=""&gt;&lt;/a&gt;At least here I can quit / restore tabs depending on the context&lt;/p&gt;

&lt;p&gt;After theses small hacks you gonna have the same kind of zen distraction-free laptop, ready to focus and ship code!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C1b7JRBx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AUt3c3MWSsg4ojm2CGJYYvw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C1b7JRBx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AUt3c3MWSsg4ojm2CGJYYvw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://usejournal.com/?utm_source=medium.com&amp;amp;utm_medium=noteworthy_blog&amp;amp;utm_campaign=guest_post_image"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LHdOt0OG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Af2IVAl0TbsfES9cFGYr40g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📝 Read this story later in &lt;a href="https://usejournal.com/?utm_source=medium.com&amp;amp;utm_medium=noteworthy_blog&amp;amp;utm_campaign=guest_post_read_later_text"&gt;Journal&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>life</category>
      <category>design</category>
      <category>freelance</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Simple release worflow for react native with expo</title>
      <dc:creator>David Leuliette 🤖</dc:creator>
      <pubDate>Tue, 10 Jul 2018 14:29:06 +0000</pubDate>
      <link>https://forem.com/flexbox/simple-release-worflow-for-react-native-with-expo-16ep</link>
      <guid>https://forem.com/flexbox/simple-release-worflow-for-react-native-with-expo-16ep</guid>
      <description>&lt;h3&gt;
  
  
  Just push a button
&lt;/h3&gt;

&lt;h4&gt;
  
  
  How much time it takes to release a React Native application to the iOS App Store and Android Play Store
&lt;/h4&gt;

&lt;p&gt;It’s 2pm and my delivery manager is asking me to release our React Native application to the iOS and Android stores.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Great! I am happy to release our application, just for your information, this will take an entire day.”&lt;br&gt;&lt;br&gt;
“What are you saying? It’s &lt;strong&gt;just pushing a button&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
I don’t see why it’s so long?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://bit.ly/expo-release" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AS5nZBi2nDSqZr5-66IY_xg.png"&gt;&lt;/a&gt;I made a drawing for you. I think now you can see why it’s a long process 😉&lt;/p&gt;

&lt;p&gt;First of all, there are 2 main application stores (Apple and Google). The release process is a little bit different for each, and the testing workflow is different as well. In this article, I am going to cover a specific scenario: &lt;strong&gt;How to release a React Native application with a standalone build from expo&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;create-react-native-app&lt;/code&gt; versus &lt;code&gt;react-native-cli&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If you are in charge of releasing your react native application, you need to understand 2 different application architectures &lt;a href="https://en.wikipedia.org/wiki/Command-line_interface" rel="noopener noreferrer"&gt;generated with your CLI&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  create-react-native-app
&lt;/h4&gt;

&lt;p&gt;According to &lt;a href="https://facebook.github.io/react-native/docs/getting-started.html" rel="noopener noreferrer"&gt;the official documentation,&lt;/a&gt; this solution is the simplest one. You can run your application on any OS with no build config. Xcode or Android Studio are not required. You just have to install another amazing tool called &lt;a href="https://expo.io/" rel="noopener noreferrer"&gt;expo&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  react-native-cli
&lt;/h4&gt;

&lt;p&gt;If you want to use custom component for each platform or add React Native code into your existing application you are probably using this solution.&lt;/p&gt;

&lt;p&gt;If you are looking for the workflow when you have “ejected” from expo, I hightly recommand theses 2 articles from the legendary &lt;a href="https://medium.com/u/6ca0fe37eac1" rel="noopener noreferrer"&gt;Gant Laborde&lt;/a&gt; 🦄&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://shift.infinite.red/simple-react-native-ios-releases-4c28bb53a97b" rel="noopener noreferrer"&gt;Simple React Native iOS Releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://shift.infinite.red/simple-react-native-android-releases-319dc5e29605" rel="noopener noreferrer"&gt;Simple React Native Android Releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Building a standalone app with expo
&lt;/h3&gt;

&lt;p&gt;It’s 2pm and a half because of the coffee break and you are ready to deploy. Let’s do this!&lt;br&gt;&lt;br&gt;
Check the dependencies and run the build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn
exp build:ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This first task takes — at least — 30 minutes. I am lucky, at the office the connection is fast.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I have an idea, maybe I can run the android build in the meantine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bad news rookie. At the moment with expo, you can’t build for iOS and Android at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;35 minutes later&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Yeah! Build successful!&lt;br&gt;&lt;br&gt;
The application is available on expo servers, now I need to download the .ipa file. I am a developer, I can’t be bothered with mouse clicks on a website. Let’s open a terminal and download the build with curl .&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -o app.ipa “$(exp url:ipa)”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;28 minutes later&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Download done!&lt;br&gt;&lt;br&gt;
Now I need to upload the .ipa file with &lt;a href="https://forums.developer.apple.com/thread/64041" rel="noopener noreferrer"&gt;Application Loader&lt;/a&gt; to the apple store servers (Because I don’t need to use Xcode with standalone builds).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;34 minutes 55 seconds later&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Build uploaded!&lt;br&gt;&lt;br&gt;
Guess what?&lt;br&gt;&lt;br&gt;
I can’t push the button yet, because my app is analysed by robots.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AMrEpUTCJ8sGp2Cq5ufWEDA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AMrEpUTCJ8sGp2Cq5ufWEDA.png"&gt;&lt;/a&gt;Your build is not available yet for your QA team&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10 minutes 12 seconds later&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
My build just disappeared from Testflight! 😱&lt;br&gt;&lt;br&gt;
Listen to me rookie, releasing a native application is a complex task. You have no idea how works the replication of your build accross all the CDN’s in the world! Give me some time to process your build.&lt;/p&gt;

&lt;p&gt;The good new is, you can follow the progress in the activity tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2APj6FGs79BSL3q2ggn6xk6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2APj6FGs79BSL3q2ggn6xk6g.png"&gt;&lt;/a&gt;Still processing&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Probally less than 10 minutes later&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Your app is back again!&lt;br&gt;&lt;br&gt;
But you have small extras steps to do: Provide export compliance information. It’s simple, &lt;em&gt;you just need to push a button&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F667%2F1%2AwORNuR3IXBGjTgsFyWMo9g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F667%2F1%2AwORNuR3IXBGjTgsFyWMo9g.gif"&gt;&lt;/a&gt;Push another button for the iOS release&lt;/p&gt;

&lt;p&gt;Straight after accepting the compliance your app should be available for your testing team 🎉&lt;/p&gt;

&lt;p&gt;But wait a minute. I am not going to repeat this workflow everytime.&lt;br&gt;&lt;br&gt;
My friends know me &lt;a href="https://www.youtube.com/watch?v=7_CAqtqEaeo" rel="noopener noreferrer"&gt;as an automation machine&lt;/a&gt;. I wrote this little script to half-automate the process of releasing our react native application with standalone expo build.&lt;/p&gt;

&lt;p&gt;Create a new file and run this script from a terminal&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./bin/ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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



&lt;p&gt;It’s 5pm and your application is released for your end users!&lt;br&gt;&lt;br&gt;
Are you sure about that?&lt;br&gt;&lt;br&gt;
Rookie, you forgot the android version. You need to run the same script for your .apk&lt;/p&gt;

&lt;p&gt;Even if the engineering team working on expo is the best in the world, you need to test on real devices. Developing with &lt;a href="https://expo.io/tools" rel="noopener noreferrer"&gt;expo XDE&lt;/a&gt; is fine, but you can’t rely on the emulator for testing.&lt;br&gt;&lt;br&gt;
By the way, If you don’t have a &lt;a href="https://uxdesign.cc/design-better-release-notes-3e8c8c785231" rel="noopener noreferrer"&gt;release note&lt;/a&gt; and a testing team, there is no point to deploy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a slick testing workflow
&lt;/h3&gt;

&lt;p&gt;Testing your application with the real world is hard. Expo is a great solution for developement but it’s not exactly the same as using the final build delivered to your users.&lt;/p&gt;

&lt;p&gt;It reminds me this talk: “&lt;em&gt;A new version of Firefox is available&lt;/em&gt;”. The mozilla team have 4 differents release channels Nightly, Aurora, Beta and Release.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F768%2F1%2ARcEF7S4E_Mqguh4RO1j4KA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F768%2F1%2ARcEF7S4E_Mqguh4RO1j4KA.jpeg"&gt;&lt;/a&gt;The release workflow for Firefox &lt;a href="https://twitter.com/fosdem" rel="noopener noreferrer"&gt;@FOSDEM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The mozilla team have a routine: every Tuesday at 3pm it’s release day! Builds are deployed in release channel for millions of users.&lt;/p&gt;

&lt;p&gt;Maybe we can follow this weekly routine? The last version is released in production every x week, and we have 2 differents channels for developement and quality insurance.&lt;/p&gt;

&lt;p&gt;Fun part: the worflow for testing your standalone app is different on the 2 platforms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AWgtWk4GnmnUU_USYv8A4Gg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AWgtWk4GnmnUU_USYv8A4Gg.jpeg"&gt;&lt;/a&gt;iOS and android are 2 differents worlds&lt;/p&gt;

&lt;h4&gt;
  
  
  How to onboard testers for iOS
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Add fullname and Apple ID on &lt;a href="https://appstoreconnect.apple.com/" rel="noopener noreferrer"&gt;https://appstoreconnect.apple.com/&lt;/a&gt;
&lt;strong&gt;Apple store connect&lt;/strong&gt; &amp;gt; &lt;strong&gt;Users and Roles&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://itunes.apple.com/gb/app/testflight/id899247664?mt=8" rel="noopener noreferrer"&gt;Download Testflight&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  How to onboard testers for Android
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Add fullname and Google play account on &lt;a href="https://play.google.com/apps/publish" rel="noopener noreferrer"&gt;https://play.google.com/apps/publish/&lt;/a&gt;
&lt;strong&gt;Google Play Console&lt;/strong&gt; &amp;gt; &lt;strong&gt;Manage testers&lt;/strong&gt; &amp;gt; &lt;strong&gt;Create list&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It’s your lucky day rookie, you didn’t have problems with updates of npm packages, screenshot issues on the app store or release notes.&lt;/p&gt;

&lt;p&gt;Your app is deployed. Remember the lesson of the day:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Deploying an app to the store takes–at leat–one day&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt; You can use &lt;a href="https://docs.expo.io/versions/latest/workflow/glossary-of-terms#over-the-air-updates" rel="noopener noreferrer"&gt;Over the Air Updates&lt;/a&gt; to bypass the validations in the stores and speed up the deploy deploy. But you have some limitations.&lt;/p&gt;

&lt;p&gt;I hope this motivates you to start building the perfect workflow for releasing your React Native app. Just drop me a message if you have any questions — I would be glad to help you!&lt;/p&gt;

</description>
      <category>technology</category>
      <category>reactnative</category>
      <category>workflow</category>
      <category>react</category>
    </item>
  </channel>
</rss>
