<?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: jesuscovam</title>
    <description>The latest articles on DEV Community by jesuscovam (@jesuscovam).</description>
    <link>https://dev.to/jesuscovam</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%2F213751%2F9a29eaa4-bee3-404a-8a02-282949a54d26.png</url>
      <title>DEV Community: jesuscovam</title>
      <link>https://dev.to/jesuscovam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jesuscovam"/>
    <language>en</language>
    <item>
      <title>React Parallax effect with Framer-Motion</title>
      <dc:creator>jesuscovam</dc:creator>
      <pubDate>Sun, 04 Apr 2021 18:13:42 +0000</pubDate>
      <link>https://dev.to/jesuscovam/react-parallax-effect-with-framer-motion-1mhd</link>
      <guid>https://dev.to/jesuscovam/react-parallax-effect-with-framer-motion-1mhd</guid>
      <description>&lt;p&gt;Let's recreate the example from &lt;a href="https://usehooks.com/useOnScreen/"&gt;https://usehooks.com/useOnScreen/&lt;/a&gt; but adding framer-motion for a parallax effect&lt;/p&gt;

&lt;p&gt;The first thing will be installing the packages. For simplicity, I'm going to use the react-intersection-observer, that uses the IntersectionObserver API.&lt;/p&gt;

&lt;h2&gt;
  
  
  install
&lt;/h2&gt;



&lt;p&gt;&lt;code&gt;npm i framer-motion react-intersection-observer&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The first look at our component will be 2 divs with a hight of 100vh each, and any background you like to make a differentiation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function Home() {

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div style={{ height: "100vh" }}&amp;gt;
        &amp;lt;h1&amp;gt;Scroll down to next section 👇&amp;lt;/h1&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div style={{ height: "100vh", backgroundColor: "#23cebd" }}&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add the div with an image that we'd like to see move when we scroll it into the viewport.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//* everything until here is the same *//
&amp;lt;div style={{ height: "100vh", backgroundColor: "#23cebd" }}&amp;gt;
  &amp;lt;div style={{ marginLeft: "50px" }}&amp;gt;
    &amp;lt;h1&amp;gt;Hey I'm on the screen&amp;lt;/h1&amp;gt;
    &amp;lt;img style={{ borderRadius: "30px" }}
      alt="ralph from the simpsons waving his hand"
      src="https://i.giphy.com/media/ASd0Ukj0y3qMM/giphy.gif"
    /&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the moment is a static image, we want it to appear when as a DOM element enters in the screen. For that we are going to use &lt;strong&gt;react-intersection-observer&lt;/strong&gt;, let's update our code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useInView } from "react-intersection-observer";

export default function Home() {
  const [ref, isVisible] = useInView({ threshold: 0.7 });
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div style={{ height: "100vh" }}&amp;gt;
        &amp;lt;h1&amp;gt;Scroll down to next section 👇&amp;lt;/h1&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div ref={ref} style={{ height: "100vh", backgroundColor: "#23cebd" }}&amp;gt;
        {isVisible &amp;amp;&amp;amp; (
          &amp;lt;div style={{ marginLeft: "50px" }}&amp;gt;
            &amp;lt;h1&amp;gt;Hey I'm on the screen&amp;lt;/h1&amp;gt;
            &amp;lt;img
              style={{ borderRadius: "30px" }}
              alt="ralph from the simpsons waving his hand"
              src="https://i.giphy.com/media/ASd0Ukj0y3qMM/giphy.gif"
            /&amp;gt;
          &amp;lt;/div&amp;gt;
        )}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the useInView will manage the communication with the IntersectionObserver API, we'll take from it the ref to be placed on the DOM element we want to observe and a boolean value for us to use. It will only take a threshold or a rootMargin, any of those will work and the propuse is to decide how much % of the DOM element we want to scroll before switching the isVisible boolean from false to true, in this case we wrote 0.7 that's equivalent to 70% of the DOM element has to be on screen to change our boolean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bringing framer-motion
&lt;/h2&gt;

&lt;p&gt;For the moment our element is just appearing on the screen, that could be rude. Let's update our code to make it slide from the left.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useInView } from "react-intersection-observer";
import { motion } from "framer-motion";

export default function Home() {
  const [ref, isVisible] = useInView({ threshold: 0.7 });
  const variants = {
    visible: {
      opacity: 1,
      x: 0,
    },
    hidden: {
      opacity: 0,
      x: -100,
    },
  };
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div style={{ height: "100vh" }}&amp;gt;
        &amp;lt;h1&amp;gt;Scroll down to next section 👇&amp;lt;/h1&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div style={{ height: "100vh", backgroundColor: "#23cebd" }}&amp;gt;
        &amp;lt;motion.div
          ref={ref}
          variants={variants}
          animate={isVisible ? "visible" : "hidden"}
          transition={{ duration: 0.5, ease: "easeOut" }}
          style={{ marginLeft: "50px" }}
        &amp;gt;
          &amp;lt;h1&amp;gt;Hey I'm on the screen&amp;lt;/h1&amp;gt;
          &amp;lt;img
            style={{ borderRadius: "30px" }}
            alt="ralph from the simpsons waving his hand"
            src="https://i.giphy.com/media/ASd0Ukj0y3qMM/giphy.gif"
          /&amp;gt;
        &amp;lt;/motion.div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would be the whole example, we did one important change besides adding the framer-motion code, changing the ref from the div with the 100vh to the div that wraps the text and the image we want to slide in.&lt;/p&gt;

&lt;p&gt;Thank you for your time&lt;br&gt;
My name is Jesus Cova, I'm a full-stack developer based in Quintana Roo, México.&lt;/p&gt;

</description>
      <category>framer</category>
      <category>react</category>
    </item>
    <item>
      <title>My JavaScript experience</title>
      <dc:creator>jesuscovam</dc:creator>
      <pubDate>Sun, 04 Apr 2021 01:42:46 +0000</pubDate>
      <link>https://dev.to/jesuscovam/my-javascript-experience-3df0</link>
      <guid>https://dev.to/jesuscovam/my-javascript-experience-3df0</guid>
      <description>&lt;p&gt;JavaScript is a unique language in the history of programming languages, it has never been a language that would return so much opportunity for a developer to master. You can find a job in almost any tech area with it, here I'll lay down the paths I took that worker the best for my environment.&lt;/p&gt;

&lt;p&gt;FrontEnd(UI) 📱 : There are multiples libraries in JavaScript for making user interfaces. I started with Vue.js, but it didn't take me much time to switch to React.js, the reason behind this change was the market opportunity for React is bigger, and Next.js (a meta framework on top of React) makes you look so good with little effort, AND the biggest JS community for mobile native development is also written in React, React Native.&lt;/p&gt;

&lt;p&gt;Backend 🛠 : I do backend serverless, which means I don't rent a server to write code in it, I just focus on my business logic and ship that code to AWS, then expose over a GraphQL API, with App Sync, and use other services to give full security to my apps, like Authentication, Object storages, etc. The key difference is that as I am a single developer for most of my projects, I get to delegate the maintenance of the servers to a company for a really good price, and I just get to write the code that makes the apps work.&lt;/p&gt;

&lt;p&gt;Extra👽 : There's also worth the effort to do geeky stuff with the options in the language, recently the JavaScript ecosystem is going to a better and faster compile direction, and services like Svelte are great to keep an eye on, also Deno, an alternative to Node (our main language for backend in JavaScript).&lt;/p&gt;

&lt;p&gt;Conclusion 🔚 : JavaScript is ultra-friendly, the language has evolved in something reliable, there are a lot of opportunities and you just have to choose in an area that you like the most to specialize, I would open up that for the last year I mainly focus on learning to ship fast and big codebases, so I focused a lot on services like GraphQL, Next.js and AWS to faster my development process, but I lacked expressiveness on UI, so I'm looking forward get better at my CSS animations and transitions, I just prioritized the other for a time as I mostly do the full-stack role.&lt;/p&gt;

&lt;p&gt;full image&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sCdFXycq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vdz5l6lq9olx859s5vpi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sCdFXycq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vdz5l6lq9olx859s5vpi.png" alt="banner"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mi error al usar Cognito (AWS).</title>
      <dc:creator>jesuscovam</dc:creator>
      <pubDate>Tue, 30 Mar 2021 02:31:24 +0000</pubDate>
      <link>https://dev.to/jesuscovam/mi-error-al-usar-cognito-aws-1hpl</link>
      <guid>https://dev.to/jesuscovam/mi-error-al-usar-cognito-aws-1hpl</guid>
      <description>&lt;p&gt;TL;DR: no uses &lt;code&gt;window.localStorage.clear()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;He invertido mucho tiempo en un proyecto con GraphQL donde la autenticación es manejada con Cognito, pero la base del proyecto solo se fundamentó en usar login con correo, nunca me tomé la molestia de hacer OAuth (porque nunca lo había hecho y ya tuve bastantes batallas con la documentación de Amplify por mi propia cuenta siendo primerizo con este backend).&lt;/p&gt;

&lt;p&gt;Usar autenticación con Cognito y GraphQL es excelente si utilizas la API de App Sync también, te permite ponerle un candado personalizado a la API por default, luego escogiendo cuales tablas de la base de datos tienen acceso público y cuáles tienen acceso solo con login.&lt;/p&gt;

&lt;h1&gt;
  
  
  Como lidiar con OAuth y Cognito
&lt;/h1&gt;

&lt;p&gt;Como todo el tiempo de desarrollo previo no tuve la necesidad de usar un link que sacará a los usuarios del proyecto, nunca me vi en la necesidad de usar la &lt;code&gt;localStorage&lt;/code&gt;, con GraphQL me bastaba conseguir la información que necesitaba para que la página en ruta funcionara. &lt;strong&gt;Pero&lt;/strong&gt; cuando agregué OAuth con Google, el usuario sale de tu proyecto y luego regresa a tu ruta inicial &lt;code&gt;/&lt;/code&gt;, (al menos porque el URI de return según Google, no puede tener un /, es decir esto &lt;a href="http://www.ejemplo.com/checkLogin"&gt;www.ejemplo.com/checkLogin&lt;/a&gt; ❌, solo esto &lt;a href="http://www.ejemplo.com"&gt;www.ejemplo.com&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Entonces antes de hacer el login con google, el programa escribe &lt;code&gt;window.localStorage.setItem('social', 'SignUp')&lt;/code&gt;&lt;br&gt;
y cuando regresa al landing page, revisa si hay un usuario conectado &amp;amp;&amp;amp; &lt;code&gt;window.localStorage.getItem('social') === 'SignUp'&lt;/code&gt;) cambia al usuario de ruta para que termine de crear su perfil.&lt;/p&gt;

&lt;h1&gt;
  
  
  El Problema (O mi novatada)
&lt;/h1&gt;

&lt;p&gt;Si esta evaluación sobre &lt;code&gt;'social' === 'SignUp'&lt;/code&gt; es falsa, estaba ejecutando &lt;code&gt;window.localStorage.clear()&lt;/code&gt; y esto elimina el usuario de Amazon Cognito del navegador 😅&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusión
&lt;/h1&gt;

&lt;p&gt;No escribas &lt;code&gt;window.localStorage.clear()&lt;/code&gt; mejor reemplaza el valor como &lt;code&gt;window.localStorage.setItem('social', 'INIT')&lt;/code&gt; porque no sabes que otros paquetes de npm están usando la localStorage.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>cognito</category>
      <category>graphql</category>
      <category>aws</category>
    </item>
    <item>
      <title>Add the delivery of products by seller🛍</title>
      <dc:creator>jesuscovam</dc:creator>
      <pubDate>Tue, 10 Nov 2020 13:48:53 +0000</pubDate>
      <link>https://dev.to/jesuscovam/add-the-delivery-of-products-by-seller-4pch</link>
      <guid>https://dev.to/jesuscovam/add-the-delivery-of-products-by-seller-4pch</guid>
      <description>&lt;p&gt;I was recently asked for a codebase to make a shopping cart where the shipping price is the most expensive shipping price for the products by the same seller + the most expensive price from the other sellers.&lt;/p&gt;

&lt;p&gt;For example, if there are 4 products in the cart, and 3 are from 1 seller, calculate the most expensive delivery from that seller + the delivery from the other seller.&lt;/p&gt;

&lt;p&gt;the delivery category could be one of these&lt;br&gt;
&lt;code&gt;moto | auto | van&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The price for &lt;strong&gt;auto and van&lt;/strong&gt; is the &lt;strong&gt;same&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;
&lt;h3&gt;
  
  
  A look at the final composed function👀
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const composeProcess = compose(
    reduce((a, b: number) =&amp;gt; a + b, 0),
    map(convertToMoney),
    values,
    mapObjIndexed(mapOverProducts),
    addNoise,
    groupByCategory(category)
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The first step is to group the products by category, for this case is the &lt;code&gt;sellerID&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const groupByCategory = (category: string) =&amp;gt; (products: { item: Product }[]) =&amp;gt; {
    return products.reduce((acc, { item }) =&amp;gt; {
      return (acc = { ...acc, [item[category]]: [...(acc[item[category]] || []), item] })
    }, {})
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function will return a tree of sellers with products&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;This DB only has 1 seller, so we are going to add some noise to test the function&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add noise 🔈
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const addNoise = (nodes) =&amp;gt; ({
    ...nodes,
    bbc: [
      { id: 10, title: 'jaja', delivery: 'moto' },
      { id: 20, title: 'jeje', delivery: 'auto' },
    ],
    ccc: [{ id: 14, title: 'jiji', delivery: 'auto' }],
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Map over the products of each seller 🛍
&lt;/h1&gt;

&lt;p&gt;What matters from this function is to return the most expensive delivery for each tree/node/seller.&lt;/p&gt;

&lt;p&gt;this function is composed of 3 more that apply only to products of each tree/node/seller&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mapObjIndexed(mapOverProducts)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;where mapOverProducts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const mapOverProducts = compose(
    reduce(deliveryReducer, 0), 
    setOf, 
    map(mapOverCategory('delivery'))

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  mapOverCategory
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const mapOverCategory = (category: string) =&amp;gt; (arr) =&amp;gt; arr[category]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;mapOverCategory('delivery') will return [moto, auto, ...NDeliveries] for each node&lt;/p&gt;

&lt;h3&gt;
  
  
  setOf
&lt;/h3&gt;

&lt;p&gt;will return the same array but avoiding repetitive delivery methods&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const setOf = (values) =&amp;gt; [...new Set(values)]&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  reduce(deliveryReducer, 0) ➕
&lt;/h3&gt;

&lt;p&gt;As we only have 3 possible scenarios, we are going to use a reducer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const deliveryReducer = (state, action) =&amp;gt; {
    switch (action) {
      case 'moto':
        return stateOverNumber(1)(state)

      case 'auto':
        return stateOverNumber(2)(state)

      case 'van':
        return stateOverNumber(3)(state)

      default:
        return state
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Where stateOverNumber(n)(state) ❔
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const stateOverNumber = (num: number) =&amp;gt; (state: number) =&amp;gt; 
    (state &amp;lt; num ? num : state)

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;This&lt;/strong&gt; is the moment we obtain which delivery is the most expensive from each node&lt;/p&gt;

&lt;p&gt;At this point, we continue with the first composed function as we ended the work inside each node of products by a seller.&lt;/p&gt;

&lt;p&gt;It's time for &lt;em&gt;values&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const composeProcess = compose(
    reduce((a, b: number) =&amp;gt; a + b, 0),
    map(convertToMoney),
    values,
    mapObjIndexed(mapOverProducts),
    addNoise,
    groupByCategory(category)
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Values
&lt;/h2&gt;

&lt;p&gt;We no longer need the id of each seller, only its biggest delivery method&lt;/p&gt;

&lt;h2&gt;
  
  
  map(converToMoney) 💰
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const convertToMoney = (deliveryTypes: number) =&amp;gt; {
    if (deliveryTypes === 1) {
      return 2.9
    } else {
      return 4.9
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1 being 'moto' and for the moment the price for the other methods is the same.&lt;/p&gt;

&lt;h3&gt;
  
  
  reduce((a, b: number) =&amp;gt; a + b, 0) ➕
&lt;/h3&gt;

&lt;p&gt;The las function adds the value of all the possible prices by a node 😁&lt;/p&gt;

&lt;h1&gt;
  
  
  Now, let's make an abstraction
&lt;/h1&gt;

&lt;p&gt;Ok spoiler alert, I work with react ⚛️&lt;/p&gt;

&lt;p&gt;We are going to abstract all of this logic in a hook that only takes as an argument the category for which we are going to split the nodes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const useAbstraction = (category: string) =&amp;gt; {
  const groupByCategory = (category: string) =&amp;gt; (products: { item: Product }[]) =&amp;gt; {
    return products.reduce((acc, { item }) =&amp;gt; {
      return (acc = { ...acc, [item[category]]: [...(acc[item[category]] || []), item] })
    }, {})
  }

  const mapOverCategory = (category: string) =&amp;gt; (arr) =&amp;gt; arr[category]
  const setOf = (values) =&amp;gt; [...new Set(values)]

  const stateOverNumber = (num: number) =&amp;gt; (state: number) =&amp;gt; (state &amp;lt; num ? num : state)

  const deliveryReducer = (state, action) =&amp;gt; {
    switch (action) {
      case 'moto':
        return stateOverNumber(1)(state)

      case 'auto':
        return stateOverNumber(2)(state)

      case 'van':
        return stateOverNumber(3)(state)

      default:
        return state
    }
  }
  const mapOverProducts = compose(
    reduce(deliveryReducer, 0),
    setOf,
    map(mapOverCategory('delivery'))
  )
  const addNoise = (sellers) =&amp;gt; ({
    ...sellers,
    bbc: [
      { id: 10, title: 'jaja', delivery: 'moto' },
      { id: 20, title: 'jeje', delivery: 'auto' },
    ],
    ccc: [{ id: 14, title: 'jiji', delivery: 'auto' }],
  })

  const convertToMoney = (deliveryTypes: number) =&amp;gt; {
    if (deliveryTypes === 1) {
      return 2.9
    } else {
      return 4.9
    }
  }

  const composeProcess = compose(
    reduce((a, b: number) =&amp;gt; a + b, 0),
    map(convertToMoney),
    values,
    mapObjIndexed(mapOverProducts),
    addNoise,
    groupByCategory(category)
  )

  return { composeProcess }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;And now&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const { composeProcess } = useAbstraction('sellerID')
  const delivery = useCallback( () 
   =&amp;gt; composeProcess(state.products)
   , [state.products])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Outro
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BUoI3Yyp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.kym-cdn.com/photos/images/newsfeed/001/499/826/2f0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BUoI3Yyp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.kym-cdn.com/photos/images/newsfeed/001/499/826/2f0.png" alt="Stonks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Probably there are better ways to give order hierarchy to the delivery methods, but this way works and it could be adapted to even group by cities or states.&lt;/p&gt;

&lt;p&gt;My name is Jesus Cova, I work with the team at &lt;a href="https://www.instagram.com/midnightouizard/"&gt;midnightouizard&lt;/a&gt;🧙🏼‍♂️ and you can contact me on &lt;a href="https://twitter.com/jesusacova"&gt;twitter&lt;/a&gt; or &lt;a href="mailto:jesuscovam@gmail.com"&gt;jesuscovam@gmail.com&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Thanks for your time!
&lt;/h3&gt;

</description>
    </item>
    <item>
      <title>Sumar el delivery de productos por vendedor🛍</title>
      <dc:creator>jesuscovam</dc:creator>
      <pubDate>Tue, 10 Nov 2020 02:39:44 +0000</pubDate>
      <link>https://dev.to/jesuscovam/sumar-el-delivery-de-productos-por-vendedor-4nf</link>
      <guid>https://dev.to/jesuscovam/sumar-el-delivery-de-productos-por-vendedor-4nf</guid>
      <description>&lt;p&gt;Recientemente me pidieron en una codebase qué mantengo hacer un carrito de compras donde el precio del envío sea el precio de envío más caro por productos de un mismo vendedor + el precio más caro de los otros vendedores.&lt;/p&gt;

&lt;p&gt;Ejemplo, si en el carrito hay 4 productos, y 3 son de 1 vendedor, calcular el delivery mas costoso de ese vendedor + el delivery del otro vendedor.&lt;/p&gt;

&lt;p&gt;La categoría de delivery puede ser &lt;br&gt;
&lt;code&gt;moto | auto | van&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;El precio de &lt;strong&gt;auto y van&lt;/strong&gt; para este uso es el &lt;strong&gt;mismo&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Codigo
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Este es un vistaso a la composición final👀
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const composeProcess = compose(
    reduce((a, b: number) =&amp;gt; a + b, 0),
    map(convertToMoney),
    values,
    mapObjIndexed(mapOverProducts),
    addNoise,
    groupByCategory(category)
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;El primer paso es agrupar los productos por categoría, en este caso la categoría será &lt;code&gt;sellerID&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const groupByCategory = (category: string) =&amp;gt; (products: { item: Product }[]) =&amp;gt; {
    return products.reduce((acc, { item }) =&amp;gt; {
      return (acc = { ...acc, [item[category]]: [...(acc[item[category]] || []), item] })
    }, {})
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta función nos va a devolver un árbol de vendedores con productos&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Esta base de datos solo tiene un vendedor, entonces agregaremos un poco de ruido para probar esta función&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Agregar ruido 🔈
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const addNoise = (nodes) =&amp;gt; ({
    ...nodes,
    bbc: [
      { id: 10, title: 'jaja', delivery: 'moto' },
      { id: 20, title: 'jeje', delivery: 'auto' },
    ],
    ccc: [{ id: 14, title: 'jiji', delivery: 'auto' }],
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Map sobre los productos de cada vendedor 🛍
&lt;/h1&gt;

&lt;p&gt;Lo que nos importa de toda esta función es calcular el delivery más costoso de cada categoria/nodo/vendedor&lt;/p&gt;

&lt;p&gt;La siguiente linea es una composición de 3 funciones para conseguir ese delivery más costoso.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mapObjIndexed(mapOverProducts)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Donde mapOverProducts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const mapOverProducts = compose(
    reduce(deliveryReducer, 0), 
    setOf, 
    map(mapOverCategory('delivery'))

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  mapOverCategory
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const mapOverCategory = (category: string) =&amp;gt; (arr) =&amp;gt; arr[category]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;mapOverCategory('delivery') va a devolver [moto, auto, ...NDeliveries] por cada vendedor&lt;/p&gt;

&lt;h3&gt;
  
  
  setOf
&lt;/h3&gt;

&lt;p&gt;va a devolver el mismo arreglo quitando los deliveries repetidos&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const setOf = (values) =&amp;gt; [...new Set(values)]&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  reduce(deliveryReducer, 0) ➕
&lt;/h3&gt;

&lt;p&gt;Ok aquí tenemos 3 escenarios posibles, entonces por comodidad lo manejé con un reducer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const deliveryReducer = (state, action) =&amp;gt; {
    switch (action) {
      case 'moto':
        return stateOverNumber(1)(state)

      case 'auto':
        return stateOverNumber(2)(state)

      case 'van':
        return stateOverNumber(3)(state)

      default:
        return state
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Donde stateOverNumber(n)(state) ❔
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const stateOverNumber = (num: number) =&amp;gt; (state: number) =&amp;gt; 
    (state &amp;lt; num ? num : state)

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Esta&lt;/em&gt;&lt;/strong&gt; es la pieza clave que da categoría a cada producto, lo demás fue llegar aquí.&lt;/p&gt;

&lt;p&gt;En este punto podemos regresar a la primera función compuesta, ya terminamos de mapear sobre los productos de cada nodo/vendedor&lt;/p&gt;

&lt;p&gt;Recordando que viene &lt;em&gt;values&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const composeProcess = compose(
    reduce((a, b: number) =&amp;gt; a + b, 0),
    map(convertToMoney),
    values,
    mapObjIndexed(mapOverProducts),
    addNoise,
    groupByCategory(category)
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Values
&lt;/h2&gt;

&lt;p&gt;Ya no necesitamos el id del vendedor, solo sus valores.&lt;/p&gt;

&lt;h2&gt;
  
  
  map(converToMoney) 💰
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const convertToMoney = (deliveryTypes: number) =&amp;gt; {
    if (deliveryTypes === 1) {
      return 2.9
    } else {
      return 4.9
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1 siendo moto, y por el momento los otros valores tienen el mismo precio&lt;/p&gt;

&lt;h3&gt;
  
  
  reduce((a, b: number) =&amp;gt; a + b, 0) ➕
&lt;/h3&gt;

&lt;p&gt;La última función nos da la suma de estos valores para tener la suma del delivery más costoso de cada vendedor 😁&lt;/p&gt;

&lt;h1&gt;
  
  
  Listo, vamos a hacer una abstracción
&lt;/h1&gt;

&lt;p&gt;Ok spoiler alert: uso react. ⚛️&lt;/p&gt;

&lt;p&gt;voy a abstraer toda esta lógica en un custom Hook que solo tome la categoría y sobre la cual queremos agrupar los productos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const useAbstraction = (category: string) =&amp;gt; {
  const groupByCategory = (category: string) =&amp;gt; (products: { item: Product }[]) =&amp;gt; {
    return products.reduce((acc, { item }) =&amp;gt; {
      return (acc = { ...acc, [item[category]]: [...(acc[item[category]] || []), item] })
    }, {})
  }

  const mapOverCategory = (category: string) =&amp;gt; (arr) =&amp;gt; arr[category]
  const setOf = (values) =&amp;gt; [...new Set(values)]

  const stateOverNumber = (num: number) =&amp;gt; (state: number) =&amp;gt; (state &amp;lt; num ? num : state)

  const deliveryReducer = (state, action) =&amp;gt; {
    switch (action) {
      case 'moto':
        return stateOverNumber(1)(state)

      case 'auto':
        return stateOverNumber(2)(state)

      case 'van':
        return stateOverNumber(3)(state)

      default:
        return state
    }
  }
  const mapOverProducts = compose(
    reduce(deliveryReducer, 0),
    setOf,
    map(mapOverCategory('delivery'))
  )
  const addNoise = (sellers) =&amp;gt; ({
    ...sellers,
    bbc: [
      { id: 10, title: 'jaja', delivery: 'moto' },
      { id: 20, title: 'jeje', delivery: 'auto' },
    ],
    ccc: [{ id: 14, title: 'jiji', delivery: 'auto' }],
  })

  const convertToMoney = (deliveryTypes: number) =&amp;gt; {
    if (deliveryTypes === 1) {
      return 2.9
    } else {
      return 4.9
    }
  }

  const composeProcess = compose(
    reduce((a, b: number) =&amp;gt; a + b, 0),
    map(convertToMoney),
    values,
    mapObjIndexed(mapOverProducts),
    addNoise,
    groupByCategory(category)
  )

  return { composeProcess }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Y ahora solo usamos&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const { composeProcess } = useAbstraction('sellerID')
  const delivery = useMemo( () 
   =&amp;gt; composeProcess(state.products)
   , [state.products])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Outro
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BUoI3Yyp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.kym-cdn.com/photos/images/newsfeed/001/499/826/2f0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BUoI3Yyp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.kym-cdn.com/photos/images/newsfeed/001/499/826/2f0.png" alt="Stonks"&gt;&lt;/a&gt;&lt;br&gt;
Probablemente pueda mejorar el reducer, pero ya esto soporta la posibilidad de agrupar en un futuro por ciudad o estado.&lt;/p&gt;

&lt;p&gt;Mi nombre es Jesus Cova, trabajo con el equipo de &lt;a href="https://www.instagram.com/midnightouizard/"&gt;midnightouizard&lt;/a&gt;🧙🏼‍♂️ y me pueden contactar en &lt;a href="https://twitter.com/jesusacova"&gt;twitter&lt;/a&gt; o en &lt;a href="mailto:jesuscovam@gmail.com"&gt;jesuscovam@gmail.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¡Gracias por tu tiempo!
&lt;/h2&gt;

</description>
    </item>
    <item>
      <title>Hacer === Function // Que hago === Data</title>
      <dc:creator>jesuscovam</dc:creator>
      <pubDate>Thu, 01 Oct 2020 18:57:03 +0000</pubDate>
      <link>https://dev.to/jesuscovam/hacer-function-que-hago-data-374i</link>
      <guid>https://dev.to/jesuscovam/hacer-function-que-hago-data-374i</guid>
      <description>&lt;p&gt;Me gusta la idea de que mis funciones se conceptualizan de manera general para que puedan ser usadas en diferentes casos especificos. Resulta que el uso que le doy a algo que tiene nombre, es solo un uso que puede ser un termino diferente para otra persona. La capacidad de desconceptualizar el termino con la acción, libera a la acción de ser reutilizada en más maneras, porque ahora ya no tengo que HacerX(), HacerY(), HacerZ(), solo tengo que Hacer(Algo).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Anatomy of a reusable component in React</title>
      <dc:creator>jesuscovam</dc:creator>
      <pubDate>Thu, 02 Jul 2020 00:53:43 +0000</pubDate>
      <link>https://dev.to/jesuscovam/anatomy-of-a-reusable-component-in-react-3ocm</link>
      <guid>https://dev.to/jesuscovam/anatomy-of-a-reusable-component-in-react-3ocm</guid>
      <description>&lt;p&gt;Hi there, I'm going to explain you how to decompose into peaces a component, like the one I'm using right now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OTTLRWKA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/N93vnLy/Screen-Shot-2020-07-01-at-7-26-55-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OTTLRWKA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/N93vnLy/Screen-Shot-2020-07-01-at-7-26-55-PM.png" alt="maincp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The component will have several selects, the goal is to use the same select component with different parameters, so we actually do ourselves the favor of not having to write the same test more than once and reduce our codebase.&lt;/p&gt;

&lt;h1&gt;
  
  
  Imports
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M_XUMRa4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/PDYcK19/Screen-Shot-2020-07-01-at-4-39-41-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M_XUMRa4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/PDYcK19/Screen-Shot-2020-07-01-at-4-39-41-PM.png" alt="imports"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imports at the first lines of every js file is a thumb rule, I've seen people using &lt;em&gt;dinamic imports&lt;/em&gt; but... well I haven't have the use case for now. So we'll write them at the beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Component Declaration
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2iSubTZl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/rHSKzJ6/Screen-Shot-2020-07-01-at-7-47-44-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2iSubTZl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/rHSKzJ6/Screen-Shot-2020-07-01-at-7-47-44-PM.png" alt="component declaration"&gt;&lt;/a&gt;&lt;br&gt;
Here is where the composition begins. &lt;/p&gt;

&lt;h3&gt;
  
  
  Declaration
&lt;/h3&gt;

&lt;p&gt;we declare the component as a function or a const, I prefer const so I have my chance of a 1 line declaration with return.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;p&gt;the parameters inside the ({ }) have general names, that's because we plan to use this component for different types of data that fit the description. This case is the already selected names of descriptive items that create a new pool in the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logic
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x6VxXAST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/VSgCxhD/Screen-Shot-2020-07-01-at-4-41-01-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x6VxXAST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/VSgCxhD/Screen-Shot-2020-07-01-at-4-41-01-PM.png" alt="logic"&gt;&lt;/a&gt;&lt;br&gt;
This function "useFetchData" will fetch some data from the database (in my case is firestore). And will update the state, from this state we can part to the UI section of this component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Return (UI)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ME0cZFjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/X8RbWYx/Screen-Shot-2020-07-01-at-4-42-16-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ME0cZFjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/X8RbWYx/Screen-Shot-2020-07-01-at-4-42-16-PM.png" alt="return statement"&gt;&lt;/a&gt;&lt;br&gt;
This is it, here's were we actually serve some UI to the app. We'll use some already written/tested components from @material-ui, which gets really mad if you don't control a form component, so we are going to use the controlledValue state and onChange method written in the component declaration.&lt;/p&gt;

&lt;h3&gt;
  
  
  &amp;lt; Select &amp;gt;some some &amp;lt; /Select &amp;gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DBFcmw6A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/SBSSJfp/Screen-Shot-2020-07-01-at-6-01-17-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DBFcmw6A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/SBSSJfp/Screen-Shot-2020-07-01-at-6-01-17-PM.png" alt="select"&gt;&lt;/a&gt;&lt;br&gt;
The select tag will display in a dropdown style N options we write inside them, as we are using react and plan to make this component reusable, we are going to display the options from the recently updated state that fit the collection written in the composition of this component.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's it
&lt;/h2&gt;

&lt;p&gt;We did it, we wrote a reusable component in React.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full Component
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YYtyugX9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/K0ksJB9/Screen-Shot-2020-07-01-at-7-51-28-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YYtyugX9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/K0ksJB9/Screen-Shot-2020-07-01-at-7-51-28-PM.png" alt="component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First Picture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n1BCYNXv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/2yz4QSr/Screen-Shot-2020-07-01-at-6-02-23-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n1BCYNXv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/2yz4QSr/Screen-Shot-2020-07-01-at-6-02-23-PM.png" alt="multiples uses of component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Thanks for your time!
&lt;/h1&gt;

&lt;p&gt;If you want to chat about javascript || apps, please, feel free to write me a message✌️&lt;/p&gt;

&lt;p&gt;Jesus Cova&lt;br&gt;
&lt;em&gt;Full Stack Developer&lt;/em&gt;&lt;br&gt;
&lt;a href="https://jesusc.dev"&gt;jesusc.dev&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/jesusacova"&gt;twitter&lt;/a&gt;&lt;/p&gt;

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