<?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: Ignacio Mattos</title>
    <description>The latest articles on DEV Community by Ignacio Mattos (@nachosource).</description>
    <link>https://dev.to/nachosource</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%2F560094%2F3f1362d0-6d43-454e-982e-b98fb01d697e.jpeg</url>
      <title>DEV Community: Ignacio Mattos</title>
      <link>https://dev.to/nachosource</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nachosource"/>
    <language>en</language>
    <item>
      <title>Good practices in ReactJs - State variables and attached logic</title>
      <dc:creator>Ignacio Mattos</dc:creator>
      <pubDate>Mon, 19 Aug 2024 18:20:08 +0000</pubDate>
      <link>https://dev.to/nachosource/good-practices-in-reactjs-state-variables-and-attached-logic-51of</link>
      <guid>https://dev.to/nachosource/good-practices-in-reactjs-state-variables-and-attached-logic-51of</guid>
      <description>&lt;p&gt;In &lt;em&gt;ReactJs&lt;/em&gt; &amp;amp; &lt;em&gt;React-Native&lt;/em&gt; we often find a bad use of components’ state. This is an issue that takes special relevance as applications scale up and get more complex (e.g. through the use of nested components) and it can end up in either a compromised performance (damaging the user’s experience), a harsh dev experience when it comes to maintain our code or even a buggy application plagued with unexpected behaviours.&lt;br&gt;
When this happens it is also common for trivial problems to take more time to be fixed than they should or for particular solutions to trigger bugs at another corner of our app.&lt;/p&gt;

&lt;p&gt;Today we will use a simple -but real- error scenario to show what a bad implementation of &lt;em&gt;React&lt;/em&gt; Components' state can get us and how to make it work as expected. In this case we are using &lt;em&gt;&lt;a href="https://react.dev/reference/react/hooks" rel="noopener noreferrer"&gt;React Hooks&lt;/a&gt;&lt;/em&gt; for state management.&lt;/p&gt;
&lt;h2&gt;
  
  
  Particular situation
&lt;/h2&gt;

&lt;p&gt;In one of our components, formed by a basic form and an attached logic that sends its data to an API, we detected an inconsistency between the inputted data and the one that our service was finally receiving.&lt;br&gt;
It turned out to be an issue allocated within the logic attached to the component’s state changes. To be more specific, a state variable was being used to save the form values and its content was being sent inside a request immediately after its update (or the attempt to update its value, as we will see).&lt;/p&gt;

&lt;p&gt;This is how &lt;em&gt;React&lt;/em&gt; Components’ lifecycle was not being followed: when we update state variables React needs some time to re-render the whole component and its children (unless we tell it &lt;a href="https://react.dev/reference/react/useMemo" rel="noopener noreferrer"&gt;not to do so&lt;/a&gt;) with every change. That’s why we cannot make use of our state variables until this process is complete.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Going a little further, bear in mind that when we instruct a state change in a component, &lt;em&gt;React&lt;/em&gt; enqueues this update (along with any other that we might have requested), applies it in the Virtual DOM and finally (through a process called &lt;a href="https://dev.toReconciliation"&gt;Reconciliation&lt;/a&gt;) transmits it to the DOM so we can see the update in our app. Definitely far more complex than just assigning a new value to a variable.&lt;br&gt;
For more information about components state and re-renders, feel free to consult the &lt;a href="https://react.dev/learn/render-and-commit#re-renders-when-state-updates" rel="noopener noreferrer"&gt;docs&lt;/a&gt;! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let me show our code at this point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TestApi&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;services&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;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;ReactElement&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;statefulData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setStatefulData&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;newData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&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="c1"&gt;// The problem here is that React needs some time to re-render our &lt;/span&gt;
     &lt;span class="c1"&gt;// component everytime statefulData is updated (in this case through a &lt;/span&gt;
     &lt;span class="c1"&gt;// hook). For this reason, statefulData is not updated by the time&lt;/span&gt;
     &lt;span class="c1"&gt;// we call TestApi.postData (its value will be `''`), so this       &lt;/span&gt;
     &lt;span class="c1"&gt;// handler needs a fix.&lt;/span&gt;
    &lt;span class="nf"&gt;setStatefulData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;TestApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statefulData&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Click&lt;/span&gt; &lt;span class="nx"&gt;me&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Possible ways out
&lt;/h2&gt;

&lt;p&gt;I believe that there are two paths to have a scenario like this one solved. The correct one depends on what you need to do with your state value once it gets an update.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Removing the state variable
&lt;/h3&gt;

&lt;p&gt;If we are not after re-renders in our component every time the form receives any changes then there is no need for a state variable and we can directly consume our API using the form’s inner data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TestApi&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;services&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;MyImprovedComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;ReactElement&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;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;newData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&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="c1"&gt;// If there is no need for a re-render (and therefore for a state &lt;/span&gt;
    &lt;span class="c1"&gt;// variable), a possible solution is to avoid the use of the hook &lt;/span&gt;
    &lt;span class="c1"&gt;// and simply use the value that we receive from params.&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;TestApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newData&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Click&lt;/span&gt; &lt;span class="nx"&gt;me&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Attaching logic to state changes
&lt;/h3&gt;

&lt;p&gt;If we do want to re-render our component everytime our variable is updated (let’s say we want to show its content on screen) then we need a state variable and, what’s more, we need to add a &lt;em&gt;&lt;a href="https://react.dev/reference/react/useEffect" rel="noopener noreferrer"&gt;useEffect&lt;/a&gt;&lt;/em&gt; hook that gets triggered when our variable is updated to handle this event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TestApi&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;services&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;MyImprovedStatefulComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;ReactElement&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;statefulData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setStatefulData&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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="c1"&gt;// If we need a state variable we have to attach our logic to its updates&lt;/span&gt;
&lt;span class="c1"&gt;// through the useEffect hook This way we will be consuming TestApi only&lt;/span&gt;
&lt;span class="c1"&gt;// when statefulData has been updated.&lt;/span&gt;

  &lt;span class="nf"&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="c1"&gt;// An extra validation here since this callback is not only&lt;/span&gt;
    &lt;span class="c1"&gt;// triggered when statefulData but also when mounting the component. &lt;/span&gt;
    &lt;span class="c1"&gt;// For more information check the docs!&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;statefulData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;TestApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statefulData&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;statefulData&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;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;newData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&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="nf"&gt;setStatefulData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newData&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Click&lt;/span&gt; &lt;span class="nx"&gt;me&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;statefulData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Concluding remarks
&lt;/h2&gt;

&lt;p&gt;The problem solved here was a consequence of bad components’ state management. As &lt;a href="https://www.freecodecamp.org/news/react-lifecycle-methods-and-hooks-for-beginners/" rel="noopener noreferrer"&gt;&lt;em&gt;React&lt;/em&gt; lifecycle stages&lt;/a&gt; were not respected, our component experienced a lag between the data stored in its state and the expected result of an enqueued state update attached to the user’s interaction.&lt;/p&gt;

&lt;p&gt;In conclusion, the use of good practices and the components’ adjustment to the &lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;official &lt;em&gt;React&lt;/em&gt; documentation&lt;/a&gt; is crucial. Correct state management, components’ atomization after SRP (&lt;em&gt;&lt;a href="https://dev.to/mikhaelesa/single-responsibility-principle-in-react-10oc#:~:text=The%20Single%20Responsibility%20Principle%20(SRP,thing%20and%20do%20it%20well.)"&gt;Single Responsibility Principle&lt;/a&gt;&lt;/em&gt;, centralizing logic after DRY (&lt;em&gt;&lt;a href="https://codedamn.com/news/javascript/keeping-your-code-dry-understanding-the-importance-of-not-repeating-yourself-in-javascript" rel="noopener noreferrer"&gt;Don't Repeat Yourself&lt;/a&gt;&lt;/em&gt;) decoupling from external components and the achievement of a highly cohesive internal logic are practices that minimize problems' solving time, lower error rate and allow for stability and scalability in our applications.&lt;/p&gt;




&lt;p&gt;Picture taken from the &lt;a href="https://react.dev/learn/state-as-a-snapshot" rel="noopener noreferrer"&gt;official &lt;em&gt;React&lt;/em&gt; docs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Tuning de conexiones en MongoDB con Serverless Lambda</title>
      <dc:creator>Ignacio Mattos</dc:creator>
      <pubDate>Fri, 10 May 2024 11:55:12 +0000</pubDate>
      <link>https://dev.to/nachosource/tuning-de-conexiones-en-mongodb-con-serverless-lambda-3f50</link>
      <guid>https://dev.to/nachosource/tuning-de-conexiones-en-mongodb-con-serverless-lambda-3f50</guid>
      <description>&lt;h2&gt;
  
  
  Contexto
&lt;/h2&gt;

&lt;p&gt;Luego de una etapa de gestión y mantenimiento manual de una base de datos &lt;em&gt;MongoDB&lt;/em&gt; (nosql) instalada &lt;em&gt;on premise&lt;/em&gt;, se tomó la decisión de comenzar a usar el servicio cloud &lt;a href="https://cloud.mongodb.com/v2/65bb8a1ba4a8dd3d7853256a#/overview" rel="noopener noreferrer"&gt;&lt;em&gt;Mongo Atlas&lt;/em&gt;&lt;/a&gt;. Esto se debió a que el mismo ofrece múltiples ventajas -de las cuales “replication” es la más destacable, ofreciendo la posibilidad de implementar la base de datos en un &lt;em&gt;cluster&lt;/em&gt; de nodos de forma rápida y eficiente. También ofrece buenas herramientas para monitorear tanto la escalabilidad de la base de datos como los estados del &lt;em&gt;cluster&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufc0221m2iph0fqbgva2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufc0221m2iph0fqbgva2.png" alt="Mongo Atlas Monitor" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Problema
&lt;/h2&gt;

&lt;p&gt;Al comenzar a utilizar &lt;em&gt;Mongo Atlas&lt;/em&gt;, se observó que crecía exageradamente el número de conexiones concurrentes abiertas –alcanzando, por ejemplo, picos de &lt;strong&gt;100&lt;/strong&gt; conexiones con un test de carga de solo 5 usuarios simultáneos. Esto derivó en dos escenarios de error:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Escenario en el que el backend (&lt;a href="https://aws.amazon.com/es/lambda/" rel="noopener noreferrer"&gt;&lt;em&gt;AWS Lambda&lt;/em&gt;&lt;/a&gt;) terminaba requests por &lt;em&gt;timeout&lt;/em&gt; debido a problemas de conexión.&lt;/li&gt;
&lt;li&gt;Caída de la base de datos en caso de haber superado el límite de conexiones de ese momento (&lt;strong&gt;500&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Diagnóstico
&lt;/h2&gt;

&lt;p&gt;Tomando como referencia a la documentación de &lt;a href="https://mongoosejs.com/docs/5.x/docs/connections.html" rel="noopener noreferrer"&gt;&lt;em&gt;Mongoose&lt;/em&gt;&lt;/a&gt; y &lt;a href="https://www.serverless.com/framework/docs/providers/aws/guide/functions" rel="noopener noreferrer"&gt;&lt;em&gt;Lambda&lt;/em&gt;&lt;/a&gt; se encuentra que, al estar acotado el parámetro &lt;em&gt;poolSize&lt;/em&gt; de las conexiones a la BD (por defecto &lt;strong&gt;5&lt;/strong&gt;) y al mismo tiempo no definido un tope para la cantidad de containers (instancias) de &lt;em&gt;Lambda Functions&lt;/em&gt; que AWS levanta / crea &lt;em&gt;on-demand&lt;/em&gt;, &lt;strong&gt;AWS está levantando containers arbitrariamente según el tráfico y requests que recibe el servicio&lt;/strong&gt; (a través de &lt;a href="https://aws.amazon.com/es/api-gateway/" rel="noopener noreferrer"&gt;&lt;em&gt;API Gateway&lt;/em&gt;&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;Por otra parte, debido a que la API está desplegada en una sola &lt;em&gt;Lambda&lt;/em&gt; (donde internamente corre un API &lt;a href="https://expressjs.com" rel="noopener noreferrer"&gt;&lt;em&gt;Express&lt;/em&gt;&lt;/a&gt;), todos los requests a diferentes recursos los gestiona un único &lt;em&gt;container&lt;/em&gt;. Por ende, este recibe varios &lt;em&gt;requests&lt;/em&gt; concurrentes y todos son atendidos por un único &lt;em&gt;pool&lt;/em&gt; de conexiones. Dicho de otra manera, cada instancia de &lt;em&gt;Lambda&lt;/em&gt; podrá procesar únicamente &lt;strong&gt;5&lt;/strong&gt; operaciones concurrentes con acceso a base de datos.&lt;/p&gt;

&lt;p&gt;Debido a que AWS no tiene predefinido un tope límite de instancias creadas, estas son creadas a medida que son necesarias para de esta manera “balancear” el tráfico. Por ese motivo, y ya que por cada &lt;em&gt;container&lt;/em&gt; Mongoose está creando un &lt;em&gt;pool&lt;/em&gt; de &lt;strong&gt;5&lt;/strong&gt; conexiones: si AWS levanta 20 &lt;em&gt;containers&lt;/em&gt; vivos, levantamos con &lt;strong&gt;100&lt;/strong&gt; conexiones en &lt;em&gt;Mongo Atlas&lt;/em&gt;, &lt;strong&gt;exponiéndolo a la condición de saturación con la que nos encontramos&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Alcanzar el límite de conexiones del &lt;em&gt;cluster&lt;/em&gt; puede afectar el rendimiento y la disponibilidad de la base de datos o, en el peor de los casos, generar una caída en el servidor, requiriendo un reinicio manual.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solución
&lt;/h2&gt;

&lt;p&gt;Ya que el &lt;em&gt;pool&lt;/em&gt; de conexiones al &lt;em&gt;cluster&lt;/em&gt; es proporcional a la cantidad de &lt;em&gt;containers&lt;/em&gt; creados por AWS, se decidió poner un límite al número de &lt;em&gt;containers&lt;/em&gt; vivos que pueden existir. Para este caso definimos un máximo de &lt;strong&gt;20&lt;/strong&gt; instancias a través de la opción &lt;a href="https://docs.aws.amazon.com/lambda/latest/operatorguide/reserved-concurrency.html" rel="noopener noreferrer"&gt;&lt;em&gt;reservedConcurrency&lt;/em&gt;&lt;/a&gt; en nuestro archivo &lt;code&gt;serverless.yml&lt;/code&gt; para configurar el &lt;em&gt;serverless&lt;/em&gt; framework.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;functions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;&amp;lt;api_name&amp;gt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;reservedConcurrency&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
      &lt;span class="na"&gt;memorySize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1536&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Asimismo y tomando en consideración este parámetro buscamos un valor para &lt;em&gt;poolSize&lt;/em&gt; que nos permitiera tener el mayor número de conexiones en el &lt;em&gt;pool&lt;/em&gt; disponible sin superar el límite del cluster: &lt;em&gt;20 x 24 = &lt;strong&gt;480&lt;/strong&gt;&lt;/em&gt; parece un escenario más conservador y, al mismo tiempo, más eficiente en el uso de los recursos. De la siguiente manera configuramos la conexión a la base desde nuestra API &lt;em&gt;Express&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mongodbUri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;poolSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; 
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Otra configuración viable podría ser 30 x 16; léase, &lt;strong&gt;30&lt;/strong&gt; instancias máximo de containers Lambdas x &lt;strong&gt;16&lt;/strong&gt; conexiones reservadas en pool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Monitoreo y conclusión
&lt;/h2&gt;

&lt;p&gt;Luego de las medidas tomadas, no se observaron picos en la apertura de conexiones con lo cual se concluye que la solución fue efectiva.&lt;/p&gt;

&lt;p&gt;Es igualmente recomendable darle un seguimiento al &lt;em&gt;performance&lt;/em&gt; del &lt;em&gt;cluster&lt;/em&gt; de la base de datos, observando las estadísticas de conexiones y gestionando alertas para casos en los que dicho número de conexiones se acerque a las &lt;strong&gt;480&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;En lo que concierne al API, es a su vez recomendable observar y buscar errores &lt;em&gt;&lt;strong&gt;5xx&lt;/strong&gt;&lt;/em&gt; dentro de &lt;em&gt;API Gateway&lt;/em&gt; y configurar alertas en caso de que sean persistentes en un corto período de tiempo (&lt;em&gt;downtime&lt;/em&gt;).&lt;/p&gt;




&lt;p&gt;Quiero agradecer a &lt;a class="mentioned-user" href="https://dev.to/frangeris"&gt;@frangeris&lt;/a&gt;  por su colaboración y aportes en el diagnóstico y la construcción de una solución acorde al escenario en cuestión, así como también en su documentación posterior.&lt;/p&gt;

&lt;p&gt;Imagen del encabezado tomada de Nick Van Hook (2020). &lt;a href="https://blog.ordina-jworks.io/cloud/2020/02/19/Combining-MongoDB-and-AWS-Lambda.html" rel="noopener noreferrer"&gt;&lt;em&gt;"Marrying Mongodb Atlas and AWS Lambda."&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>mongodb</category>
      <category>node</category>
    </item>
    <item>
      <title>Organizing your React code: Cohesion and Coupling</title>
      <dc:creator>Ignacio Mattos</dc:creator>
      <pubDate>Fri, 06 Jan 2023 12:25:15 +0000</pubDate>
      <link>https://dev.to/cloudx/organizing-your-react-code-cohesion-and-coupling-579</link>
      <guid>https://dev.to/cloudx/organizing-your-react-code-cohesion-and-coupling-579</guid>
      <description>&lt;p&gt;Have you ever needed to spend a considerable amount of time reviewing your own code (written just a couple of months ago) or been assigned to a new project just to find a pile of messy and eternal files?&lt;/p&gt;

&lt;p&gt;I'm sure we've all had the feeling that a fix that took a day could've been solved in a fraction of that time by only having the code a little more organized.&lt;/p&gt;

&lt;p&gt;Consequences of spaghetti code are usually spending days instead of hours solving problems, code repetition, inconsistencies between behaviors that should work the same way, inaccurate estimations and, of course, some headaches.&lt;/p&gt;

&lt;p&gt;In this series I’ll try to share some notions that help me when it comes to designing clean and maintainable components, architecture and logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cohesion and coupling
&lt;/h2&gt;

&lt;p&gt;These two are key concepts that will go along with you wherever you code, leaving aside the particular language or framework you work with. Since they've already been explained way better than I could do here and now, I'm only talking about the core concept.&lt;/p&gt;

&lt;p&gt;Imagine that your web has a couple of pages that share a component. Let's also say this component has a basic behaviour: a button that requests some data from an API, formats it and stores it, but this process slightly varies in each case.&lt;/p&gt;

&lt;p&gt;It's easy to see that we are going to reuse at least a part of our code, keeping in mind that our goal is to have as little code as possible (we'll return to this later). The point is, which is going to be our criteria here? Is there a standard to conform to when designing our reusable component? The golden rule is: &lt;em&gt;the greatest cohesion, the lowest coupling&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What does this mean? Said in a few words, &lt;em&gt;cohesion&lt;/em&gt; is related with the criteria that gathers the inside elements of your component, while &lt;em&gt;coupling&lt;/em&gt; has to do with the external relations established between your component and the environment in which it is used (I mean, everything else). And let me just add that, as we have a components tree, these concepts are to be transported to wherever you want, from less to more abstract.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For more info about this topic &lt;a href="https://betterprogramming.pub/coupling-cohesion-552b022492b2" rel="noopener noreferrer"&gt;&lt;em&gt;have a read&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why do we want our components to be &lt;em&gt;cohesive&lt;/em&gt; and &lt;em&gt;decoupled&lt;/em&gt;?
&lt;/h3&gt;

&lt;p&gt;The stronger relation you achieve between your inside elements, the more definite and accurate the identity of your component is. The more abstracted you keep from the external requirements, the freer you get to reuse and adapt your components to different situations.&lt;/p&gt;

&lt;p&gt;Should I declare every single behavior the button might have when handling the click? Seems we could get a handler from our &lt;code&gt;props&lt;/code&gt;, &lt;em&gt;decoupling&lt;/em&gt; our logic from the one depending on foreign elements. Are you sure it's clean to fill your component with &lt;code&gt;if&lt;/code&gt;s to validate what to render or not according to every possible use case? Let's have a simple one-job component as external logic is out of our scope  since it is inside another component's one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Have you heard about the &lt;a href="https://www.geeksforgeeks.org/how-to-use-single-responsibility-principle-in-reactjs/" rel="noopener noreferrer"&gt;&lt;em&gt;single-responsibility&lt;/em&gt;&lt;/a&gt; principle?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let me share a simple example so we can figure this out:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isHeader&lt;/span&gt; &lt;span class="o"&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;isFooter&lt;/span&gt; &lt;span class="o"&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;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;headerTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isHeader&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyHeader&lt;/span&gt;&lt;span class="dl"&gt;"&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;footerTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isFooter&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyFooter&lt;/span&gt;&lt;span class="dl"&gt;"&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;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isHeader&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;200px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lighter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;500px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClickHeader&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Getting header's data from API.&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;handleClickFooter&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Getting footer's data from API.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&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;isHeader&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;headerTitle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isHeader&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;headerClickHandler&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;footerClickHandler&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;Click&lt;/span&gt; &lt;span class="nx"&gt;Me&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isFooter&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;footerTitle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we said, in these two scenarios the components' behaviour is similar. We can find differences in the &lt;code&gt;button&lt;/code&gt;'s &lt;em&gt;callback&lt;/em&gt;, in the &lt;code&gt;labels&lt;/code&gt;' content and in the subcomponents' order and styles, but the core idea of the component is the same for both cases.&lt;/p&gt;

&lt;p&gt;Besides, it's bothering to see that the component is full of validations that adjust what the component renders and does according to the &lt;code&gt;props&lt;/code&gt;' values. This means the component is coupled to the context's needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Doing it better 😃
&lt;/h3&gt;

&lt;p&gt;As all of this can be parameterized without losing the component's identity, we are going to extract the contextual logic to achieve a simpler and more compact component that only does what it's meant to.&lt;/p&gt;

&lt;p&gt;Following this same logic, we end up generating a few more components that gather their own specific logic (including a parent &lt;code&gt;Container&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&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;Click&lt;/span&gt; &lt;span class="nx"&gt;Me&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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;Header&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;headerStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;200px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;headerTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyHeader&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;headerTitle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyComponent&lt;/span&gt;
                &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;headerStyles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Footer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Getting header's data from API.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}}&lt;/span&gt;
            &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Footer&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;footerStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lighter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;500px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;footerTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyFooter&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyComponent&lt;/span&gt;
                &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;footerStyles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Footer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Getting footer's data from API.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}}&lt;/span&gt;
            &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;footerTitle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Container&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Footer&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;But hey! Didn't I say one of our targets is to have less code? 🤔 Why do we have a larger amount lines in the&lt;br&gt;
second snippet?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well the point here isn't only the code you use to define your components, but also the potential repetition you are avoiding by having a reusable example that can adapt to different situations and be upgraded if your requirements change.&lt;/p&gt;

&lt;p&gt;In the next post, I am going to share a few tips that help me organize my files.&lt;/p&gt;

&lt;p&gt;But if this didn't move you to review your programming habits, check this out: the person on the left is a responsible developer who follows the best practices and makes an effort to improve his code's legibility when he has the chance.&lt;br&gt;
The one on the right is his twin brother, who thinks it’s fine to &lt;em&gt;copy&amp;amp;paste&lt;/em&gt; the same logic over and over again and concentrate his code in a few files.&lt;br&gt;
Choose your cards wisely!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9py5u30wd7vyj2x9vttt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9py5u30wd7vyj2x9vttt.png" alt="people" width="800" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>An alternative way to integrate with Slack using Node-RED</title>
      <dc:creator>Ignacio Mattos</dc:creator>
      <pubDate>Thu, 27 May 2021 20:04:38 +0000</pubDate>
      <link>https://dev.to/cloudx/an-alternative-way-to-integrate-with-slack-using-node-red-4m7k</link>
      <guid>https://dev.to/cloudx/an-alternative-way-to-integrate-with-slack-using-node-red-4m7k</guid>
      <description>&lt;p&gt;Do you want to make an integration with &lt;em&gt;Slack&lt;/em&gt;?&lt;br&gt;
Do you already know &lt;a href="https://nodered.org/" rel="noopener noreferrer"&gt;&lt;em&gt;Node-RED&lt;/em&gt;&lt;/a&gt; but the solutions that appear in the documentation and the tutorials are not working?&lt;/p&gt;

&lt;p&gt;I’ve been there and I passed through that.&lt;/p&gt;
&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Pros and cons using &lt;em&gt;Node-RED&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Using a simpler node&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id="context"&gt;Context&lt;/h2&gt;

&lt;p&gt;A few weeks ago I started working in a &lt;em&gt;Slack&lt;/em&gt; chatbot which should answer some questions. The idea was good and the tool that was suggested to me to solve this - we talk about &lt;em&gt;Node-RED&lt;/em&gt; - has a lot of examples on the web where it actually works.&lt;br&gt;
But for some reason they didn’t work for me. I don’t know if the solutions proposed on the web are outdated or if I’ve been missing something important (of course this is something probable). The thing here is that, as developers, we are supposed to either reuse or to create new solutions.&lt;/p&gt;

&lt;p&gt;And after a while, I finally managed to connect with the Slack API, but not in the way it was supposed to according to the doc.&lt;/p&gt;

&lt;p&gt;In this post I’m going to show you how I solved this out hoping this might be reusable for other similar scenarios.&lt;/p&gt;

&lt;h2 id="p&amp;amp;c"&gt;Pros and cons using &lt;em&gt;Node-RED&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Something really helpful about &lt;em&gt;Node-RED&lt;/em&gt; is that it’s really worth it as it saves a lot of time that you would spend writing down every function you need. There’s a pile of useful nodes that facilitate the integration with external APIs.&lt;/p&gt;

&lt;p&gt;The problem is that once you let the app manage your code, you’ll start wondering what is actually occurring and how things happen.&lt;br&gt;
Leaving aside the annoying or not this could be, the big problem will show as the bugs appear and you don’t know what the node function is doing, so it is double tedious to fix them.&lt;br&gt;
I mean, it is a problem to don’t know if you are missing a semicolon or if the auth token is wrong.&lt;/p&gt;

&lt;p&gt;That is exactly what happened and what pushed me to find an alternative solution to &lt;a href="https://flows.nodered.org/node/node-red-contrib-slack" rel="noopener noreferrer"&gt;&lt;em&gt;slack-rm&lt;/em&gt; node&lt;/a&gt; or the &lt;a href="https://flows.nodered.org/node/node-red-contrib-slackbot" rel="noopener noreferrer"&gt;&lt;em&gt;slackbot listen&lt;/em&gt;&lt;/a&gt;, which were the ones proposed everywhere I searched for.&lt;/p&gt;

&lt;h2 id="simplerNode"&gt;Using a simpler node&lt;/h2&gt;

&lt;p&gt;There’s a node called &lt;em&gt;http in&lt;/em&gt; which listens to API calls. The advantage of using this one is that we can directly test the endpoint services using either &lt;strong&gt;curl&lt;/strong&gt; or &lt;strong&gt;postman&lt;/strong&gt;. This lets you know if you have an error in the request, I mean, before adding some logic.&lt;/p&gt;

&lt;p&gt;Let me show you how to set it up:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fypeif5lb6gpy8w9m9yuo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fypeif5lb6gpy8w9m9yuo.png" alt="Alt Text" width="510" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can test this from outside the app with the &lt;strong&gt;debug&lt;/strong&gt; node, using &lt;code&gt;curl -X POST http://localhost:1880/postmessage&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The next step here is using a &lt;em&gt;function&lt;/em&gt; node, in which we’ll set the headers and body of the request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BOT_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xoxb-...&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;CHANNEL_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_channel_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BOT_TOKEN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json; charset=utf-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;channel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CHANNEL_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is finally working&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;msg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll find the &lt;strong&gt;BOT_TOKEN&lt;/strong&gt; in &lt;a href="https://api.slack.com/apps" rel="noopener noreferrer"&gt;Slack apps settings&lt;/a&gt;. But the &lt;strong&gt;CHANNEL_ID&lt;/strong&gt; is something that you’ll be able to obtain after reading this post ;)&lt;/p&gt;

&lt;p&gt;After setting this up, we can send a request to the &lt;a href="https://api.slack.com/methods" rel="noopener noreferrer"&gt;&lt;em&gt;Slack&lt;/em&gt; API&lt;/a&gt;. If you didn’t do this yet, remember that you must set your bot’s permissions to let it use the API methods. Otherwise, no method will work.&lt;/p&gt;

&lt;p&gt;For this use the &lt;em&gt;http request node&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0zu628h5v12z4avq31n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0zu628h5v12z4avq31n.png" alt="Alt Text" width="514" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, we add the &lt;em&gt;http response&lt;/em&gt; node so we can have the response in the console.&lt;br&gt;
The complete flow should seem like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnc6gpzz3aexxatpqnint.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnc6gpzz3aexxatpqnint.png" alt="Alt Text" width="800" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After calling the endpoint we should receive the response in the bot chat as a formatted &lt;strong&gt;“This is finally working”&lt;/strong&gt; message. To change that, you only need to modify the &lt;strong&gt;text&lt;/strong&gt; at the request body, either in the app or in the call.&lt;/p&gt;

&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This is just a very first step in the general task, but I wanted to share it because I think that &lt;em&gt;Node-RED&lt;/em&gt; is a good tool to make integrations with external APIs, but also it can get confusing when tuning it in at first.&lt;/p&gt;

&lt;p&gt;I think that something useful after this example is that, most of the time, I guess I’d rather have smaller functions that make it clear to see what I am doing instead of using those in which we can’t see the code in the back but should solve the problems at once.&lt;/p&gt;




&lt;p&gt;I'd like to thank to &lt;a class="mentioned-user" href="https://dev.to/lucasota"&gt;@lucasota&lt;/a&gt; and &lt;a class="mentioned-user" href="https://dev.to/navarroaxel"&gt;@navarroaxel&lt;/a&gt; for the tips and the reviews which have been helping me to improve my posts.&lt;/p&gt;

</description>
      <category>nodered</category>
      <category>javascript</category>
      <category>slack</category>
      <category>chatbot</category>
    </item>
    <item>
      <title>What you should know about Reactjs if you are a mobile developer</title>
      <dc:creator>Ignacio Mattos</dc:creator>
      <pubDate>Tue, 11 May 2021 17:07:46 +0000</pubDate>
      <link>https://dev.to/cloudx/what-you-should-know-about-reactjs-if-you-are-a-mobile-developer-44lc</link>
      <guid>https://dev.to/cloudx/what-you-should-know-about-reactjs-if-you-are-a-mobile-developer-44lc</guid>
      <description>&lt;p&gt;If you are a Mobile developer, it is very likely that, at some point, you will be asked to switch to web development, or even to develop an hybrid app.&lt;br&gt;
Has this already happened to you? You surely have noticed that there are a few differences between each type of app that you should consider before facing a new web project.&lt;/p&gt;

&lt;p&gt;In this post I’ll try to show some of those differences as we can see the similarities we can find among them.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The great similarities between this two tools are most related with the fact that &lt;em&gt;React Native&lt;/em&gt; is a framework that implements &lt;em&gt;Reactjs&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lhrk8ktmej9m209429h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lhrk8ktmej9m209429h.jpg" alt="Alt Text" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  Some of the main diffs
&lt;/h2&gt;

&lt;p&gt;These are some of the most visible things you’ll notice at first glance once you switch to &lt;em&gt;Reactjs&lt;/em&gt;. &lt;br&gt;
However, I’m not making the deepest possible comparison here, so some of you guys will probably find a more consistent way to make an intensive comparison.&lt;/p&gt;

&lt;p&gt;Anyway, I think you will find some of these points quite useful.&lt;/p&gt;

&lt;p&gt;At first, something important here is that, as &lt;em&gt;React Native&lt;/em&gt; is a &lt;a href="https://sofienebk.medium.com/what-is-the-difference-between-a-framework-and-library-2b712a1a1c41" rel="noopener noreferrer"&gt;&lt;em&gt;framework&lt;/em&gt;&lt;/a&gt;, you should have almost everything you need to develop an app from scratch in it. This is something that won’t happen with &lt;em&gt;Reactjs&lt;/em&gt;, which is just a &lt;em&gt;JS&lt;/em&gt; library. &lt;/p&gt;

&lt;p&gt;What does it mean? Basically in &lt;em&gt;React Native&lt;/em&gt; you use some features and components that are integrated with the framework and are not able outside it.&lt;br&gt;
For example, in &lt;em&gt;RN&lt;/em&gt; you use react-navigation to switch between your app screens, which is something that we won't have in &lt;em&gt;Reactjs&lt;/em&gt;, so it may be replaced by the implementation of &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;&lt;em&gt;Nextjs&lt;/em&gt;&lt;/a&gt; and its router.&lt;br&gt;
Or remember the &lt;code&gt;&amp;lt;FlatList&amp;gt;&lt;/code&gt; component? That is also a &lt;em&gt;RN&lt;/em&gt; component, so we'll need to use a Map instead. &lt;/p&gt;

&lt;p&gt;However, I didn’t say that external libraries implementation was forbidden or something. Even more, something that won't happen in &lt;em&gt;Reactjs&lt;/em&gt; is that, unlike &lt;em&gt;RN&lt;/em&gt;, the components style won't differ according to the OS nor the platform they are rendered in.&lt;/p&gt;

&lt;p&gt;And that's the point where you'll be pleased to know that there are some Component Libraries like &lt;em&gt;Chakra&lt;/em&gt;, &lt;em&gt;Bootstrap&lt;/em&gt; and &lt;a href="https://www.codeinwp.com/blog/react-ui-component-libraries-frameworks/" rel="noopener noreferrer"&gt;&lt;em&gt;many others&lt;/em&gt;&lt;/a&gt; you might have met in mobile development that, combined with some &lt;a href="https://reactjs.org/docs/introducing-jsx.html" rel="noopener noreferrer"&gt;&lt;em&gt;JSX&lt;/em&gt;&lt;/a&gt;, will allow you to display your web app quickly.&lt;/p&gt;
&lt;h3&gt;
  
  
  The components
&lt;/h3&gt;

&lt;p&gt;Another thing you should know is that, unlike &lt;em&gt;React Native&lt;/em&gt;, &lt;em&gt;Reactjs&lt;/em&gt; uses a virtual DOM that compiles your &lt;em&gt;javascript&lt;/em&gt; code to &lt;em&gt;HTML&lt;/em&gt; and renders the app.&lt;br&gt;
This doesn’t happen in &lt;em&gt;RN&lt;/em&gt;: here you don’t have a thing like a DOM, and the &lt;em&gt;React-Native&lt;/em&gt; components are formed only by &lt;em&gt;JSX&lt;/em&gt;.&lt;br&gt;
You will notice that &lt;em&gt;HTML&lt;/em&gt; thing when you try to debug your app in the browser, so if you have skipped the basics, it is time to start reading.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In &lt;em&gt;Reactjs&lt;/em&gt;, for example, you won’t have a &lt;code&gt;&amp;lt;View&amp;gt;&lt;/code&gt; component, so you should learn what a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; is.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mwpa2ui21qiz3fdgu1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mwpa2ui21qiz3fdgu1y.png" alt="Alt Text" width="800" height="549"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The styling
&lt;/h3&gt;

&lt;p&gt;What happens with the &lt;em&gt;CSS&lt;/em&gt;? Are you used to the &lt;em&gt;React Native&lt;/em&gt; &lt;em&gt;StyleSheet&lt;/em&gt; class? Forget about it, it won’t accompany you anymore in &lt;em&gt;Reactjs&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is how you style a component using a &lt;em&gt;React Native&lt;/em&gt; StyleSheet class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="nx"&gt;A287&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="na"&gt;decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;none&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;View&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&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;This&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="nx"&gt;Native&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/View&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;And &lt;em&gt;this is the way&lt;/em&gt; you will do the same using basic &lt;em&gt;CSS&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="nx"&gt;A287&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;none&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 must be imported from the &lt;code&gt;.css&lt;/code&gt; file to be able to use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../styles/Home.module.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&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;This&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;Reactjs&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  Are you wishing to start a web app yet or what?
&lt;/h2&gt;

&lt;p&gt;As you can see, it is not that difficult to switch to web development if you’ve learned the basics of &lt;em&gt;React&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Even the hardest issues are a matter of time until you get used to some new practices.&lt;/p&gt;

&lt;p&gt;If it’s helpful to say it, when I started programming in &lt;em&gt;React Native&lt;/em&gt;, it was very nice to avoid downloading an intricate and annoying emulator to run my code. As you are going to work with a browser, the only thing you'll have to think about is where to put your &lt;code&gt;console.log&lt;/code&gt;’s: no &lt;em&gt;Reload&lt;/em&gt; button, no external programs and no native APIs.&lt;/p&gt;

&lt;p&gt;So, if you think there is no such big deal to replace a &lt;code&gt;View&lt;/code&gt; by a &lt;code&gt;div&lt;/code&gt;, I hope I can see the progress of some React engineers here! ;)&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>mobile</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My first month as an intern mobile developer</title>
      <dc:creator>Ignacio Mattos</dc:creator>
      <pubDate>Fri, 15 Jan 2021 13:33:02 +0000</pubDate>
      <link>https://dev.to/cloudx/my-first-month-as-an-intern-mobile-developer-11bi</link>
      <guid>https://dev.to/cloudx/my-first-month-as-an-intern-mobile-developer-11bi</guid>
      <description>&lt;p&gt;Well, I have to say that this is not only the first time I write about my job: this is the very first time I write a post, so I think this is the best way to get along with the situation that I’ve got here.&lt;/p&gt;

&lt;p&gt;I’m an Argentinian 21 years old beginner developer, and this is directed to those young developers who don’t know if they are capable of start working on what they like to do.&lt;/p&gt;

&lt;p&gt;I started an internship as a JavaScript developer last December. My previous work had no relation with the IT world and I was trying to get out of it and find a place where I could upgrade my skills or at least do something cool.&lt;/p&gt;

&lt;p&gt;First of all, I have to tell you that my very first time with a code line was at school, where I had my introduction to backend development and I had to construct a few desktop applications. &lt;/p&gt;

&lt;p&gt;So, am I a beginner or not? The truth is, after I finished high school, I’ve started college and began to work in a lot of different places, but none of them were related to IT, so everything is more like a new beginning for someone that is not used to programming anymore.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcd7mq4l7n5g0xk08502s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcd7mq4l7n5g0xk08502s.png" alt="Alt Text" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Joining a team
&lt;/h1&gt;

&lt;p&gt;It’s been just one month working at &lt;code&gt;Cloud(x);&lt;/code&gt; and the most important thing that I have to say is that there is no way that someone can just imagine the difference between developing at home or in a school project and doing it for work.&lt;/p&gt;

&lt;p&gt;I’m not saying that this is a nightmare or something similar. Far away from that, you will be happy to join a team formed by experienced people who have passed through your current situation and who can show you all those mistakes that would have taken you hours of headaches and sleepless nights.&lt;/p&gt;

&lt;p&gt;Obviously, nobody is ever going to bring you the definitive solution that will fix all your bugs and tell you what to do line by line. But it’s always better to have someone to ask for help when those YouTube solutions are not working.&lt;/p&gt;

&lt;h1&gt;
  
  
  First steps, getting stuck and… what’s next?
&lt;/h1&gt;

&lt;p&gt;As I told you before, my academic previous experience had no relation with almost anything that I’m doing right now. Linux, React Native, Redux and even Git were such unknown stuff to me, and it wasn’t easy to catch up with all these new tech, neither with the app that my actual team has developed up to now.&lt;/p&gt;

&lt;p&gt;But you know what? That is the best thing that could have happened to me right now. I’m learning a lot of new things every single day, and it’s not that bad to get stuck all the time while this is useful to keep my brain working hard.&lt;/p&gt;

&lt;p&gt;Step by step, everything is getting easier as I get able to develop higher solutions to bigger problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa2b3cgrgaup3nxbiz4kg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa2b3cgrgaup3nxbiz4kg.jpg" alt="Alt Text" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From now on...
&lt;/h2&gt;

&lt;p&gt;If I have to give advice to those people who are trying to get an IT job, I think this would be that you shouldn’t be afraid of getting stuck or not knowing what to do. That’s the funny thing in here and the one that makes the difference between this and any other job: the point is that you can learn a new thing every time you solve a problem.&lt;/p&gt;

&lt;p&gt;So get along with the idea of you passing through hard times sometimes but with a high comfort once you understand what is going on with your code and what you will need to do next time.&lt;/p&gt;

&lt;p&gt;Make sure you have a clear idea of what you want to do -I mean, in which area would you like to begin working at- and, if you don’t know it yet, good news! Software development needs more people everywhere.&lt;/p&gt;

&lt;p&gt;One last thing! If this isn’t your first language, I recommend you to start practicing your English with a mirror because you’ll need to communicate with people from all over the world and guess what, you won’t be able to use smoke signals or something.&lt;/p&gt;

&lt;p&gt;As I’m just starting in this, I would like to read about your experiences as beginner developers too! &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>reactnative</category>
      <category>mobile</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
