<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Leonardo Bruno Lima on Medium]]></title>
        <description><![CDATA[Stories by Leonardo Bruno Lima on Medium]]></description>
        <link>https://medium.com/@leonardobrunolima?source=rss-42ccfccbb437------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*QqH9IQzcEdbc7oGxhdg_8A@2x.jpeg</url>
            <title>Stories by Leonardo Bruno Lima on Medium</title>
            <link>https://medium.com/@leonardobrunolima?source=rss-42ccfccbb437------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 18:36:08 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@leonardobrunolima/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[How to cancel/abort a fetch request using abortController]]></title>
            <link>https://medium.com/@leonardobrunolima/how-to-cancel-abort-a-fetch-request-using-abortcontroller-b5ad39c10901?source=rss-42ccfccbb437------2</link>
            <guid isPermaLink="false">https://medium.com/p/b5ad39c10901</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[request]]></category>
            <category><![CDATA[fetch-api]]></category>
            <dc:creator><![CDATA[Leonardo Bruno Lima]]></dc:creator>
            <pubDate>Mon, 21 Oct 2019 19:25:26 GMT</pubDate>
            <atom:updated>2019-10-21T19:25:26.170Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*D-z53EJJxiBYFmm7qaYD-Q.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@shemul?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Shahadat Shemul</a> on <a href="https://unsplash.com/s/photos/script?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Hey guys, have you heard about abortController before? It’s an experimental technology, but it’s already supported for almost all modern browsers.</p><p><a href="https://dom.spec.whatwg.org/#interface-abortcontroller">https://dom.spec.whatwg.org/#interface-abortcontroller</a></p><p>Basically, when we create an abortController we have access to the AbortSignal object that we can pass it as an option inside the request object. This associates the signal and controller with the fetch request and allows us to abort it calling the abort method.</p><p>Let’s create a simple method that receives an URL and a timeout parameter.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/50f18d53a9844e6f569baf7d55f8841b/href">https://medium.com/media/50f18d53a9844e6f569baf7d55f8841b/href</a></iframe><p>In the method above, we simply created an abortController and grabbed the signal object and passed it to the request. Finally, we used a setTimeout to abort the request. We can try to call this method passing a low timeout value like 50 and increase to 200 and check the result. Very simple isn’t it?</p><p>Just remember that the request is aborted only at the client, the server is still processing the operation although the client won’t receive it anymore.</p><p>Thanks for reading,</p><p><a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController">AbortController - Web APIs | MDN</a></p><p><a href="https://dom.spec.whatwg.org/#interface-abortcontroller">https://dom.spec.whatwg.org/#interface-abortcontroller</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b5ad39c10901" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Javascript tips — Class vs Instance properties]]></title>
            <link>https://medium.com/@leonardobrunolima/javascript-tips-class-vs-instance-properties-efbceae22b6d?source=rss-42ccfccbb437------2</link>
            <guid isPermaLink="false">https://medium.com/p/efbceae22b6d</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[static]]></category>
            <category><![CDATA[class]]></category>
            <category><![CDATA[ecmascript]]></category>
            <category><![CDATA[es6]]></category>
            <dc:creator><![CDATA[Leonardo Bruno Lima]]></dc:creator>
            <pubDate>Wed, 05 Sep 2018 11:59:51 GMT</pubDate>
            <atom:updated>2018-09-05T11:59:51.813Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GxgN1UUyZTIg-vOqlBsgnQ.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/ruiU36AR5zo?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Pankaj Patel</a> on <a href="https://unsplash.com/search/photos/javascript?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>This post is just a small tip about ES6+ properties. We can find in many languages instance and class (static) fields. Let’s see an example:</p><p>1 — Instance property</p><pre>class Employee {<br>   constructor() {<br>      <strong>this.Name</strong> = &quot;Leonardo Lima&quot;;<br>   }<br>}</pre><pre>const emp = new Employee();</pre><pre>console.log(emp.Name); //output Leonardo Lima<br>console.log(Employee.Name); //output undefined</pre><p>This code above we just create a class and defined a instance field called <strong>Name </strong>and this field is accessible only via instance, <strong>emp</strong> variable. We can rewrite this code removing the constructor:</p><pre>class Employee {<br>   <strong>Name </strong>= &quot;Leonardo Lima&quot;;<br>}</pre><pre>const emp = new Employee();</pre><pre>console.log(emp.Name); //output Leonardo Lima<br>console.log(Employee.Name); //output undefined</pre><p>2 — Class property</p><p>In order to create a class property, we need to create the field using <strong>static </strong>keyword:</p><pre>class Employee {<br>   static Name = &quot;Leonardo Lima&quot;;<br>}</pre><pre>const emp = new Employee();</pre><pre>console.log(emp.Name); //output <strong>undefined</strong><br>console.log(Employee.Name); //output Leonardo Lima</pre><p>As you can see in the code above, now the <strong>Name </strong>field is accessible directly via class and you cannot access it using the instance <strong>emp</strong>.</p><p>Thanks for reading!</p><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static">static - JavaScript | MDN</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=efbceae22b6d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native tips — Animate cards (react-native-elements, interpolation and more)]]></title>
            <link>https://medium.com/@leonardobrunolima/react-native-tips-animate-cards-react-native-elements-interpolation-and-more-8fa36ce6f050?source=rss-42ccfccbb437------2</link>
            <guid isPermaLink="false">https://medium.com/p/8fa36ce6f050</guid>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[mobile-apps]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <dc:creator><![CDATA[Leonardo Bruno Lima]]></dc:creator>
            <pubDate>Fri, 31 Aug 2018 20:22:09 GMT</pubDate>
            <atom:updated>2018-08-31T20:27:08.463Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GorMajZaqMRwv-Zgqjaq2w.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/OvN4OkhkTLo?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Wayne Low</a> on <a href="https://unsplash.com/search/photos/cards?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Hi guys, in this post I will show you how to create a simple swipe effect with cards, Tinder like. I am going to use basically React Native components except the <a href="https://github.com/react-native-training/react-native-elements"><strong>react-native-elements</strong></a> to create the Cards.</p><p><em>You can see how to setup the dev environment here: </em><a href="https://medium.com/@leonardobrunolima/react-native-tips-setting-up-your-development-environment-for-windows-d326635604ea?source=linkShare-42ccfccbb437-1535561576"><em>https://medium.com/@leonardobrunolima/react-native-tips-setting-up-your-development-environment-for-windows-d326635604ea?source=linkShare-42ccfccbb437-1535561576</em></a></p><h3>TL;DR</h3><p>You can clone the project and use this post as reference, but if you want read the full post go ahead!</p><p>Let’s get started creating a new project using react-native cli:</p><pre>$ react-native init SwipeIt --version <strong>0.55.4</strong></pre><p>Add react-native-elements package:</p><pre>$ npm i react-native-elements</pre><p>As we are not using EXPO, we have to install <strong>react-native-vector-icons</strong> and link it:</p><pre>$ npm i --save react-native-vector-icons</pre><p>Link it:</p><pre>$ react-native link react-native-vector-icons</pre><p>You can check the documentation here: <a href="https://react-native-training.github.io/react-native-elements/docs/0.19.0/getting_started.html">https://react-native-training.github.io/react-native-elements/docs/0.19.0/getting_started.html</a></p><p>Let’s separate development in steps:</p><p><strong>1 </strong>— Create the folder <strong>src </strong>and the basic card container component:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/353/1*fviA5AwCvektb2w3-tGtBw.png" /></figure><pre>//import liraries<br>import React, { Component } from &#39;react&#39;;<br>import { View } from &#39;react-native&#39;;</pre><pre>// create a component<br>class CardsContainer extends Component {<br>   renderCards() {<br>      return <strong>this.props.data</strong>.map((item, index) =&gt; {<br>         return (<br>            &lt;View key={item.id}&gt;<br>               {<strong>this.props.renderCard</strong>(item)}<br>            &lt;/View&gt;<br>         )<br>      });<br>   }</pre><pre>   render() {<br>      return (<br>         &lt;View&gt;<br>            {this.renderCards()}<br>         &lt;/View&gt;<br>      );<br>   }<br>}</pre><pre>//make this component available to the app<br>export default CardsContainer;</pre><p>Ok, this is the basic cards container, as you can see we have two props: <strong>this.props.data </strong>and <strong>this.props.renderCard</strong>. The render method just call the renderCards method and we call the <strong>renderCard </strong>for each item in <strong>data </strong>prop. These props we are going to pass from App.js component.</p><p><strong>2</strong> — Configure App.js to create and pass the props to CardsContainer component:</p><p>We are going to use <a href="https://github.com/react-native-training/react-native-elements"><strong>react-native-elements</strong></a><strong> </strong>to create the cards, you can check the documentation here: <a href="https://react-native-training.github.io/react-native-elements/docs/0.19.0/card.html">https://react-native-training.github.io/react-native-elements/docs/0.19.0/card.html</a></p><p>On cards we need to show some images, so I will get those images from unsplash.com and create a const <strong>DATA</strong> to hold this images. You can get it from anywhere you want. Let’s see the App.js code:</p><pre>import React, { Component } from &#39;react&#39;;<br>import {<br>   StyleSheet,<br>   Text,<br>   View<br>  } from &#39;react-native&#39;;</pre><pre>import { Card, Button } from &#39;react-native-elements&#39;;<br>import <strong>CardsContainer </strong>from &#39;./src/CardsContainer&#39;;</pre><pre>const <strong>DATA </strong>= [<br>{ id: 1, text: &#39;Card #1&#39;, uri: &#39;https://images.unsplash.com/photo-1535591273668-578e31182c4f?ixlib=rb-0.3.5&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;s=f28261f0564880c9086a57ee87a68887&amp;auto=format&amp;fit=crop&amp;w=500&amp;q=60&#39; },</pre><pre>{ id: 2, text: &#39;Card #2&#39;, uri: &#39;https://images.unsplash.com/photo-1535576434247-e0f50b766399?ixlib=rb-0.3.5&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;s=232f6dbab45b3f3a6f97e638c27fded2&amp;auto=format&amp;fit=crop&amp;w=500&amp;q=60&#39; },</pre><pre>{ id: 3, text: &#39;Card #3&#39;, uri: &#39;https://images.unsplash.com/photo-1535565454739-863432ea3c0e?ixlib=rb-0.3.5&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;s=7edfb9bc7d214dbf2c920723cb0ffce2&amp;auto=format&amp;fit=crop&amp;w=500&amp;q=60&#39; },</pre><pre>{ id: 4, text: &#39;Card #4&#39;, uri: &#39;https://images.unsplash.com/photo-1535546204504-586398ee6677?ixlib=rb-0.3.5&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;s=7320b162b147a94d4c41377d9035e665&amp;auto=format&amp;fit=crop&amp;w=500&amp;q=60&#39; },</pre><pre>{ id: 5, text: &#39;Card #5&#39;, uri: &#39;https://images.unsplash.com/photo-1535531298052-7457bcdae809?ixlib=rb-0.3.5&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;s=f15acb2aedb30131bb287589399185a2&amp;auto=format&amp;fit=crop&amp;w=500&amp;q=60&#39; },</pre><pre>{ id: 6, text: &#39;Card #6&#39;, uri: &#39;https://images.unsplash.com/photo-1535463731090-e34f4b5098c5?ixlib=rb-0.3.5&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;s=ebe64b284c0ccffbac6a0d7ce2c8d15a&amp;auto=format&amp;fit=crop&amp;w=500&amp;q=60&#39; },</pre><pre>{ id: 7, text: &#39;Card #7&#39;, uri: &#39;https://images.unsplash.com/photo-1535540707939-6b4813adb681?ixlib=rb-0.3.5&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;s=ce3177d04728f7d1811e342b47d1e391&amp;auto=format&amp;fit=crop&amp;w=500&amp;q=60&#39; },</pre><pre>{ id: 8, text: &#39;Card #8&#39;, uri: &#39;https://images.unsplash.com/photo-1535486509975-18366f9825df?ixlib=rb-0.3.5&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;s=ea59f63a657824d02872bb907fe85e76&amp;auto=format&amp;fit=crop&amp;w=500&amp;q=60&#39; }<br>];</pre><pre>export default class App extends Component {<br>   <strong>renderCard</strong>(item) {<br>      return (<br>         &lt;<strong>Card</strong><br>            key={item.id}<br>            title={item.text}<br>            image={{ uri: item.uri }}<br>         &gt;<br>            &lt;<strong>Text </strong>style={{ marginBottom: 10 }}&gt;<br>               Testing....<br>            &lt;/<strong>Text</strong>&gt;<br>            &lt;<strong>Button</strong><br>               backgroundColor=&#39;#03A9F4&#39;<br>               title=&quot;More details&quot;<br>            /&gt;<br>         &lt;/<strong>Card</strong>&gt;<br>      );<br>   }</pre><pre>   render() {<br>      return (<br>         &lt;View style={styles.container}&gt;<br>            &lt;CardsContainer<br>               <strong>data</strong>={DATA}<br>               <strong>renderCard</strong>={this.renderCard}<br>            /&gt;<br>         &lt;/View&gt;<br>      );<br>   }<br>}</pre><pre>const styles = StyleSheet.create({<br>   container: {<br>      flex: 1,<br>   }<br>});</pre><p>We basically have the the <strong>DATA </strong>and <strong>renderCard </strong>method to pass to <strong>CardsContainer </strong>component. Now let’s see how it looks like on emulator:</p><pre>$ react-native run-android</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*j4cAYuD17Gr336L20TL68Q.png" /></figure><p>Cool, now we can go to <strong>CardsContainer </strong>component and do the magic:</p><p><strong>3 </strong>— Adjust on Cards position and add basic animation:</p><p>First, let’s make the cards aligned and create a basic translation animation. Add the Style and set the position to absolute, so all cards will be fixed on top. Once you do that, the width will follow lowest size inside the container, so we need to add the width manually using the screen width using <strong>Dimensions </strong>component:</p><pre>//import liraries<br>import React, { Component } from &#39;react&#39;;<br>import {<br>   View,<br>   StyleSheet,<br>   <strong>Dimensions</strong><br>  } from &#39;react-native&#39;;</pre><pre>const <strong>SCREEN_WIDTH </strong>= Dimensions.get(&#39;window&#39;).width;</pre><pre>// create a component<br>class CardsContainer extends Component {<br>   renderCards() {<br>      return this.props.data.map((item, index) =&gt; {<br>         return (<br>            &lt;View<br><strong>               style={styles.cardStyle}</strong><br>               key={item.id}<br>            &gt;<br>               {this.props.renderCard(item)}<br>            &lt;/View&gt;<br>         )<br>      }).<strong>reverse()</strong>;<br>   }</pre><pre>   render() {<br>      return (<br>         &lt;View&gt;<br>            {this.renderCards()}<br>         &lt;/View&gt;<br>      );<br>   }<br>}</pre><pre>// define your styles<br><strong>const styles = StyleSheet.create({<br>   cardStyle: {<br>      position: &#39;absolute&#39;,<br>      width: SCREEN_WIDTH<br>   },<br>});</strong></pre><pre>//make this component available to the app<br>export default CardsContainer;</pre><blockquote>As you can see I called the <strong>reverse()</strong> method on <strong>renderCards </strong>otherwise the last image will be on top.</blockquote><p>Now we must have something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zIhNH0p1uV2gQgqPRYphYg.png" /></figure><p>Animations!! Let’s go!</p><p>I am going to use <strong>Animated </strong>and <strong>PanResponder</strong>, the same components I’ve used in the post below, take some time, read it and come back:</p><p><a href="https://medium.com/@leonardobrunolima/react-native-tips-using-animated-and-panresponder-components-to-interact-with-user-gestures-4620bf27b9e4">React Native tips — Using Animated and PanResponder components to interact with user gestures</a></p><p>The code is becoming big, don’t worry, you can clone it on GitHub: <a href="https://github.com/lblima/react-native-swipeit">https://github.com/lblima/react-native-swipeit</a></p><pre>//import liraries<br>import React, { Component } from &#39;react&#39;;<br>import {<br>   View,<br>   StyleSheet,<br>   Dimensions,<br>   <strong>Animated</strong>,<br>   <strong>PanResponder</strong><br>} from &#39;react-native&#39;;</pre><pre>const SCREEN_WIDTH = Dimensions.get(&#39;window&#39;).width;</pre><pre>// create a component<br>class CardsContainer extends Component {<br>   constructor(props) {<br>      super(props);</pre><pre>      const <strong>position </strong>= new <strong>Animated</strong>.ValueXY();<br>      const <strong>panResponder </strong>= <strong>PanResponder</strong>.create({<br>         onStartShouldSetPanResponder: () =&gt; true,<br>         <strong>onPanResponderMove</strong>: (event, gesture) =&gt; {<br>            position.setValue({ x: gesture.dx, y: gesture.dy });<br>         },<br>         onPanResponderRelease: (event, gesture) =&gt; {}<br>      });</pre><pre>      this.state = { panResponder, position, index: 0 };<br>   }</pre><pre>   renderCards() {<br>      return this.props.data.map((item, index) =&gt; {<br>         //Add animation only to the card on top<br>         if (index === this.state.index) {<br>            return (<br>               &lt;<strong>Animated.View</strong><br>                  style={[<br>                    styles.cardStyle,<br>                    this.state.position.getLayout()<br>                  ]}  <br>                  {...this.state.panResponder.panHandlers}<br>                  key={item.id}<br>               &gt;<br>                  {this.props.renderCard(item)}<br>               &lt;/<strong>Animated.View</strong>&gt;<br>            )<br>         }</pre><pre>      return (<br>         &lt;<strong>Animated.View</strong><br>            style={styles.cardStyle}<br>            key={item.id}<br>         &gt;<br>            {this.props.renderCard(item)}<br>         &lt;/<strong>Animated.View</strong>&gt;<br>         );<br>      }).reverse();<br>    }</pre><pre>   render() {<br>      return (<br>         &lt;View&gt;<br>            {this.renderCards()}<br>         &lt;/View&gt;<br>      );<br>   }<br>}</pre><pre>...</pre><pre>export default CardsContainer;</pre><p>This is the basic code to make an element move when you drag it on screen, now we must have this:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FGeEXWjKeJRQ%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DGeEXWjKeJRQ&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FGeEXWjKeJRQ%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/379d9d427cd1aa54b3beb16dcfafb959/href">https://medium.com/media/379d9d427cd1aa54b3beb16dcfafb959/href</a></iframe><p><strong>4</strong> — Interpolation and rotation</p><p>The next step is rotate the card when you change the X axis, we can do it using interpolation. It is basically saying whenever you move some pixel on X axis do something (move Y axis, change color, rotate, etc). Let’s do that:</p><pre>...</pre><pre>//Add animation only to the card on top<br>if (index === this.state.index) {<br>   return (<br>      &lt;Animated.View<br>         style={[<br>            styles.cardStyle,<br>            <strong>this.state.position.getLayout()</strong><br>         ]}<br>         {...this.state.panResponder.panHandlers}<br>         key={item.id}<br>      &gt;<br>         {this.props.renderCard(item)}<br>      &lt;/Animated.View&gt;<br>   )<br>}</pre><pre>...</pre><p>In this part of the code, we have the position been passed to Animated.View using the line: <strong>this.state.position.getLayout() </strong>and the position is changed on <strong>onPanResponderMove</strong> event. What we have to do now is modify this behavior to not only pass the new position, but do some rotation on card. So let’s create a new method to do this called <strong>getCardStyle.</strong></p><pre>...</pre><pre><strong>getCardStyle</strong>() {<br>   const { position } = this.state;<br>   const rotationX = SCREEN_WIDTH * 2;</pre><pre>   const rotate = position.x.interpolate({<br>      inputRange: [-rotationX, 0, rotationX],<br>      outputRange: [&#39;-120deg&#39;, &#39;0deg&#39;, &#39;120deg&#39;]<br>   });</pre><pre>   return {<br>      ...position.getLayout(),<br>      <strong>transform: [{ rotate }]</strong><br>   }<br>}</pre><pre>renderCards() {<br>   return this.props.data.map((item, index) =&gt; {<br>      if (index &lt; this.state.index)<br>         return null;<br>      <br>      //Add animation only to the card on top<br>      if (index === this.state.index) {<br>         return (<br>            &lt;Animated.View<br>               style={[<br>                  styles.cardStyle,<br>                  this.<strong>getCardStyle</strong>()<br>               ]}<br>               {...this.state.panResponder.panHandlers}<br>               key={item.id}<br>            &gt;<br>               {this.props.renderCard(item)}<br>            &lt;/Animated.View&gt;<br>         );<br>      }<br> <br>      return (<br>         &lt;Animated.View<br>            key={item.id}<br>            style={[<br>               styles.cardStyle, <br>               <strong>{transform: [{ rotate: &#39;0deg&#39;}]},</strong> <br>               <strong>{ top: 10 * (index - this.state.index) }</strong><br>            ]}<br>         &gt;<br>            {this.props.renderCard(item)}<br>         &lt;/Animated.View&gt;<br>      );<br>   }).reverse();<br>}</pre><pre>...</pre><p>Now we are getting the style for the first card calling this method <strong>getCardStyle </strong>that apply the interpolation to the element. Whenever you move on X axis e have a rotation o same direction.</p><blockquote>To the other cards, I had to apply a <strong>{transform: [{ rotate: ‘0deg’}]} </strong>due a bug for Android.</blockquote><p>To make the UX more rich, I’ve added a small space to other cards: <strong>{ top: 10 * (index — this.state.index) }</strong></p><p>Now we must have this:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fexjx-M0hn98%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dexjx-M0hn98&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fexjx-M0hn98%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/f7e1ba5bcf00555b61588ab91713aef2/href">https://medium.com/media/f7e1ba5bcf00555b61588ab91713aef2/href</a></iframe><p>5 — Response when user release the card</p><p>The next step is detect when user release the card and check if we make the current card go back to original position or bring the next card on top. To do this we need to add some code on <strong>onPanResponderRelease </strong>event.</p><p>Let’s create 3 new methods to deal with it:</p><pre>completeSwipe(direction) {<br>   const x = (direction === &#39;right&#39; ? <br>                    SCREEN_WIDTH + 50 : -SCREEN_WIDTH - 50);</pre><pre>   Animated.timing(this.state.position, {<br>      toValue: { x, y: 0 },<br>      duration: 250<br>   }).start(() =&gt; this.<strong>onCompleteSwipe</strong>());<br>}</pre><pre><strong>onCompleteSwipe</strong>() {<br>   this.setState({ index: this.state.index + 1 });<br>   this.state.position.setValue({ x: 0, y: 0 });<br>}</pre><pre>resetPosition() {<br>   this.state.position.setValue({ x: 0, y: 0 });<br>}</pre><p>The <strong>completeSwipe </strong>method will be called when drag and release the card beyond a certain value on X axis. So we create a animation to remove it from screen and call the callback <strong>onCompleteSwipe. </strong>The <strong>onCompleteSwipe </strong>method just increment the index and set the default position to next card.</p><p>Now we can modify the constructor to use this methods:</p><pre>//import liraries<br>import React, { Component } from &#39;react&#39;;<br>import {<br>   View,<br>   StyleSheet,<br>   Dimensions,<br>   Animated,<br>   PanResponder<br>}</pre><pre>const SCREEN_WIDTH = Dimensions.get(&#39;window&#39;).width;<br>const <strong>SWIPE_THRESHOLD </strong>= SCREEN_WIDTH * 0.40;</pre><pre>...</pre><pre>constructor(props) {<br>   super(props);</pre><pre>   const position = new Animated.ValueXY();<br>   const panResponder = PanResponder.create({<br>      onStartShouldSetPanResponder: () =&gt; true,<br>      onPanResponderMove: (event, gesture) =&gt; {<br>         position.setValue({ x: gesture.dx, y: gesture.dy });<br>      },<br>      onPanResponderRelease: (event, gesture) =&gt; {<br>         if (gesture.dx &gt; <strong>SWIPE_THRESHOLD</strong>)<br>            this.<strong>completeSwipe</strong>(&#39;right&#39;);<br>         else if (gesture.dx &lt; -<strong>SWIPE_THRESHOLD</strong>)<br>            this.<strong>completeSwipe</strong>(&#39;left&#39;);<br>         else<br>            this.<strong>resetPosition</strong>();<br>      }<br>   });</pre><pre>   this.state = { panResponder, position, index: 0 };<br>}</pre><pre>...</pre><p>The <strong>SWIPE_THRESHOLD </strong>is a constant to calculate how far user can drag the card without let it go and bring another card to top.</p><p>Almost done, we must have this:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FTR2USlUX_T0%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DTR2USlUX_T0&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FTR2USlUX_T0%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/6c1f79e12997d916af22b07353869178/href">https://medium.com/media/6c1f79e12997d916af22b07353869178/href</a></iframe><p>6 — Final touching</p><p>Now let’s make the next card move up smoothly.</p><p>Add Animation on resetPosition method:</p><pre>...</pre><pre>resetPosition() {<br>   Animated.spring(this.state.position, {<br>      toValue: { x: 0, y: 0 }<br>   }).start();<br>}</pre><pre>...</pre><p>Import two components <strong>LayoutAnimation </strong>and <strong>UIManager</strong></p><pre>//import liraries</pre><pre>import React, { Component } from &#39;react&#39;;<br>import {<br>   View,<br>   StyleSheet,<br>   Dimensions,<br>   Animated,<br>   PanResponder,<br>   <strong>LayoutAnimation,<br>   UIManager</strong><br>} from &#39;react-native&#39;;</pre><p>And use on <strong>componentWillUpdate </strong>lifecycle method:</p><pre>... </pre><pre>componentWillUpdate() {<br>   UIManager.setLayoutAnimationEnabledExperimental &amp;&amp; UIManager.setLayoutAnimationEnabledExperimental(true);</pre><pre>   LayoutAnimation.spring();<br>}</pre><pre>...</pre><p>Final version:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F2jAUAnDM99A%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D2jAUAnDM99A&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F2jAUAnDM99A%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/a88ab46df2d16fc19e50f8fa32ced4e4/href">https://medium.com/media/a88ab46df2d16fc19e50f8fa32ced4e4/href</a></iframe><p>Well, I know it was a big post, but you can clone the project on GitHub and use this post to understand what I’ve done in each step. If you have any question let me know!</p><p>Thanks for reading!</p><ul><li><a href="https://github.com/lblima/react-native-swipeit">lblima/react-native-swipeit</a></li><li><a href="https://react-native-training.github.io/react-native-elements/docs/0.19.0/getting_started.html">Getting Started · React Native Elements</a></li><li><a href="https://github.com/react-native-training/react-native-elements">GitHub - react-native-training/react-native-elements: Stub repo of https://github.com/react-native-elements/react-native-elements to maintain google links</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8fa36ce6f050" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native tips — Using Animated and PanResponder components to interact with user gestures]]></title>
            <link>https://medium.com/@leonardobrunolima/react-native-tips-using-animated-and-panresponder-components-to-interact-with-user-gestures-4620bf27b9e4?source=rss-42ccfccbb437------2</link>
            <guid isPermaLink="false">https://medium.com/p/4620bf27b9e4</guid>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[mobile]]></category>
            <dc:creator><![CDATA[Leonardo Bruno Lima]]></dc:creator>
            <pubDate>Wed, 29 Aug 2018 16:14:53 GMT</pubDate>
            <atom:updated>2018-08-29T19:42:15.521Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OeS7A1z_FCa-kjNHj5Ee-g.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/W1B2LpQOBxA?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Brooke Lark</a> on <a href="https://unsplash.com/search/photos/touching-water?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Hi guys! One of the most important thing in a mobile app is understand and interact with user gestures. In React Native we have many ways to do this, but I will show in this post a component call <strong>PanResponder </strong>that is responsible for track user gestures and once a gesture is detected I will move an element on screen using another component called <strong>Animated</strong>.</p><p><em>You can see how to setup the dev environment here: </em><a href="https://medium.com/@leonardobrunolima/react-native-tips-setting-up-your-development-environment-for-windows-d326635604ea?source=linkShare-42ccfccbb437-1535561576"><em>https://medium.com/@leonardobrunolima/react-native-tips-setting-up-your-development-environment-for-windows-d326635604ea?source=linkShare-42ccfccbb437-1535561576</em></a></p><p>Let’s get started creating a new project using react-native cli:</p><pre>$ react-native init AnimatedBall --version <strong>0.55.4</strong></pre><p>Now, add a new folder on root path called <strong>src </strong>and add a new file called <strong>Ball.js</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/364/1*8dOUbrbf6Br2ZuT8I1Y16w.png" /></figure><p>Change the Ball component to show a small black ball on screen:</p><pre>//import liraries<br>import React, { Component } from &#39;react&#39;;<br>import { View, StyleSheet } from &#39;react-native&#39;;</pre><pre>// create a component<br>class Ball extends Component {<br>   render() {<br>      return (<br>         &lt;View style={styles.ball} /&gt;<br>      );<br>   }<br>}</pre><pre>// define your styles<br>const styles = StyleSheet.create({<br>   ball: {<br>      height: 80,<br>      width: 80,<br>      borderColor: &#39;black&#39;,<br>      borderRadius: 40,<br>      borderWidth: 40<br>   },<br>});</pre><pre>//make this component available to the app<br>export default Ball;</pre><p>On App.js import and call the Ball component:</p><pre>import React, { Component } from &#39;react&#39;;<br>import {<br>   StyleSheet,<br>   View<br>} from &#39;react-native&#39;;</pre><pre><strong>import Ball from &#39;./src/Ball&#39;;</strong></pre><pre>export default class App extends Component {<br>   render() {<br>      return (<br>         &lt;View style={styles.container}&gt;<br><strong>            &lt;Ball /&gt;</strong><br>         &lt;/View&gt;<br>      );<br>   }<br>}</pre><pre>const styles = StyleSheet.create({<br>   container: {<br>      flex: 1,<br>      justifyContent: &#39;center&#39;,<br>      alignItems: &#39;center&#39;,<br>      backgroundColor: &#39;#F5FCFF&#39;,<br>   }<br>});</pre><p>It should look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/389/1*FFx4fAnO-ihSFqRgdZehcg.png" /></figure><p>Now let’s get the user gestures using <strong>PanResponder </strong>component. You can see the full documentation here: <a href="https://facebook.github.io/react-native/docs/0.56/panresponder">https://facebook.github.io/react-native/docs/0.56/panresponder</a></p><p>Import <strong>PanResponder </strong>component on Ball and create a new instance on constructor:</p><pre>//import liraries<br>import React, { Component } from &#39;react&#39;;<br>import { View, StyleSheet, <strong>PanResponder </strong>} from &#39;react-native&#39;;</pre><pre>// create a component<br>class Ball extends Component {<br>   constructor(props) {<br>      super(props);</pre><pre>    <strong>  </strong>const panResponder = PanResponder.create({<br>         <strong>onStartShouldSetPanResponder</strong>: () =&gt; true,<br>         <strong>onPanResponderMove</strong>: (event, <strong>gesture</strong>) =&gt; {<br>            console.log(<strong>gesture</strong>);<br>         }<br>      });</pre><pre>      this.state = { <strong>panResponder </strong>};<br>   }</pre><pre>   render() {<br>      return (<br>         &lt;View <br>            style={styles.ball}<br>            <strong>{...this.state.panResponder.panHandlers}</strong><br>         /&gt;<br>      );<br>   }<br>}</pre><pre>...</pre><pre>export default Ball2;</pre><p>The code above create a new instance of <strong>PanResponder </strong>and allows any component attached to it to track user gestures. On event <strong>onPanResponderMove </strong>you can see the result on console when you try to drag the boll on screen:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/945/1*7Axj7KzNNRZ258Z9eO3BKQ.png" /></figure><p>Now we have the gesture and we can grab the position X and Y from it to animate the ball. Import the <strong>Animated </strong>component and create a new instance of <strong>position</strong>. In order to animate a component we have to use the <strong>Animated.View, </strong>so every component inside it will be animated. In our case we just renamed the <strong>View </strong>to <strong>Animated.View</strong>.</p><pre>//import liraries<br>import React, { Component } from &#39;react&#39;;<br>import { View, StyleSheet, PanResponder, <strong>Animated</strong> } from &#39;react-native&#39;;</pre><pre>// create a component<br>class Ball extends Component {<br>   constructor(props) {<br>      super(props);</pre><pre><strong>      const position = new Animated.ValueXY();</strong><br>      const panResponder = PanResponder.create({<br>         onStartShouldSetPanResponder: () =&gt; true,<br>         onPanResponderMove: (event, gesture) =&gt; {<br>            position.setValue({ x: gesture.dx, y: gesture.dy });<br>         }<br>      });<br>   <br>      this.state = { panResponder, position };<br>   }</pre><pre>   render() {<br>      let handles = this.state.panResponder.panHandlers;<br>      return (<br>         &lt;<strong>Animated.View</strong><br>            style={[styles.ball, <strong>this.state.position.getLayout()</strong>]}<br>            {...handles}<br>         /&gt;<br>      );<br>   }<br>}</pre><pre>...</pre><pre>export default Ball;</pre><p>Now you can drag the ball around the screen. This is a simple example, you can interesting things with <strong>PanResponder </strong>and <strong>Animated </strong>components.</p><p>That’s all folks,</p><p>Thanks for reading!</p><ul><li><a href="https://github.com/lblima/react-native-animated-ball">lblima/react-native-animated-ball</a></li><li><a href="https://facebook.github.io/react-native/docs/0.56/animated">Animated · React Native</a></li><li><a href="https://facebook.github.io/react-native/docs/0.56/panresponder">PanResponder · React Native</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4620bf27b9e4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native tips — Setting Up your Development Environment (for Windows)]]></title>
            <link>https://medium.com/@leonardobrunolima/react-native-tips-setting-up-your-development-environment-for-windows-d326635604ea?source=rss-42ccfccbb437------2</link>
            <guid isPermaLink="false">https://medium.com/p/d326635604ea</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[mobile-apps]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <dc:creator><![CDATA[Leonardo Bruno Lima]]></dc:creator>
            <pubDate>Tue, 21 Aug 2018 01:52:40 GMT</pubDate>
            <atom:updated>2018-08-21T11:49:50.522Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/450/1*nMjitWGmTtWh_o8YuyJ0sQ.jpeg" /></figure><p>Hi guys! In this article I will talk about how to set up your development environment on Windows to use React Native and Android Studio.</p><p>These are the tools we need on an development environment (Windows):</p><ul><li>Visual Studio Code (you can use any other editor or IDE)</li><li>Android Studio</li><li>Built-in emulator in Android Studio</li><li>Node Package Manager (NPM)</li><li>Node.js (Version 8 or newer)</li><li>React Native command line interface (React Native CLI)</li><li>Java Development Kit (JDK 8 or newer)</li></ul><blockquote><em>There are two ways to start a React Native Project: Using the React Native CLI or using </em><a href="https://github.com/react-community/create-react-native-app"><em>Create React Native App</em></a><em>. If you chose the second option, you don’t need to configure anything, just start coding and be happy. I will talk about the pros and cons of these two options.</em></blockquote><h4>Step 1: Install Node</h4><ul><li>Download and install the latest version of Node.js from <a href="https://nodejs.org/en">https://nodejs.org/en</a>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yIP9v2ZFlwH5lf1cL0zfDQ.png" /></figure><p>I recommend you install the LTS version.</p><h4>Step 2: Install Java SDK</h4><ul><li>Download and install the latest version of Java SDK from <a href="http://www.oracle.com/technetwork/pt/java/javase/downloads/jdk8-downloads-2133151.html">http://www.oracle.com/technetwork/pt/java/javase/downloads/jdk8-downloads-2133151.html</a>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/752/1*o4HqYD4MNXrSaKz6tv0ejw.png" /></figure><h4>Step 3: Install Python 2</h4><ul><li>Download and install Python 2.7.15 from <a href="https://www.python.org/downloads/windows/">https://www.python.org/downloads/windows/</a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*F0Vylc1UKH7yIaZGLBdBSQ.png" /></figure><blockquote>You can use <a href="https://chocolatey.org/"><strong>Chocolatey </strong></a>to install Node, Python2 and Java SDK together, to do it install Chocolatey and just type:</blockquote><pre>$ choco install -y nodejs.install python2 jdk8</pre><h4>Step 4: Install Android Studio</h4><ul><li>Download and install the latest version of Android Studio for Windows from <a href="https://developer.android.com/studio/">https://developer.android.com/studio/</a></li></ul><p>The Android Studio installs the latest Android SDK by default and React Native requires Android 6.0 (Marshmallow) SDK or higher.</p><p>Once installed you can go to Tools &gt; SDK Manager and choose any version above 6.0.</p><blockquote>If you didn’t have any project yet (our case), you should go to Configure &gt; SDK Manager:</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*a7Y7CAnfSj111uklXxeG9A.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Cj_-v33lwokHiB_6Sdnxhw.png" /></figure><p>Now, go to SDK Tools tab and choose these options below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LnEUBBdL-CwXdQHmwCAEpQ.png" /></figure><p>You will need the <strong>Intel x86 Emulator Accelerator (HAXM installer)</strong> to run the emulator on Windows. For more information, please refer to the following link: <a href="https://github.com/intel/haxm/wiki/Installation-Instructions-on-Windows">https://github.com/intel/haxm/wiki/Installation-Instructions-on-Windows</a>.</p><blockquote>If you have Hyper-V feature enabled, you need to disable it (I know…)</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/561/1*IaNTDDQwopkmHP0W3B9Jrg.png" /></figure><p>Make sure if JDK location is selected. Go to File &gt; Other Settings &gt; Default Project Structure:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*y84l6XbV3huPmLUnH83rdA.png" /></figure><h4>Step 5: Configure environment variables</h4><ul><li>Add the ANDROID_HOME variable:</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_r7kl82OmnCLFX9cZ9Q0vQ.png" /></figure><ul><li>Add JAVA_HOME variable:</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8dX6FK9x_A0MGPG5zvJ15g.png" /></figure><ul><li>Make sure you add on <strong>Path </strong>variable the path for Java SDK and Android platform tools:</li></ul><p><em>C:\Users\{your_user_name}\AppData\Local\Android\Sdk\platform-tools<br>C:\Program Files\Java\jdk1.8.0_181\bin</em></p><h4>Step 6: Install React Native CLI and create the first project</h4><pre>$ npm install -g react-native-cli</pre><p>Finally you can create your first React Native application by running the following command in your workspace location:</p><pre>$ react-native init myFirstReactNativeApp --version 0.55.4</pre><blockquote>The latest version, 0.56, has some issues on Windows, so, use 0.55.4</blockquote><p>This will create the following project structure:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/713/1*r_cxSBjWucTm7e_qCJLNsg.png" /></figure><p>Before run you project we have to configure the <strong>emulator</strong>. Take a look at the folder <strong>android</strong>. We have to open it on Android Studio:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ODsnbGOvysQH8Xfaw8ogLg.png" /></figure><p>Click on “Open an existing Android Studio project”, go to your project and select the folder <strong>android</strong> and click Ok.</p><blockquote>If Gradle ask you to update, click on “Don’t remind me again for this project”</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/646/1*NvyOPw-yVcXtDPHwxCksUA.png" /></figure><p>Now, go to Tools &gt; ADV Manager:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/862/1*liVpn-Z1lxIGfHdQHqzGTQ.png" /></figure><p>On this screen, click on “Create Virtual Device”:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nu36hwKKBbbDOs_9GYVNsQ.png" /></figure><p>You can select any device on the list and click next:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uBXrZEOFjHiAZjv3M0W6nA.png" /></figure><p>On the next screen select the System Image. Click on download to download the selected image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wqnUE-N1WPPyvENUzkIhfg.png" /></figure><p>Follow the instructions and finish. After that you can see the created virtual device on the list.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tO4y88RDvmYHWEl-wiaUOg.png" /></figure><p>Now, just click on play and you can see the emulator running:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/562/1*ctkMwAvNDlEvLBno1HBnMg.png" /></figure><p>It’s time to run your project and see it on emulator. Just type:</p><pre>$ react-native run-android</pre><p>And voilà!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6NuboqRxA8OBoEylCEA8Ng.png" /></figure><p>Now you can edit you app and reload the emulator to see the changes, just type “ctrl + m” and click Reload:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/432/1*i5mx-fXR3Qzv9tmaizpUPg.png" /></figure><p>That´s all folks, I hope you can enjoy your first React Native App. Let me know if you have any question or if these steps didn’t work for you.</p><p>Thanks for reading!</p><p><a href="https://facebook.github.io/react-native/docs/getting-started.html">Getting Started · React Native</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d326635604ea" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React tips — Working with relative path using create-react-app]]></title>
            <link>https://medium.com/@leonardobrunolima/react-tips-working-with-relative-path-using-create-react-app-fe55c5f97a21?source=rss-42ccfccbb437------2</link>
            <guid isPermaLink="false">https://medium.com/p/fe55c5f97a21</guid>
            <category><![CDATA[babel]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[babeljs]]></category>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Leonardo Bruno Lima]]></dc:creator>
            <pubDate>Fri, 03 Aug 2018 14:27:35 GMT</pubDate>
            <atom:updated>2018-08-03T14:27:35.356Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ovhZJcgKs_KXeLfs_4aFHw.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/zS4lUqLEiNA?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Jack Anstey</a> on <a href="https://unsplash.com/search/photos/path?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Deal with relative path is not a complex thing, but when we are creating an application using<strong> </strong><a href="https://github.com/facebook/create-react-app"><strong>create-react-app</strong></a> sometimes it could be a tough work. To configure paths and other configurations we usually use <a href="http://babeljs.io/"><strong>Babel</strong></a>, but Babel is not available to edit when we create an app using create-react-app, unless you <a href="https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-eject"><strong>eject</strong></a>.</p><p>In this post I will show you how to change path configuration using Babel without eject your application. Let’s create an app using create-react-app called react-relative-path:</p><pre>$ create-react-app react-relative-path</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/762/1*zgmGfy8NxeOy7SVGOOObXA.png" /></figure><p>Now, I will create some folders, add some components and add references to each other.</p><p>First create a folder called <strong>Api </strong>and add a Item.js file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/748/1*sTp3YqHvH3m9sHYNL89yhg.png" /></figure><p>And a folder called <strong>Components </strong>with subfolders <strong>ListItems </strong>and <strong>Item </strong>as we can see below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/936/1*yxnGCDUBAHxKxHUUdR6j4w.png" /></figure><p>On <strong>App.js</strong> we just import and use the component <strong>Item</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fYM7v7yx5wBDq0SV6zMhvw.png" /></figure><p>The result should be like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/878/1*dfSTd9WUU4Gbm2pG7OHryw.png" /></figure><p>Alright, everything is working well, but if you decide to change the folder structure? Remember the path inside Item component:</p><pre>import item from &#39;../../../Api/Item&#39;;</pre><p>If you decide to remove the folder <strong>ListItems </strong>and let only the folder <strong>Item</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/939/1*fC6lDkKMRrkQiGlZddEl3A.png" /></figure><p>Now we have an error:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Puz0y9SbAD9ac1lO3pVgZg.png" /></figure><p>We have to change all paths inside all components inside <strong>Item</strong> folder, of course in this case is easy, but imagine you have many components, I could be hard to maintain.</p><p>In order to deal with this situation, we can use some third-part components. This first we need to install is the <a href="https://github.com/timarney/react-app-rewired"><strong>react-app-rewired</strong></a>. This component allow us to change webpack configuration without using ‘eject’ and without creating a fork of the react-scripts:</p><pre>npm i --dev react-app-rewired</pre><p>The second component the <a href="https://github.com/entwicklerstube/babel-plugin-root-import"><strong>babel-plugin-root-import</strong></a>, that allow us to import components using root based paths.</p><pre>npm i --dev babel-plugin-root-import</pre><p>Alright, now we need create a file on root folder called <strong>config-overrides.js</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FEL4goRiBZ-aFhrwpEyfRA.png" /></figure><p>In this file we are going to configure basically two things: the root prefix and root sufix. The <strong>rootPathPrefix </strong>is the character we would like to use to refer the root folder and the <strong>rootPathSuffix </strong>is the name of the root folder.</p><p>Next step is change the <strong>package.json</strong> file to use the <strong>react-app-rewired</strong> (<strong>except the eject script</strong>):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/927/1*-FviKshZcnU3FZGDv42CEg.png" /></figure><p>Finally let’s change the <strong>Item </strong>component to use the new prefix “~”:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/921/1*UliW1VilbXPucgIWRLURgg.png" /></figure><p>And now it’s working again:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/815/1*0E5X3XdsqyvFdnKU-_BQAQ.png" /></figure><p>If you are using VSCode, I have one more tip. After these changes we’ve made, you can see we lost the intellisense for paths. So, after you type ~/… the VSCode will not complete or suggest the available path. To fix this, we need to add a file called <strong>jsconfig.json </strong>and add some configs:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/899/1*N193FrlXEDz-iivKTbx8eg.png" /></figure><p>The most important part is the “paths” section. In this section we instruct the VSCode to map the path “~/” to “./src” and after that the intellisense will work again:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DZ6uf8wlD9sJOmtkalUhiQ.png" /></figure><p>You can clone this project here: <a href="https://github.com/lblima/react-relative-path">https://github.com/lblima/react-relative-path</a></p><p>That’s all folks,</p><p>Thanks for reading!</p><ul><li><a href="https://github.com/timarney/react-app-rewired">timarney/react-app-rewired</a></li><li><a href="https://github.com/entwicklerstube/babel-plugin-root-import">entwicklerstube/babel-plugin-root-import</a></li><li><a href="https://github.com/lblima/react-relative-path">lblima/react-relative-path</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fe55c5f97a21" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React tips — Drag and Drop using Point Events]]></title>
            <link>https://medium.com/@leonardobrunolima/react-tips-drag-and-drop-using-point-events-2ba33cf7653e?source=rss-42ccfccbb437------2</link>
            <guid isPermaLink="false">https://medium.com/p/2ba33cf7653e</guid>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[pointevents]]></category>
            <category><![CDATA[drag-and-drop]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Leonardo Bruno Lima]]></dc:creator>
            <pubDate>Fri, 20 Jul 2018 19:35:58 GMT</pubDate>
            <atom:updated>2018-07-21T03:55:29.436Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZzC_xl9i78khe-XBbqupVg.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/CbgXKSd3qkQ?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Guillaume de Germain</a> on <a href="https://unsplash.com/search/photos/draw?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>The latest release (16.4.1) of React added support for a good feature: pointer events. But, it will only work in browsers that support the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events">Pointer Events specification</a>. If your want your application runs on all browser, I recommend using a third-party pointer events polyfill.</p><p>The event types available in React DOM are:</p><ul><li>onPointerDown</li><li>onPointerMove</li><li>onPointerUp</li><li>onPointerCancel</li><li>onGotPointerCapture</li><li>onLostPointerCapture</li><li>onPointerEnter</li><li>onPointerLeave</li><li>onPointerOver</li><li>onPointerOut</li></ul><p>Let’s do an example based on React blog. First thing to do is create a new app using create-react-app.</p><pre>$ create-react-app react-drag-drop-pointevents</pre><p>Feel free to change some texts, but the most important is create a new component called <strong>DragItem</strong>.</p><pre>import React from &#39;react&#39;;</pre><pre>export default class <strong>DragItem </strong>extends React.Component {</pre><pre>}</pre><p>And now call this component on App.js:</p><pre>import React, { Component } from &#39;react&#39;;<br>import logo from &#39;./logo.svg&#39;;<br>import &#39;./App.css&#39;;</pre><pre>import <strong>DragItem</strong> from &#39;./DragItem&#39;;</pre><pre>class App extends Component {<br>   render() {<br>      return (<br>         &lt;div className=&quot;App&quot;&gt;<br>            &lt;header className=&quot;App-header&quot;&gt;<br>               &lt;img src={logo} className=&quot;App-logo&quot; alt=&quot;logo&quot; /&gt;<br>               &lt;h1 className=&quot;App-title&quot;&gt;Welcome to React sample of Point Events&lt;/h1&gt;<br>            &lt;/header&gt;<br>            &lt;div className=&quot;App-intro&quot;&gt;<br>               <strong>&lt;DragItem /&gt;</strong><br>            &lt;/div&gt;<br>         &lt;/div&gt;);<br>   }<br>}</pre><pre>export default App;</pre><p>Alright, now let’s work on DragItem component:</p><pre>import React from &#39;react&#39;;</pre><pre>const CIRCLE_DIAMETER = 100;</pre><pre>export default class <strong>DragItem </strong>extends React.Component {<br>   state = {<br>      gotCapture: false,<br>      circleLeft: 500,<br>      circleTop: 100<br>   };</pre><pre>isDragging = false;<br>   previousLeft = 0;<br>   previousTop = 0;<br> <br>   onDown = e =&gt; {<br>      this.isDragging = true;<br>      e.target.setPointerCapture(e.pointerId);<br>      this.getDelta(e);<br>   };</pre><pre><strong>onMove </strong>= e =&gt; {<br>      if (!this.isDragging) {<br>         return;<br>      }<br>  <br>      const {left, top} = this.getDelta(e);<br>      this.setState(({circleLeft, circleTop}) =&gt; ({<br>         circleLeft: circleLeft + left,<br>         circleTop: circleTop + top<br>      }));<br>   };</pre><pre>   <strong>onUp </strong>= e =&gt; (this.isDragging = false);</pre><pre>   <strong>onGotCapture </strong>= e =&gt; this.setState({gotCapture: true});</pre><pre>   <strong>onLostCapture </strong>= e =&gt; this.setState({gotCapture: false});</pre><pre>   getDelta = e =&gt; {<br>      const left = e.pageX;<br>      const top = e.pageY;<br>      const delta = {<br>         left: left - this.previousLeft,<br>         top: top - this.previousTop,<br>      };<br>      this.previousLeft = left;<br>      this.previousTop = top;<br>   <br>      return delta;<br>   };</pre><pre>   render() {<br>      const {gotCapture, circleLeft, circleTop} = this.state;</pre><pre>      const boxStyle = {<br>         border: &#39;2px solid #cccccc&#39;,<br>         margin: &#39;10px 0 20px&#39;,<br>         minHeight: 400,<br>         width: &#39;100%&#39;,<br>         position: &#39;relative&#39;,<br>      };</pre><pre>      const circleStyle = {<br>         width: CIRCLE_DIAMETER,<br>         height: CIRCLE_DIAMETER,<br>         borderRadius: CIRCLE_DIAMETER / 2,<br>         position: &#39;absolute&#39;,<br>         left: circleLeft,<br>         top: circleTop,<br>         backgroundColor: gotCapture ? &#39;red&#39; : &#39;green&#39;,<br>         touchAction: &#39;none&#39;,<br>      };</pre><pre>      return (<br>         &lt;div style={boxStyle}&gt;<br>            &lt;div<br>               style={circleStyle}<br>               onPointerDown={this.onDown}<br>               onPointerMove={this.onMove}<br>               onPointerUp={this.onUp}<br>               onPointerCancel={this.onUp}<br>               onGotPointerCapture={this.onGotCapture}<br>               onLostPointerCapture={this.onLostCapture}<br>            /&gt;<br>         &lt;/div&gt;<br>      );<br>   }<br>}</pre><p>It should look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2QmorUnLfpqwEQxJeaYGPg.png" /></figure><p>Now you can try to move the circle around the screen. Enjoy!</p><p>That’s all folks,</p><p>Thanks for reading!</p><ul><li><a href="https://github.com/lblima/react-drag-drop-pointevents">lblima/react-drag-drop-pointevents</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events">Pointer events</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2ba33cf7653e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Javascript tips — Object freeze vs const]]></title>
            <link>https://medium.com/@leonardobrunolima/javascript-tips-object-freeze-vs-const-4cc0fd30449a?source=rss-42ccfccbb437------2</link>
            <guid isPermaLink="false">https://medium.com/p/4cc0fd30449a</guid>
            <category><![CDATA[freez]]></category>
            <category><![CDATA[es6]]></category>
            <category><![CDATA[const]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Leonardo Bruno Lima]]></dc:creator>
            <pubDate>Fri, 13 Jul 2018 13:40:45 GMT</pubDate>
            <atom:updated>2018-07-13T13:40:45.044Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*X_9SH4p5n0Ft2XJriwTrOQ.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/6nqmBPAGeyc?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Aaron Burden</a> on <a href="https://unsplash.com/search/photos/freeze?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>The first thing I would like to make clear is there’s no relation and comparison between them, they are two completely different things.</p><h3>const</h3><p>The <strong>const </strong>keyword applies to <strong>bindings</strong> and creates an <strong>immutable binding</strong>. In other words, you cannot assign a new value to the binding.</p><pre>let person = {<br>   name: &quot;Leonardo&quot;<br>};</pre><pre>console.log(person); //output { name: &#39;Leonardo&#39; }</pre><p>Now add another object and assign to the person object:</p><pre>let person = {<br>   name: &quot;Leonardo&quot;<br>};</pre><pre>let animal = {<br>   species: &quot;snake&quot;<br>};</pre><pre><strong>person = animal;</strong></pre><pre>console.log(person); //output { species: &#39;snake&#39; }</pre><p>Ok, if you change the person object declaration to be a constant the code above won’t work anymore:</p><pre>const person = {<br>   name: &quot;Leonardo&quot;<br>};</pre><pre>let animal = {<br>   species: &quot;snake&quot;<br>};</pre><pre>person = animal; // <strong>ERROR &quot;person&quot; is read-only</strong></pre><pre>console.log(person);</pre><p>But you can change its values:</p><pre>const person = {<br>   name: &quot;Leonardo&quot;<br>};</pre><pre>let animal = { <br>   species: &quot;snake&quot;<br>};</pre><pre>person.name = &quot;Lima&quot;;</pre><pre>console.log(person); //output { name: &#39;Lima&#39; }</pre><p>Make sense right?</p><h3><strong>Object.freeze</strong></h3><p>It works on <strong>values </strong>and it makes an object immutable, i.e. you cannot change, add or delete its properties, but you can assign another instance.</p><pre>let person = {<br>   name: &quot;Leonardo&quot;<br>};</pre><pre>let animal = {<br>   species: &quot;snake&quot;<br>};</pre><pre><strong>Object.freeze(person);</strong></pre><pre>person = animal;</pre><pre>console.log(person); { species: &#39;snake&#39; }</pre><p>As you can see above, even using Object.freeze I could assign animal object to to person. Now, let’s try change some property of the person:</p><pre>let person = {<br>   name: &quot;Leonardo&quot;<br>};</pre><pre>let animal = {<br>   species: &quot;snake&quot;<br>};</pre><pre>Object.freeze(person);</pre><pre><strong>person.name = &quot;Lima&quot;; //TypeError: Cannot assign to read only property &#39;name&#39; of object</strong></pre><pre>console.log(person);</pre><p>As you can see, we cannot change any value of the object once it’s frozen, it’s <strong>immutable</strong>. The only problem is it isn’t deep freeze.</p><pre>let person = {<br>   name: &quot;Leonardo&quot;,<br>   profession: {<br>      name: &quot;developer&quot;<br>   }<br>};</pre><pre>Object.freeze(person);</pre><pre>person.profession.name = &quot;doctor&quot;;</pre><pre>console.log(person); //output { name: &#39;Leonardo&#39;, <strong>profession: { name: &#39;doctor&#39; }</strong> }</pre><p>If you want make sure the object is deep frozen you have to create a recursive function to freeze each property which is of type object:</p><pre>function deepFreeze(object) {<br>   let propNames = Object.getOwnPropertyNames(object);</pre><pre>   for (let name of propNames) {<br>      let value = object[name];<br>      object[name] = value &amp;&amp; typeof value === &quot;object&quot; ?  <br>                           deepFreeze(value) : value;<br>   }</pre><pre>   return Object.freeze(object);<br>}</pre><pre>let person = {<br>   name: &quot;Leonardo&quot;,<br>   profession: {<br>      name: &quot;developer&quot;<br>   }<br>};</pre><pre><strong>deepFreeze(person);</strong></pre><pre>person.profession.name = &quot;doctor&quot;; // <strong>TypeError: Cannot assign to read only property &#39;name&#39; of object</strong></pre><pre>console.log(person);</pre><p>That’s all folks,</p><p>Thanks for reading!</p><ul><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze">Object.freeze() - JavaScript | MDN</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const">const - JavaScript | MDN</a></li><li><a href="https://medium.com/@leonardobrunolima/javascript-tips-var-let-const-and-hoisting-8ddf00aa47e">Javascript tips — var, let, const and hoisting</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4cc0fd30449a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React tips — Validating Props with PropTypes]]></title>
            <link>https://medium.com/@leonardobrunolima/react-tips-validating-props-with-proptypes-24c64d58f4c0?source=rss-42ccfccbb437------2</link>
            <guid isPermaLink="false">https://medium.com/p/24c64d58f4c0</guid>
            <category><![CDATA[prop-types]]></category>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[validation]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Leonardo Bruno Lima]]></dc:creator>
            <pubDate>Fri, 01 Jun 2018 17:18:42 GMT</pubDate>
            <atom:updated>2018-06-01T17:18:42.013Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e7O7A5rM79ng6b8Dc3EbEg.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/RLw-UC03Gwc?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Glenn Carstens-Peters</a> on <a href="https://unsplash.com/search/photos/validation?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>React PropTypes are a very good way to help you catching bugs by validating data types of values passed through props. You can also flag props as required or set default values.</p><p>Picture the situation where you just picked up a component written by another developer and have to figure out which properties the component needs, which ones are required, what is the correct type for each one, etc. If he used <strong>Proptypes</strong>, he made your life easier in this situation.</p><blockquote>React.PropTypes has moved into a different package since React v15.5. Use the prop-types library instead.</blockquote><p>Let’s see a example creating a Customer component:</p><pre>import React from &#39;react&#39;;<br><strong>import PropTypes from &#39;prop-types&#39;;</strong></pre><pre>const Customer = (props) =&gt; &lt;div&gt; <br>  &lt;h1&gt;{props.firstName} {props.lastName}&lt;/h1&gt;<br>  &lt;p&gt;Age: {props.age}&lt;/p&gt;<br>&lt;/div&gt;;</pre><pre>Customer.propTypes = {<br>  firstName:PropTypes.string,<br>  lastName:PropTypes.string,<br>  age:PropTypes.number<br>};</pre><pre>export default Customer;</pre><p>Now let’s use this component:</p><pre>...</pre><pre>&lt;Customer <br>   firstName=&#39;Leo&#39;<br>   lastName=&#39;Lima&#39;<br>   age=41<br>/&gt;</pre><pre>...</pre><p>Everything is fine here, but suppose you pass a string on age prop:</p><pre>...</pre><pre>&lt;Customer <br>   firstName=&#39;Leo&#39;<br>   lastName=&#39;Lima&#39;<br>   age=&#39;41&#39;<br>/&gt;</pre><pre>...</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/967/1*2hNYLJwWy8HmtCIx6IlJtA.png" /></figure><p>As you can see, once I passed a string instead a number, I received a error. Now, suppose we didn’t pass the <strong>age </strong>prop, what will happen?</p><pre>...</pre><pre>&lt;Customer <br>   firstName=&#39;Leo&#39;<br>   lastName=&#39;Lima&#39;<br>/&gt;</pre><pre>...</pre><p>Nothing happens here, because this prop isn’t required. So, let’s make it required:</p><pre>import React from &#39;react&#39;;<br><strong>import PropTypes from &#39;prop-types&#39;;</strong>const Customer = (props) =&gt; &lt;div&gt; <br>  &lt;h1&gt;{props.firstName} {props.lastName}&lt;/h1&gt;<br>  &lt;p&gt;Age: {props.age}&lt;/p&gt;<br>&lt;/div&gt;;</pre><pre>const Customer = (props) =&gt; &lt;div&gt; <br>  &lt;h1&gt;{props.firstName} {props.lastName}&lt;/h1&gt;<br>  &lt;p&gt;Age: {props.age}&lt;/p&gt;<br>&lt;/div&gt;;</pre><pre>Customer.propTypes = {<br>  firstName:PropTypes.string,<br>  lastName:PropTypes.string,<br>  age:PropTypes.number.<strong>isRequired</strong><br>};</pre><pre>export default Customer;</pre><p>Now, if run the app you will see an error:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oAd6bPB2nZNxTlIbS76tpg.png" /></figure><p>Ok, let’s add another prop to our component called Gender and add a proptype <strong>OneOf</strong>:</p><pre>import React from &#39;react&#39;;<br><strong>import PropTypes from &#39;prop-types&#39;;</strong></pre><pre>const Customer = (props) =&gt; &lt;div&gt; <br>  &lt;h1&gt;{props.firstName} {props.lastName}&lt;/h1&gt;<br>  &lt;p&gt;Age: {props.age}&lt;/p&gt;<br>  &lt;p&gt;Gender: {props.gender}&lt;/p&gt;<br>&lt;/div&gt;;</pre><pre>Customer.propTypes = {<br>  firstName:PropTypes.string,<br>  lastName:PropTypes.string,<br>  age:PropTypes.number.isRequired<strong>,<br></strong>  gender: PropTypes.<strong>oneOf</strong>([&#39;female&#39;, &#39;male&#39;])<br>};</pre><pre>export default Customer;</pre><p>Using <strong>oneOf</strong> we can specify a range of valid Prop Values, in this case I will only accept male and female strings. If I pass anything different I will get an error:</p><pre>...</pre><pre>&lt;Customer <br>   firstName=&#39;Leo&#39;<br>   lastName=&#39;Lima&#39;<br>   age={42}<br>   gender=&#39;other&#39;<br>/&gt;</pre><pre>...</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LCQLViu_UwprZEiDuM3Q3w.png" /></figure><p>As you can see we have many ways to ensure our component will be a valid “state” with PropTypes and there are many other type you can use. You can check here: <a href="https://github.com/facebook/prop-types">https://github.com/facebook/prop-types</a></p><p>If you are moving from React 15.5 you may have a look in this link: <a href="https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-react.proptypes">https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-react.proptypes</a></p><p>That’s all folks,</p><p>Thanks for reading!</p><p><a href="https://github.com/facebook/prop-types">GitHub - facebook/prop-types: Runtime type checking for React props and similar objects</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=24c64d58f4c0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React tips — Testing React Component with Jest + Enzyme — Part 2]]></title>
            <link>https://medium.com/@leonardobrunolima/react-tips-testing-react-component-with-jest-enzyme-part-2-251cce305f6b?source=rss-42ccfccbb437------2</link>
            <guid isPermaLink="false">https://medium.com/p/251cce305f6b</guid>
            <category><![CDATA[unit-testing]]></category>
            <category><![CDATA[enzyme]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[jest]]></category>
            <dc:creator><![CDATA[Leonardo Bruno Lima]]></dc:creator>
            <pubDate>Wed, 30 May 2018 17:18:25 GMT</pubDate>
            <atom:updated>2018-05-30T17:18:25.817Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VXA73wVSv3fOZprqPj-uAA.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/fw7lR3ibfpU?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Dawid Małecki</a> on <a href="https://unsplash.com/search/photos/testing?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>In my last <a href="https://medium.com/@leonardobrunolima/react-tips-testing-react-component-with-jest-enzyme-basics-38a15d5dd72a"><strong><em>post </em></strong></a>I wrote a introduction on testing react component with Jest and Enzyme. In this post I will evolve the last project to introduce more tests to check props and functions/events.</p><p><a href="https://medium.com/@leonardobrunolima/react-tips-testing-react-component-with-jest-enzyme-basics-38a15d5dd72a">React tips — Testing React Component with Jest + Enzyme (basics)</a></p><p>I will assume you have already cloned the project we started in the last post. Now, let’s do some changes on it adding a new component called <strong>BasicInput</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Wi1wL3xPbzmdsRwuIp-46g.png" /></figure><p>It is a very simple functional component that receives some props in order to render a input html object.</p><p>Now let’s test it creating a new test file called <strong>basic-input.test.js:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DED0CBhcSO0RAJ78Ls5Q9g.png" /></figure><p>Basically I’ve imported Enzyme and the component. After that I chose to test two very basic things: test if component renders without crashing and the two props: <strong>placeholder </strong>and <strong>type</strong>.</p><p>To test these props, we can use the <strong>prop </strong>method of Enzyme, it’s very straightforward:</p><pre>const placeholder_text = &#39;type anything here&#39;;</pre><pre>const wrapper = shallow(&lt;BasicInput placeholder={placeholder_text} /&gt;);</pre><pre>expect(wrapper.<strong>prop</strong>(&#39;placeholder&#39;)).toEqual(placeholder_text);</pre><p>Now let’s go back to main component App and change it to use this new component:</p><pre>import React, { Component } from &#39;react&#39;;<br>import logo from &#39;./logo.svg&#39;;<br>import &#39;./App.css&#39;;</pre><pre>import BasicInput from &#39;./components/basic-input&#39;;</pre><pre>class App extends Component {<br>   <strong>constructor() {<br>      super();<br>      this.state = {<br>         basicValue: &#39;&#39;<br>      };<br>      <br>      this.handleBasicInputChanges = this.handleBasicInputChanges.bind(this);<br>}</strong></pre><pre><strong>   handleBasicInputChanges(e) {<br>      this.setState({<br>         basicValue: e.target.value<br>      });<br>   }</strong></pre><pre>   render() {<br>      return (<br>         &lt;div className=&quot;App&quot;&gt;<br>            &lt;header className=&quot;App-header&quot;&gt;<br>               &lt;img src={logo} className=&quot;App-logo&quot; alt=&quot;logo&quot; /&gt;<br>               &lt;h1 className=&quot;App-title&quot;&gt;Welcome to React Basic Tests&lt;/h1&gt;<br>            &lt;/header&gt;<br>           &lt;p className=&quot;App-intro&quot;&gt;<br>             <strong> &lt;BasicInput<br>                 type=&quot;text&quot;<br>                 placeholder=&quot;type something&quot;<br>                 handleChanges={this.handleBasicInputChanges}<br>               /&gt;</strong><br>            &lt;/p&gt;<br>         &lt;/div&gt;<br>      );<br>   }<br>}</pre><pre>export default App;</pre><p>Basically I’ve created a constructor and method to handle the input change. I’ve added the component <strong>BasicInput </strong>to and passed some props. It should look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/673/1*z625pdeW1ptH_2-RRSoc_g.png" /></figure><p>Ok, now let’s change our existing App.test.js to include a test for input changes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ai1rQrzMO0NgKXOstDCw6g.png" /></figure><p>In this part I had to include a new function called <strong>mount</strong>. As you can see, the goal here is to test if the <strong>BasicInput </strong>input changes modifies the state.</p><p><em>Always use </em><strong><em>mount </em></strong><em>if you want full rendering including child components and access to the DOM.</em></p><blockquote><strong>handleBasicInputChanges </strong>is passed to <strong>handleChanges </strong>props</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/791/1*cSjTxqb03dd_J0pyuHhebg.png" /></figure><pre>it(&#39;should change the state after change the input value&#39;, () =&gt; {<br>   const newValue = &#39;testing component&#39;;<br>   const wrapper = mount(&lt;App /&gt;);<br>   const input = wrapper.find(&#39;input&#39;);<br>   <br>   input.<strong>simulate</strong>(&#39;change&#39;, { target: { value: newValue }});<br>   expect(wrapper.state().basicValue).toEqual(newValue);<br>});</pre><p>The only thing we need to do is mouting the App component and find the component we want simulate the event, in this case it will the the input. After that we just verify if the state was changed.</p><p>You can read the Enzyme documentation for more details about the api and how to use it.</p><p>You can clone this project on my GitHub: <a href="https://github.com/lblima/react-basic-tests-with-jest-enzyme">https://github.com/lblima/react-basic-tests-with-jest-enzyme</a></p><p>That’s all folks,</p><p>Thanks for reading!</p><ul><li><a href="https://github.com/airbnb/enzyme">airbnb/enzyme</a></li><li><a href="http://airbnb.io/enzyme/docs/api/">API Reference · Enzyme</a></li><li><a href="https://airbnb.io/projects/enzyme/">Enzyme | Airbnb Engineering</a></li><li><a href="https://github.com/lblima/react-basic-tests-with-jest-enzyme">lblima/react-basic-tests-with-jest-enzyme</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=251cce305f6b" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>