<?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: Vlad Oganov</title>
    <description>The latest articles on DEV Community by Vlad Oganov (@viscoze).</description>
    <link>https://dev.to/viscoze</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%2F387329%2F8ff94de3-3e0b-4d2b-ac9d-e34a6b52041d.png</url>
      <title>DEV Community: Vlad Oganov</title>
      <link>https://dev.to/viscoze</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/viscoze"/>
    <language>en</language>
    <item>
      <title>Small React Tip – Customisable Filter Panel Component</title>
      <dc:creator>Vlad Oganov</dc:creator>
      <pubDate>Sun, 03 Jan 2021 13:53:01 +0000</pubDate>
      <link>https://dev.to/viscoze/small-react-tip-customisable-filter-panel-component-4klb</link>
      <guid>https://dev.to/viscoze/small-react-tip-customisable-filter-panel-component-4klb</guid>
      <description>&lt;p&gt;We're working on an application that's basically a number of tables. Of course for making life of our customers better we wanted to add an ability to filter data in these tables.&lt;/p&gt;

&lt;p&gt;Depending on a kind of data tables could be filtered by the date, price, name, or an id of an item in the system. Different table had different set of column, hence could have different filters.&lt;/p&gt;

&lt;p&gt;We wanted to have a reusable and customisable solution, that holds the logic of keeping state locally, and give as an ability of adding a new type of a filter field.&lt;/p&gt;

&lt;p&gt;We could go with a straight forward solution like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;FilterPanel&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="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;pug&lt;/span&gt;&lt;span class="s2"&gt;`
    if props.hasDate
      FieldDate(
        value=...
        onChange=...
      )

    if props.hasAmount
      FieldAmount(
        value=...
        onChange=...
      )

    ...
  `&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And as you can see here we just control presence of fields by flags like &lt;code&gt;hasDate&lt;/code&gt;, &lt;code&gt;hasAmount&lt;/code&gt;, which is not flexible in a case we want to change the order of the fields. Then we decided to separate fields and the panel.&lt;/p&gt;

&lt;p&gt;The first step to find a better solution was to draft its interface to outline the way we want to use it. We came up with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;FilterPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="nx"&gt;onApply&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="nx"&gt;FieldGroup&lt;/span&gt;
    &lt;span class="nx"&gt;FieldDate&lt;/span&gt;&lt;span class="p"&gt;(&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;dateMin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;    

    &lt;span class="nx"&gt;FieldDate&lt;/span&gt;&lt;span class="p"&gt;(&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;dateMax&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;FieldGroup&lt;/span&gt;
    &lt;span class="nx"&gt;FieldAmount&lt;/span&gt;&lt;span class="p"&gt;(&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;amountMin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;    

    &lt;span class="nx"&gt;FieldAmount&lt;/span&gt;&lt;span class="p"&gt;(&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;amountMax&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see here we have an ability to configure the panel depending on what table we're going to use it with.&lt;/p&gt;

&lt;p&gt;To share the logic between these fields and make it flexible in a case we want to group the fields we used React Context.&lt;/p&gt;

&lt;p&gt;If it looks new for you, I highly recommend to read the &lt;a href="https://reactjs.org/docs/context.html"&gt;official docs&lt;/a&gt; first.&lt;/p&gt;

&lt;p&gt;We create the following folder structure for this component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;FilterPanel&lt;/span&gt;&lt;span class="o"&gt;/&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;FieldDate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="nx"&gt;FieldAmount&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="nx"&gt;FieldName&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="nx"&gt;atoms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;common&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;---&lt;/span&gt; &lt;span class="nx"&gt;common&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt;
  &lt;span class="nx"&gt;atoms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
  &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start with the Context module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&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;createContext&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;getValue&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;setValue&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="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FilterPanelContext&lt;/span&gt;&lt;span class="dl"&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;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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useFilterPanelContext&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;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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This it our interface to work with the context instance: the Provider component and useFilterPanelContext.&lt;/p&gt;

&lt;p&gt;The state holding went to the FilterPanel component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;FilterPanel&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="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;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValues&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&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;wasChanged&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setWasChanged&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isApplied&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isEmpty&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="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getValue&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setValue&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;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setWasChanged&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="nx"&gt;setValues&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&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;value&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;clearValues&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setWasChanged&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="nx"&gt;setValues&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="nx"&gt;onApply&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;submitValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;setWasChanged&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="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onApply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&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;formLogic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;setValue&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;pug&lt;/span&gt;&lt;span class="s2"&gt;`
    form(onSubmit=submitValues)
      Provider(value=formLogic)
        Wrapper
          each child in Children.toArray(props.children)
            Box(mr=1.5)
              = child

          Box(mr=1.2)
            if isApplied &amp;amp;&amp;amp; !wasChanged
              Button(
                type="button"
                variant="outlined"
                size="medium"
                onClick=clearValues
              ) Clear

            else
              Button(
                type="submit"
                variant="outlined"
                size="medium"
              ) Filter
  `&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A code is the best documentation. And if there are some places you'd like to know more about, here is some explanations.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why do we hold state locally?&lt;/em&gt;  We want not to apply this filters right after they changed — only by click on the "Filter" button.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why do we track &lt;code&gt;wasChanged&lt;/code&gt;?&lt;/em&gt; We want to know if user has changed a value of a field, so we show the "Filter" button again instead of the "Clear" one.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How does &lt;code&gt;Provider&lt;/code&gt; help us?&lt;/em&gt; Data that were passed as the &lt;code&gt;value&lt;/code&gt; props are now available in all components that use the &lt;code&gt;useFilterPanelContext&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What the purpose of &lt;code&gt;Children.toArray(props.children)&lt;/code&gt;?&lt;/em&gt; It's a way to render the children and to apply some additional logic. Here we wrap each child into &lt;code&gt;Box&lt;/code&gt; — a component that adds margin right.&lt;/p&gt;

&lt;p&gt;And the last but not least — a field component. We will take the amount one as an example. Here it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;FilterPanelFieldAmount&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="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;getValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useFilterPanelContext&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;our&lt;/span&gt; &lt;span class="nx"&gt;hook&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClear&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;setValue&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="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getValue&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="nx"&gt;name&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;Icon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pug&lt;/span&gt;&lt;span class="s2"&gt;`
    if value
      IconButton(
        variant="icon"
        size="small"
        type="button"
        onClick=handleClear
      )
        Icons.TimesCircle

    else
      IconLabel(for=props.name)
        Icons.AmountFilter
  `&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;pug&lt;/span&gt;&lt;span class="s2"&gt;`
    FieldText(
      size="medium"
      id=props.name
      name=props.name
      value=value
      placeholder=props.placeholder
      onChange=handleChange
      endAdornment=Icon
    )
  `&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! It's a really nice practice to make something customisable via React Context. I hope it was useful, and let me know if there something I missed.&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>Add pattern matching in React using Daggy</title>
      <dc:creator>Vlad Oganov</dc:creator>
      <pubDate>Wed, 19 Aug 2020 15:41:14 +0000</pubDate>
      <link>https://dev.to/datarockets/add-pattern-matching-in-react-using-daggy-22dg</link>
      <guid>https://dev.to/datarockets/add-pattern-matching-in-react-using-daggy-22dg</guid>
      <description>&lt;p&gt;I’m going to talk about a great library called Daggy, which gives you the ability to &lt;a href="https://datarockets.com/blog/javascript-pattern-matching-library-daggy/"&gt;add pattern matching to your Javascript code&lt;/a&gt; and transform the React render method.&lt;/p&gt;

&lt;p&gt;This article is for people who are already familiar with React and have experience working with it. If you’re a newbie in React, read the article about a &lt;a href="https://datarockets.com/blog/reactjs-quick-start"&gt;quick start in React&lt;/a&gt;, and then return to us. Have a nice read!&lt;/p&gt;

&lt;h1&gt;
  
  
  The problem of “if”
&lt;/h1&gt;

&lt;p&gt;Let’s start with this statement: we love React 😊&lt;br&gt;
&lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt; is a powerful and easy-to-use library with many advantages. And, of course, it has some trade-offs. One of them: it’s a library… so we don’t have any predeclared patterns and restrictions—a.k.a. standards and practices. In this case, we have to invent our own solutions.&lt;/p&gt;

&lt;p&gt;One of these patterns is called conditional rendering. What does this mean? This “if” hell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;render() {
if (this.state.isLoading) {
    return ...
}

if (this.state.isError) {
    return ...
}

if (this.state.isListEmpty) {
    return ...
}

return this.state.list.map(item =&amp;gt; ...)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I don’t like it… do you? I think that you’re just used to it.&lt;/p&gt;

&lt;p&gt;OK, maybe it’s necessary to solve this problem. I think this is the case. Why? Here are some reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React is based on the idea of a declarative way of defining the render function. Using ifs, we have to investigate all the imperative workflow instead of just taking a look at the JSX (or pug) code.&lt;/li&gt;
&lt;li&gt;You have to define a lot of system helper fields in the state, like isLoading, isError, etc. And it’s complicated to reuse such solutions, even with Redux.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  The Solution: javascript pattern matching
&lt;/h1&gt;

&lt;p&gt;Once upon a time, I got the solution: pattern matching. There is only one problem with this solution: we don’t have one in the JS standard, and so we need to use a custom solution. I found one: &lt;a href="https://github.com/fantasyland/daggy"&gt;Daggy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Daggy is a library that gives you the ability to define a type and values of this type—sum types. Using pattern matching we can declare the action depending on the value of this type. Take a look at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Item = daggy.tagged('Item', ['title'])

const List = daggy.taggedSum('List', {
  Empty: [],
  Items: [Item],
})

const list = List.Empty

list.cata({
  Empty: () =&amp;gt; console.log(‘empty…’),
  Items: items =&amp;gt; items.map(item =&amp;gt; console.log(item.title)),
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you have some functional background you may say, “Oh my Haskell!”&lt;br&gt;
And it almost is 🤘&lt;/p&gt;

&lt;p&gt;The advantages of this approach are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You get the type security to make your code more predictable.&lt;/li&gt;
&lt;li&gt;Ability to reuse this definition over your code.&lt;/li&gt;
&lt;li&gt;You make your app behavior more obvious and your life easier 🙂&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And a small explanation about types from my perspective.&lt;/p&gt;
&lt;h1&gt;
  
  
  Binding with Haskell and FP
&lt;/h1&gt;

&lt;p&gt;Types make our code more expressive and readable. You define a range of values that a variable with a type as a label can be or a function can accept. It protects you from summing strings or compelling a cat to “woof”.&lt;/p&gt;

&lt;p&gt;Another advantage is that it makes your code more descriptive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Password = String
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This gives you a little bit of context, but I’d recommend that you take a look at &lt;a href="https://www.haskell.org/"&gt;Haskell&lt;/a&gt; to get familiar with the modern functional hype 😉&lt;/p&gt;

&lt;h1&gt;
  
  
  Javascript pattern matching example
&lt;/h1&gt;

&lt;p&gt;Well, let’s get back to the React world and sprinkle your app with the magic of types. How can it help us make our code more readable and declarative? I think the best way to answer this question is to create a pet application with poor names and logic, but that is to the point 😀&lt;/p&gt;

&lt;p&gt;I’d recommend using &lt;code&gt;create-react-app&lt;/code&gt; and then &lt;code&gt;yarn add daggy&lt;/code&gt;. You can use whatever project structure you want, and I’d recommend the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src
  index.js
  App.js
  App.css
  types.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our pet application will be a small list with fake data fetching and filtering. We’re going to start by declaring types—it’s pretty easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Item = daggy.tagged('Item', ['title'])

const List = daggy.taggedSum('Page', {
  Empty: [],
  Initial: [],
  Items: [Item],
  NotFound: ['searchMessage'],
  FetchError: [],
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A small explanation. The &lt;code&gt;tagged&lt;/code&gt; function gives you a type-wrapper called Item with a field called “title”. The &lt;code&gt;taggedSum&lt;/code&gt; function returns union types so that we can work with an entity depending on the state of the value.&lt;/p&gt;

&lt;p&gt;We’ll define start data and the fake fetch function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const LIST = [
  { title: 'Butter' },
  { title: 'Bread' },
  { title: 'Eggs' },
  { title: 'Fish' },
  { title: 'Cake :3' },
]

const petFetch = () =&amp;gt;
  Promise
    .resolve(LIST)
    .then(list =&amp;gt; ({ list }))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then we’ll focus on our component. State and render go first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class App extends Component {
  state = {
    list: List.Initial,
    searchString: '',
  }

  render() {
    return (
      &amp;lt;div className="container"&amp;gt;
        &amp;lt;ul&amp;gt;
          {this.state.list.cata({
            Empty: () =&amp;gt; &amp;lt;li&amp;gt;This list is empty =(&amp;lt;/li&amp;gt;,
            Initial: () =&amp;gt; &amp;lt;li&amp;gt;Loading...&amp;lt;/li&amp;gt;,
            Items: items =&amp;gt; items.map(({ title }) =&amp;gt; &amp;lt;li&amp;gt;{title}&amp;lt;/li&amp;gt;),
            NotFound: seacrhMessage =&amp;gt; &amp;lt;li&amp;gt;There is nothing on your request: ’{seacrhMessage}’&amp;lt;/li&amp;gt;,
            FetchError: () =&amp;gt; &amp;lt;li&amp;gt;Oooooops...&amp;lt;/li&amp;gt;,
          })}
        &amp;lt;/ul&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Take a closer look at the render function. We are using the cata method to start the pattern matching and, depending on the value of the list, we’ll render a piece of JSX. Personally, I think that looks better than ifs or even switch 💩&lt;/p&gt;

&lt;p&gt;The result is the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8K9an1QT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datarockets.com/wp-content/uploads/2018/08/Screen-Shot-2017-11-11-at-8.03.47-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8K9an1QT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datarockets.com/wp-content/uploads/2018/08/Screen-Shot-2017-11-11-at-8.03.47-PM.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Easy peasy lemon squeezy. Eloquent UI 🙃&lt;br&gt;
And now we’re ready to add other methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;componentWillMount() {
    setTimeout(this.fetchList, 2000)
  }

  fetchList = () =&amp;gt;
    petFetch()
      .then(res =&amp;gt; this.wrapList(res.list))
      .catch(() =&amp;gt; this.setState({ list: List.FetchError }))

  wrapList = (list) =&amp;gt; {
    const wrapperList = list.length === 0
      ? List.Empty
      : List.Items(list)

    this.setState({ list: wrapperList })
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we start fetching with a 2-second delay to show the loading method. Everything’s clear with the lifecycle method &lt;code&gt;componentWillMount&lt;/code&gt; and &lt;code&gt;fetchList&lt;/code&gt;, but you might have some questions about the &lt;code&gt;wrapList&lt;/code&gt; method. Here we construct a value using type constructors, depending on the length of the list, and then set it to the state field “list”.&lt;/p&gt;

&lt;p&gt;For the sake of good code design, I’d recommend that you separate wrapping and state changing, then create a set of functions for working with types. I’ll skip it here, to prevent creating a post with tremendous size 😜&lt;/p&gt;

&lt;p&gt;Let’s make our life a little bit harder and add a filter for titles. First, we should upgrade our state and render method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; state = {
     list: List.Initial,
     searchString: '', }

 render() {
     return (
       &amp;lt;div className="container"&amp;gt;
         &amp;lt;input onChange={this.handleChange} /&amp;gt;
         &amp;lt;ul&amp;gt;
           {this.filterList().cata({
             Empty: () =&amp;gt; &amp;lt;li&amp;gt;This list is empty =(&amp;lt;/li&amp;gt;,
             Initial: () =&amp;gt; &amp;lt;li&amp;gt;Loading...&amp;lt;/li&amp;gt;,
             Items: items =&amp;gt; items.map(({ title }) =&amp;gt; &amp;lt;li key={title}&amp;gt;{title}&amp;lt;/li&amp;gt;),
             NotFound: seacrhMessage =&amp;gt; &amp;lt;li&amp;gt;There is nothing on your request: {seacrhMessage}&amp;lt;/li&amp;gt;,
             FetchError: () =&amp;gt; &amp;lt;li&amp;gt;Oooooops...&amp;lt;/li&amp;gt;,
           })}
         &amp;lt;/ul&amp;gt;
       &amp;lt;/div&amp;gt;
     );
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then we need to add a method for filtering, handling the input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;filterList = () =&amp;gt;
    this.state.list.cata({
      Empty: () =&amp;gt; List.Empty,
      Initial: () =&amp;gt; List.Initial,
      Items: items =&amp;gt; {
        const filteredList = items.filter(this.matchSearch)

        return filteredList.length &amp;gt; 0
          ? List.Items(filteredList)
          : List.NotFound(this.state.searchString)
      },
      NotFound: () =&amp;gt; List.NotFound(this.state.searchString),
      FetchError: () =&amp;gt; List.FetchError,
    })

  handleChange = ({ target }) =&amp;gt;
    this.setState(() =&amp;gt; ({ searchString: target.value }))

  matchSearch = item =&amp;gt;
    (item.title.indexOf(this.state.searchString) !== -1)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The workflow of the filtering is pretty clear and obvious: we filter the list and the result of this action wraps into the type constructors. We get value depending on the result of filtering. Here’s what we got:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vnrkpVku--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datarockets.com/wp-content/uploads/2018/08/Screen-Shot-2017-11-11-at-9.15.35-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vnrkpVku--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datarockets.com/wp-content/uploads/2018/08/Screen-Shot-2017-11-11-at-9.15.35-PM.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Create tagged constructors with Daggy
&lt;/h1&gt;

&lt;p&gt;Here we go. First of all, I’d like to say about the library Daggy that it’s a nice and easy-to-use portal to the functional world that gives us the ability to use pattern matching and union types in JS applications. Second, please go to the &lt;a href="https://github.com/fantasyland/daggy"&gt;official Daggy GitHub&lt;/a&gt; of this library and click on “Star”, so that the creators will know you find their tool useful 😎&lt;/p&gt;

&lt;p&gt;Also, types give us a simple way to make our code readable, giving entities of our application a descriptive name and a list of fields for predictability.&lt;/p&gt;

&lt;p&gt;I’d recommend that you get an experience in any Functional Language to be on top of the modern style of JS coding and write more maintainable applications, not through the objects, but through functions and types.&lt;/p&gt;

&lt;p&gt;As always, have a nice experience with your Functional start!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>How I arrange a React component</title>
      <dc:creator>Vlad Oganov</dc:creator>
      <pubDate>Wed, 19 Aug 2020 15:29:46 +0000</pubDate>
      <link>https://dev.to/datarockets/how-i-arrange-a-react-component-2j6h</link>
      <guid>https://dev.to/datarockets/how-i-arrange-a-react-component-2j6h</guid>
      <description>&lt;p&gt;In this article, I’m going to offer my vision of how a basic &lt;a href="https://datarockets.com/blog/react-components-basic-tutorial/"&gt;React component&lt;/a&gt; should look and how to structure your React app. If you have a different point of view, go ahead and let me know 😉&lt;/p&gt;

&lt;p&gt;I do like React and the concept of components as building blocks of your application. So, the fact that React is a library brings freedom to make everything we want and use any approach that we have in our mind. It sounds good because it is, but this liberation of development using React brings our application to the core of chaos: every team uses different concepts and arrangements. And, it touches not just a project folder structure but the arrangement of components as well.&lt;/p&gt;

&lt;p&gt;If you’re a newbie in React, read the article about a &lt;a href="https://datarockets.com/blog/reactjs-quick-start"&gt;quick start in React&lt;/a&gt;, and then return to us.&lt;/p&gt;

&lt;h1&gt;
  
  
  Basic React component
&lt;/h1&gt;

&lt;p&gt;To solve the problem of over diversity it’d be great to have a &lt;strong&gt;fixed component structure&lt;/strong&gt;. I prefer the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MyComponent extends Component {
  // prop types

  // state declaration

  // lifecycle methods

  // render

  // event handlers

  // private methods
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The main idea of such an arrangement is that you process data (state and props) and construct a render method’s JSX. The idea to &lt;strong&gt;keep private methods after the “render” function&lt;/strong&gt; is that you first read a method name in “render” before you read further and understand what the method does. And, if you pick good names for private methods, you rarely need to jump from reading the render method to the bottom of the component to understand what the component does. And, of course, it gives you a better way to understand and “read” a component.&lt;/p&gt;

&lt;p&gt;Let’s take a look at an example. We will create a list of items and add an ability to filter the items by title. Also, all items have a formatted date of creation so, for this, we’re going to use a moment – &lt;strong&gt;a library with awesome API to process date&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class List extends Component {
 // props types
 static propTypes = {
   items: PropTypes.arrayOf(PropTypes.shape({
     text: PropTypes.string,
     date: PropTypes.string,
   })),
 }

 // state declaration
 state = {
   seachString: '',
 }

 // lifecycle methods
 shouldComponentUpdate() {
   return !_.isEmpty(this.filterItems());
 }

 // render
 render = () =&amp;gt; (
   &amp;lt;div&amp;gt;
     &amp;lt;input
       type="text"
       value={this.state.seachString}
       onChange={this.handleSearchStringChange}
     /&amp;gt;

     &amp;lt;ul&amp;gt;
       {this.filterItems().map(({ text, date }) =&amp;gt; (
         &amp;lt;li key={`${text}__${date}`}&amp;gt;
           {text}
           {this.formatDate(date)}
         &amp;lt;/li&amp;gt;
       ))}
     &amp;lt;/ul&amp;gt;
   &amp;lt;/div&amp;gt;
 ); 

 // event handlers
 handleSearchStringChange = event =&amp;gt;
   this.setState({ seachString: event.target.value });

 // private methods
 filterItems = () =&amp;gt;
   this.props.items.filter(({ text }) =&amp;gt;
     (text.indexOf(this.state.seachString) !== -1));

 formatDate = date =&amp;gt; 
   moment(date).format('MMM Do YY');
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we go! We create the component using our arrangement approach, and it makes our components more predictable and quicker at reading your code.&lt;/p&gt;

&lt;h1&gt;
  
  
  React dumb components
&lt;/h1&gt;

&lt;p&gt;In the React community, we define components as smart, which has a state, and dumb, which has no state. Most of your components should be dumb because they are easy to compose, reuse, and debug.&lt;/p&gt;

&lt;p&gt;Most often, the &lt;strong&gt;dumb component&lt;/strong&gt; is a simple function which gets props and returns JSX. And, the arrangement of such components should be simple: all handles should be passed to one and all the data should be already processed and formatted. Take a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Button = ({ label, onClick }) =&amp;gt; (
  &amp;lt;button onClick={onClick}&amp;gt;
    {label}
  &amp;lt;/button&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Actually, there is nothing to arrange and that’s the point: there is only the destructuring and the return of JSX. Simple and reusable.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;The main purpose of such a &lt;strong&gt;component arrangement&lt;/strong&gt; is to bring an order to this zoo of the approaches to work with React components and create a good React project structure. And, yes, you should have a linter for checking your code and keep the same approach in every point of your project. I’d recommend you to use &lt;a href="https://github.com/datarockets/style-guide"&gt;our company’s linter config&lt;/a&gt;. We made it for you!&lt;/p&gt;

&lt;p&gt;Make your application orderly and it’ll give a great sense of readability and then maintainability in the future 😉&lt;/p&gt;

&lt;p&gt;Have a productive coding!&lt;/p&gt;

</description>
      <category>react</category>
      <category>beginners</category>
    </item>
    <item>
      <title>React. Quick Start</title>
      <dc:creator>Vlad Oganov</dc:creator>
      <pubDate>Wed, 19 Aug 2020 14:43:51 +0000</pubDate>
      <link>https://dev.to/datarockets/react-quick-start-3909</link>
      <guid>https://dev.to/datarockets/react-quick-start-3909</guid>
      <description>&lt;p&gt;Everyone was a newbie in some field. And there is no way to become a pro in an hour. In this article, I’m going to give you a roadmap to react quick start.&lt;/p&gt;

&lt;p&gt;The most important and, unfortunately, the hardest part is deciding which order you should learn in, and separating good resources from bad ones. I had this challenge. There wasn’t a lighthouse to show me the way, so it was the way of trial and error to find what I should focus on and what I should ignore.&lt;/p&gt;

&lt;h1&gt;
  
  
  Learn HTML &amp;amp; CSS and the basics of JS
&lt;/h1&gt;

&lt;p&gt;First and foremost, I hope that you know HTML &amp;amp; CSS and the basics of JS, especially ES6. You should know how to use ES6 classes, instance level arrow functions, and how inheritance works before the React quick start.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 0. Install React
&lt;/h1&gt;

&lt;p&gt;The hardest part of every journey is the first step! In our case it is the zero step – &lt;strong&gt;install an environment&lt;/strong&gt;. To make it as fast as possible, use &lt;a href="https://github.com/facebookincubator/create-react-app"&gt;create react app&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You’ll get all things you need, and start learning React without friction with a setup part of development.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1. Learn the React basics
&lt;/h1&gt;

&lt;p&gt;At this step, it will be enough to read the &lt;a href="https://facebook.github.io/react"&gt;official React guide&lt;/a&gt;. Everything you need is there.&lt;/p&gt;

&lt;p&gt;Use these code examples as samples, and &lt;strong&gt;create your own app&lt;/strong&gt; by upgrading these code snippets. Pay attention to the rendering of lists, and lifecycle methods.&lt;/p&gt;

&lt;p&gt;Before you move further… check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is the difference between props and state?&lt;/li&gt;
&lt;li&gt;How can we hide some block of JSX under a condition?&lt;/li&gt;
&lt;li&gt;Why should we use keys?&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Step 2. Learn the React best practices
&lt;/h1&gt;

&lt;p&gt;In the React community, we use the techniques from &lt;strong&gt;Functional Programming&lt;/strong&gt; such as pure functions, immutability, explicit dataflow, etc. For example, you should use &lt;code&gt;.map/.filter/.reduce&lt;/code&gt; instead of &lt;code&gt;for loop&lt;/code&gt; in the matter of immutability.&lt;/p&gt;

&lt;p&gt;Well, to keep things simple, I’d recommend to read the &lt;a href="https://tylermcginnis.com/react-aha-moments/"&gt;‘React “Aha” Moments‘&lt;/a&gt; article and take some notes from it. This article will give you &lt;strong&gt;the React way of thinking&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Also, reread &lt;a href="https://facebook.github.io/react/docs/thinking-in-react.html"&gt;the following article&lt;/a&gt; from the React official docs.&lt;/p&gt;

&lt;p&gt;Check my thoughts on &lt;a href="https://new.datarockets.com/blog/react-components-basic-tutorial/"&gt;how to arrange methods inside a component&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ask yourself:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is the inverse data flow?&lt;/li&gt;
&lt;li&gt;What the difference between containers and represental components?&lt;/li&gt;
&lt;li&gt;How should we use the children prop?&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Step 3. Learn React &amp;amp; Redux stack
&lt;/h1&gt;

&lt;p&gt;Of course, it’s harder than just using React for creating some small apps, but in the real development world, Redux is the essential part of any React app, not just attachment. And, of course, there are a lot of other flux-like frameworks, but Redux gives you the simplest way to keep an application state of any scale. Don’t run into this stuff now and start with so-called container components. When you feel it is not meeting your expectations, start using Redux in learning apps and you’ll see how it helps.&lt;/p&gt;

&lt;p&gt;Read the &lt;a href="http://redux.js.org/"&gt;official Redux guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check yourself:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Try to draw the React-Redux work cycle. Check this.&lt;/li&gt;
&lt;li&gt;When do middlewares come in?&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Step 4. Learn React + React Router stack
&lt;/h1&gt;

&lt;p&gt;It goes without saying that we live in the epoch of the web applications, but it’s still web and it’s very important to &lt;strong&gt;divide apps by routes&lt;/strong&gt; to add more semantics. For instance, a route for your blog post /posts/42, or your profile /profile, etc.&lt;/p&gt;

&lt;p&gt;Of course, don’t fall into this and push Router everywhere. First, you should experience the problem of the route-less and then you’ll feel how it will make your application smarter and user-friendly.&lt;/p&gt;

&lt;p&gt;Read the &lt;a href="https://github.com/ReactTraining/react-router"&gt;official React Router guide&lt;/a&gt;, and the &lt;a href="https://css-tricks.com/learning-react-router/"&gt;following article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ask yourself:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is the difference between absolute and relative paths?&lt;/li&gt;
&lt;li&gt;How do the nested routes render?&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Step 5. Reuse components
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;To keep your code clean&lt;/strong&gt;, you should create a component that you can reuse. It’s obvious, but there’s another part of the ‘Reuse components’ principle: &lt;strong&gt;don’t be afraid of third-party components&lt;/strong&gt;. Use the components that were created by other developers because they’ll save you time.&lt;/p&gt;

&lt;p&gt;You should also take into consideration the fact that any third-party component is a dependency.&lt;/p&gt;

&lt;p&gt;And discover how it works, because you’ll learn from others best practice and principles.&lt;/p&gt;

&lt;p&gt;A short list of available components is &lt;a href="https://github.com/brillout/awesome-react-components"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6. Keep moving and practice more
&lt;/h1&gt;

&lt;p&gt;Learn more, practice more!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create apps that will solve your problems and make your life more comfortable.&lt;/li&gt;
&lt;li&gt;Read articles about React and its environment. Check authors, and follow them on Twitter. Check this for example.&lt;/li&gt;
&lt;li&gt;Don’t be afraid of some strange techs, such as Redux Sagas, or Redux Observables. Use them, and you’ll love them ❤️&lt;/li&gt;
&lt;li&gt;Investigate the static typing in JS using Flow or Typescript.&lt;/li&gt;
&lt;li&gt;Learn React Native to feel the real power of React in the mobile dev field.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://datarockets.com/blog/react-native-architecture-split-components/"&gt;React Native: how to split responsibilities across components&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7. Be in the heart of the community
&lt;/h1&gt;

&lt;p&gt;We live in the IT age and it’s hard to learn something if you are isolated. You should go to conferences and follow interesting people on Twitter. In general, keep track of the community life, and you’ll always be in-demand as a developer.&lt;/p&gt;

&lt;p&gt;I recommend to check these repos from time to time:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/enaqx/awesome-react"&gt;Awesome-react&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/markerikson/react-redux-links"&gt;React-redux-links&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also recommend to follow these guys:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/grabbou"&gt;Mike Grabowski&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/tylermcginnis"&gt;Tyler McGinnis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/ReactGuru"&gt;ReactGuru&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/ReactJS_News"&gt;ReactJS_News&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/sebmarkbage/"&gt;Sebastian Markbåge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/swannodette"&gt;David Nolen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More interesting people to follow in the &lt;a href="https://medium.com/@dan_abramov/my-react-list-862227952a8c"&gt;Dan Abramov’s React List&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrapping up
&lt;/h1&gt;

&lt;p&gt;If you want to do something, do it well! Don’t be afraid, keep moving, widen your horizons, and learn from other people to evolve yourself. Enjoy your quick start!&lt;/p&gt;

</description>
      <category>react</category>
      <category>beginners</category>
      <category>redux</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Typing React Components with Flow</title>
      <dc:creator>Vlad Oganov</dc:creator>
      <pubDate>Wed, 19 Aug 2020 14:31:08 +0000</pubDate>
      <link>https://dev.to/datarockets/typing-react-components-with-flow-1kic</link>
      <guid>https://dev.to/datarockets/typing-react-components-with-flow-1kic</guid>
      <description>&lt;p&gt;I’m going to describe &lt;a href="https://datarockets.com/blog/react-components-flow-tutorial/"&gt;how to use Flow in terms of React &amp;amp; Redux&lt;/a&gt;. The reason I did this is that this area is not commonly covered. I couldn’t find any best practices or really cool tutorials for using Flow in React &amp;amp; Redux applications. Let’s fix that!&lt;/p&gt;

&lt;p&gt;We live in a strange time when almost all programming languages are moving towards static type systems. There are some rumors that Python and Ruby are going to become a static type. And JavaScript is no exception.&lt;/p&gt;

&lt;p&gt;There are some options for making JS type safe: &lt;strong&gt;TypeScript, Dart, and Flow&lt;/strong&gt;. I don’t like Dart because of its non-JS appearance. It looks like Java or something similar, but not JS. And of course, it’s not really popular in the JS community.&lt;/p&gt;

&lt;p&gt;Another option is TypeScript. In comparison with Flow, in TypeScript, you have to write all of your projects from the beginning, whereas you can apply Flow gradually. And because TypeScript is NOT JavaScript, it cannot follow the ECMAScript standard, and of course, not all libraries are available for TypeScript.&lt;/p&gt;

&lt;p&gt;The final option is Flow. It is really amazing! It covers the entire spectrum of typing tools you need, such as type aliases, type inference, type unions, etc.&lt;/p&gt;

&lt;p&gt;This article is not for newbies to Flow, because here I focus on React with Flow practices. If you don’t know the basics of Flow, please read my article &lt;a href="https://datarockets.com/blog/reactjs-quick-start"&gt;“ReactJS. Quick Start”&lt;/a&gt;, the &lt;a href="https://flowtype.org/"&gt;official Flow docs&lt;/a&gt; and then come back to us.&lt;/p&gt;

&lt;h1&gt;
  
  
  Advantages of using Flow
&lt;/h1&gt;

&lt;p&gt;The advantages of using Flow as a static type checker are the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It looks very clear and natural.&lt;/strong&gt; People with either Haskell or a Swift, Scala, and Kotlin background will find this checker extremely accessible and nice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is still JavaScript.&lt;/strong&gt; We have the same idioms, the same environment, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your code more reliable.&lt;/strong&gt; It checks your code at compilation time, not runtime, so that you have feedback about how your code will perform before you run it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It offers code documentation.&lt;/strong&gt; You need only one glance to understand what this function wants to accept and what it returns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It decreases the number of tests.&lt;/strong&gt; With static type checking, you don’t need to test every function with many conditions and in many contexts to recognize that it doesn’t work like it is supposed to because if it compiles, it probably works. You are recommended to test only high-level APIs such as what a user sees and how a user interacts with your application.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  From PropTypes to Props
&lt;/h1&gt;

&lt;p&gt;Currently, react library provides &lt;code&gt;PropTypes&lt;/code&gt; for checking the types of props that we pass to a component. That’s cool, but using PropTypes becomes a mess: we have to use the PropTypes namespace and add some strange-looking checkers like &lt;code&gt;PropTypes.oneOf([‘…’])&lt;/code&gt;. Also, the main thing is that PropTypes checks your code at runtime, while Flow checks your code before you run it. Check it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { Component, PropTypes } from ‘react’;

class MyComponent extends Component { 
    static propTypes = {
        label: PropTypes.string,
        status: PropTypes.oneOf(['error', 'fetching', 'ready']),
        items : PropTypes.arrayOf(PropsTypes.string),
        numberOfUsers: PropTypes.number,
        metainfo: PropTypes.shape({
            content: PropTypes.string,
                        userAvatar: PropTypes.string,
        }),
        }
        // cooooode
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Using Flow, we can clean it up and add more semantics via type aliases and union types. For instance, the status property has a countless number of discrete values, so it’d be better to transform it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Status = ‘error’ | ‘fetching’ | ‘ready’;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And now, instead of &lt;code&gt;status: PropTypes.oneOf(['error', 'fetching', 'ready']),&lt;/code&gt; we can use &lt;code&gt;status: Status,&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We should do the same thing with metainfo too. For this task, we need to type alias the shape of a Metainfo object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Metainfo = {
    content: string,
    userAvatar: string,
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s combine our semantics improvements and Flow syntax in our component. We’d get something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Status = ‘error’ | ‘fetching’ | ‘ready’;
type Metainfo = {
        content: string,
        userAvatar: string,
};


class MyComponent extends Component { 
    props: {
        label: string,
        status: Status,
        items: Array&amp;lt;string&amp;gt;,
        numberOfUsers: number,
        metainfo: Metainfo,
        }

        // cooooode
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Pretty concise and clear. One glance and you see what happens.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pure Components
&lt;/h1&gt;

&lt;p&gt;I hope you know what this is. If not, a small explanation: a pure component is a component without a state or methods inside itself; it is just a pure function that accepts props and returns JSX. Briefly, I like to use this feature with UI things such as buttons, inputs, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The only problem that destroys all the beauty of pure components is PropTypes&lt;/strong&gt;. We have to make something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MyPureComponent.propTypes = { … }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;…or go back to the class declaration. Well, let’s move to Flow. It gives us the ability to &lt;strong&gt;create pure components without PropTypes&lt;/strong&gt; and keep the type safe. I’m gonna show you a comparison example for better understanding. Take a look at this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { Component, PropTypes } from ‘react’;

class Section extends Component {
    static propTypes = {
        title: PropTypes.string,
                content: PropTypes.string,
                link: PropTypes.string,
        }

        render = () =&amp;gt; (
            &amp;lt;div&amp;gt;
           &amp;lt;title&amp;gt;{this.props.title}&amp;lt;/title&amp;gt;
           &amp;lt;p&amp;gt;{this.props.content}&amp;lt;/p&amp;gt;
           &amp;lt;div&amp;gt;{this.props.link}&amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
    ) 
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s transform it into a pure component using function syntax and Flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { Component, PropTypes } from ‘react’;

    type SectionProps = {
                title: string,
                content: string,
                link: string
        };

const Section = ({ title, content, link }: SectionProps) =&amp;gt; (
    &amp;lt;div&amp;gt;
        &amp;lt;title&amp;gt;{title}&amp;lt;/title&amp;gt;
            &amp;lt;p&amp;gt;{content}&amp;lt;/p&amp;gt;
            &amp;lt;div&amp;gt;{link}&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
) ;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Awesome! In my opinion, this looks simple and clear.&lt;/p&gt;

&lt;h1&gt;
  
  
  Redux (Action Creators, Thunk Action Creators, Reducer)
&lt;/h1&gt;

&lt;p&gt;Action creators are just pure functions that accept something and return an object. To increase safety, we can use types. But this is not the only reason to use Flow; we can add the semantics to it. For instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const fetchedUserProfile = user =&amp;gt; ({
        type: ‘fetchedUserProfile’,
        payload: {
            user,
        },
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Using Flow, we can make our type for the user to check that the user object has the properties we expect. Also, we can do the same for action so that it’ll enforce the convention about what action should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type User = { id: number, name: string, email: string };
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And for actions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type ActionType = ‘error’ | ‘fetchUserProfile’ | ‘fetchedUserProfile’;
type Action = { type: ActionType, payload: Object };
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With our new types, the transformation of the &lt;code&gt;fetchedUserProfile&lt;/code&gt; function will be the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const fetchedUserProfile = (user: User): Action =&amp;gt; ({ … });
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Just one glance and you’ll know how to use it. Documentability! 🙂&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Reducer&lt;/code&gt; is just a function too, so we can add some magic (not) to it via types. A plain reducer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const defaultState = {
    status: ‘’,
    userProfile: {},
    items: [],
};

const reducer = (state = defaultState, action) =&amp;gt; {
    switch(action.type) {
            case ‘’: {}
            default: return state;
    }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Add types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type User = { id: number, name: string, email: string };
    type Items = { id: number, content: string, check: boolean };

    type ActionType = ‘error’ | ‘fetchUserProfile’ | ‘fetchedUserProfile’;
    type Action = { type: ActionType, payload: Object };

    type State = {
        status: ‘error’ | ‘loading’ | ‘ready’,
        userProfile: User, 
        items: Array&amp;lt;Items&amp;gt;,
    };
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And our reducer becomes cool and clear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const defaultState: State = {
    status: ‘’,
    userProfile: {},
    items: [],
};

const reducer = (state: State = defaultState, action:  Action): State =&amp;gt; {
    switch(action.type) {
            case ‘’: {}
            default: return state;
    }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Meow :3&lt;/p&gt;

&lt;p&gt;We’re moving further toward more advanced types of action creators—thunk action creators. Here we can also use types, but it’s more developed than previous cases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fetchUserProfile = (userId) =&amp;gt; (dispatch) =&amp;gt; 
    User
    .load(userId)
    .then(response =&amp;gt; dispatch(fetchedUserProfile(response.user)))
    .catch(() =&amp;gt; dispatch(fetchingError()));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Are you ready for types? Of course, you are!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type ActionType = ‘error’ | ‘fetchUserProfile’ | ‘fetchedUserProfile’;
type Action = { type: ActionType, payload: Object };

type Dispatch = (action: Action) =&amp;gt; void;


const fetchUserProfile = (userId: number) =&amp;gt;
(dispatch: Dispatch): void =&amp;gt; 
    User
    .load(userId)
    .then(response =&amp;gt; dispatch(fetchedUserProfile(response.user)))
    .catch(() =&amp;gt; dispatch(fetchingError()));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I’d recommend you look at some &lt;a href="https://flow.org/en/docs/types/#functions"&gt;examples of using types with async functions&lt;/a&gt; in the official docs. There you’ll find awesome instances of using Flow with asyncs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Don’t Use Object
&lt;/h1&gt;

&lt;p&gt;In this section, I’d like to go on a tangent and talk about generics. It’s useful to raise a level of abstraction and make boxes around the things with different types.&lt;/p&gt;

&lt;p&gt;Do you remember our &lt;code&gt;Action type&lt;/code&gt;? No? Me either 🙂 JK&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Action = { type: ActionType, payload: Object };
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It isn’t type safe in light of the payload property’s type because we can place every object with whatever signature. The only one that works—unpredictable. How can we solve this problem in terms of Flow? &lt;strong&gt;Use disjoint unions&lt;/strong&gt;. Look at this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Action =
{ type: ‘create’, payload: { name: string } }
|  { type: ‘delete’, payload: { id: number } }
|  { type: ‘update’, payload: { id: number, name: string} };
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Type library
&lt;/h1&gt;

&lt;p&gt;Move your types to a separate module (js file) so that they can be used in other modules and be the same throughout the entire app. You just need something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// types.js
export type User = { name: string, email: string, id: number | string };
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And just import it to another js file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// actions.js
import type { User } from ‘./types.js’;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Add more semantics
&lt;/h1&gt;

&lt;p&gt;Instead of using types only for checking the reliability of your apps, you should use it to add an explanation of what it is via the type name. Check the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Password = string;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I think it is more understandable for further use now.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Use type aliases and union types to add more semantics.&lt;/li&gt;
&lt;li&gt;Use pure components.&lt;/li&gt;
&lt;li&gt;Use types for class components.&lt;/li&gt;
&lt;li&gt;Use types for action creators.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But enough is enough. Don’t type alias everything, and don’t recreate the wheel.&lt;br&gt;
Well, thank you for coming! Love React, use types, and be happy.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>redux</category>
    </item>
    <item>
      <title>useReducer for the win</title>
      <dc:creator>Vlad Oganov</dc:creator>
      <pubDate>Mon, 25 May 2020 18:42:58 +0000</pubDate>
      <link>https://dev.to/viscoze/usereducer-for-the-win-413f</link>
      <guid>https://dev.to/viscoze/usereducer-for-the-win-413f</guid>
      <description>&lt;p&gt;Hey, how are you there? Well, here is a story. It's quite small, but it can save your time and health. So keep reading.&lt;/p&gt;

&lt;p&gt;We wanted to have a sequence of steps in our application which it’s changed depending on user’s answers. Take a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;step with yes/no question -&amp;gt; if yes: Step 1 -&amp;gt; if yes: Step 2 -&amp;gt; Step 3 -&amp;gt; Step 4
                          -&amp;gt; if no: skip    -&amp;gt; if no:  skip   -&amp;gt; Step 3 -&amp;gt; Step 4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The logic is the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User pick an answer in a form&lt;/li&gt;
&lt;li&gt;The form sends the data to an API – the API persists the answer&lt;/li&gt;
&lt;li&gt;On success we change the state of the redux store&lt;/li&gt;
&lt;li&gt;We change a flow of steps depending on the answers&lt;/li&gt;
&lt;li&gt;Go to the next step accordingly to the flow&lt;/li&gt;
&lt;li&gt;Profit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Disclaimer 1.: there is a pretty nice library that can help to manage sophisticated flows – &lt;a href="https://xstate.js.org"&gt;xstate&lt;/a&gt;. And for this case it'd be an overkill, so we created our small, simple, homemade solution 😌&lt;/p&gt;

&lt;p&gt;Disclaimer 2.: the code presented here is simplified to focus on the issue. Please, don't judge &lt;/p&gt;

&lt;p&gt;And here is the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useSteps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setStep&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flow&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;goBack&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="nx"&gt;prevStep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;setStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevStep&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;goForward&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="nx"&gt;nextStep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;setStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextStep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;current&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;goForward&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;goBack&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;LeComponent&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;entity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useEntity&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;flow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;STEP_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yesOrNo&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Yes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;STEP_2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yesOrNo&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Yes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;STEP_3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;STEP_4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&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;steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useSteps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flow&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;pug&lt;/span&gt;&lt;span class="s2"&gt;`
    if steps.current === STEP_1
       LeForm(
          onCancel=steps.goBack
          onSubmitSuccess=steps.goForward
        )

    if steps.current === STEP_2
       .........
  `&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And it won't work. Every time we run it, &lt;code&gt;onSubmitSuccess&lt;/code&gt; is called with the old &lt;code&gt;steps.goForward&lt;/code&gt; so even if user answered 'yes', we redirect them to &lt;code&gt;Step 3&lt;/code&gt;. Meh. Worth to mention: the &lt;code&gt;entity&lt;/code&gt; and the &lt;code&gt;flow&lt;/code&gt; are updated correctly before the action of going forward. It. Must. Work. Except it doesn't.&lt;/p&gt;

&lt;p&gt;Ok, an overengineered solution to help. Every time user updates the value in the form we update the state of the parent component using &lt;code&gt;redux-form&lt;/code&gt;'s &lt;code&gt;onChange&lt;/code&gt;. Also we have to sync the state of our component with the state that has been persisted on the API in case of the page reloading – so we have this &lt;code&gt;useEffect&lt;/code&gt; there. Shit is getting crazy. Take a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;LeComponent&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;entity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useEntity&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;yesOrNo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setYesOrNo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleYesOrNo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setYesOrNo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yesOrNo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setYesOrNo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yesOrNo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yesOrNo&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;flow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;STEP_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yesOrNo&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Yes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;STEP_2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yesOrNo&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Yes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;STEP_3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;STEP_4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&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;steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useSteps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flow&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;pug&lt;/span&gt;&lt;span class="s2"&gt;`
    if steps.current === STEP_1
       LeForm(
          onCancel=steps.goBack
          onSubmitSuccess=steps.goForward
          onChange=handleYesOrNo
        )

    if steps.current === STEP_2
       .........
  `&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Perfect! I'm being paid for a reason definitely. But no, come on, we can't leave it as that. What if we need to track more answers? So we started to investigate if there is something wrong with &lt;code&gt;redux-form&lt;/code&gt;. Every value around is new, but &lt;code&gt;onSubmitSuccess&lt;/code&gt; is living in the past.&lt;/p&gt;

&lt;p&gt;And we didn't find what really happened. Instead we decided why not to use &lt;code&gt;useReducer&lt;/code&gt; in the &lt;code&gt;useSteps&lt;/code&gt;. How? Take a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useSteps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;goBack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;goForward&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;default&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;step&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;current&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;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flow&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;goBack&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;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;goBack&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;goForward&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;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;goForward&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;goForward&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;goBack&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;Sweet! Now &lt;code&gt;goForward&lt;/code&gt; just push an action w/o rely on the closure, so we can remove all of these stuff of keeping state of the answer in the component and make it in the &lt;em&gt;react way&lt;/em&gt; so to say.&lt;/p&gt;

&lt;p&gt;And it worked out 🚀 And this is a nice practice in your toolkit for creating such flows with conditional showing of steps. Be happy. &lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

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