<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Rick1196</title>
    <description>The latest articles on Forem by Rick1196 (@rick1196).</description>
    <link>https://forem.com/rick1196</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%2F404117%2F46dcba52-58eb-45f0-9f4f-acd290f38a80.png</url>
      <title>Forem: Rick1196</title>
      <link>https://forem.com/rick1196</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rick1196"/>
    <language>en</language>
    <item>
      <title>How to debounce a input text on React</title>
      <dc:creator>Rick1196</dc:creator>
      <pubDate>Mon, 09 Jan 2023 02:50:23 +0000</pubDate>
      <link>https://forem.com/rick1196/how-to-debounce-a-input-text-on-react-1g60</link>
      <guid>https://forem.com/rick1196/how-to-debounce-a-input-text-on-react-1g60</guid>
      <description>&lt;h2&gt;
  
  
  Let's explain what a debounce function
&lt;/h2&gt;

&lt;p&gt;A debounce function does not execute at call time, it waits a specific number of times to be executed if the function it's called again before being executed, the time restarts, this will happen N number of times until the function can execute&lt;/p&gt;

&lt;h2&gt;
  
  
  How can I achieve this with react?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First we need to check how the &lt;code&gt;setTimeout&lt;/code&gt;  function works
&lt;/h3&gt;

&lt;p&gt;This function allows us to execute a block of code after a certain amount of time, it returns a unique identifier which will allow us to clear that &lt;code&gt;time out&lt;/code&gt; every time we call our function with the help of another function called &lt;code&gt;clearTimeout&lt;/code&gt; which gets an identifier of the &lt;code&gt;time out&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;All this is possible thanks to the global scope of javascript, if want to learn more about this, you can check the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/setTimeout" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Now we need to build our debounce function
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; Let's store the ID of the timeout
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    let timeoutID  = null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A varaible with no value on it&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Let's build the function that will clear the &lt;code&gt;time out&lt;/code&gt; and set the new one
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const debounceFunction = (params) =&amp;gt;{
    clearTimeout(timeoutID);// the timeout will be removed, so the code won't be executed
    timeoutID = setTimeout({ // set the new timeout
        //...your custom code
    },500)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let's check a full example
&lt;/h2&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/buscador-solution-1-3p7trx"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Let's create a small example to use useRef to bind elements</title>
      <dc:creator>Rick1196</dc:creator>
      <pubDate>Mon, 23 Aug 2021 16:57:50 +0000</pubDate>
      <link>https://forem.com/rick1196/how-to-avoid-invalid-inputs-in-react-hln</link>
      <guid>https://forem.com/rick1196/how-to-avoid-invalid-inputs-in-react-hln</guid>
      <description>&lt;h2&gt;
  
  
  Avoid invalid inputs in react
&lt;/h2&gt;

&lt;p&gt;So you want to avoid your user typing invalid characters in, for example, a numeric input?  You only need a custom hook and a regex or a custom function.&lt;/p&gt;

&lt;p&gt;Important note!!!: This validation will not replace any validation library and will not work on mobile devices.&lt;/p&gt;

&lt;p&gt;your can check the a code and a live demo at &lt;a href="https://codesandbox.io/s/event-listener-for-validation-84x9g?file=/src/App.tsx:0-1109"&gt;code sandbox&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/event-listener-for-validation-84x9g"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Lets build the custom hook
&lt;/h2&gt;

&lt;p&gt;Let's add a custom hook to add an event listener to a specific element and trigger a function when that event happens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect } from "react";

type EventListenerParams = {
  action: (event: Event) =&amp;gt; void; // what do we want to perform with the event
  event: string; // what event do we want to listen for
  reference: React.RefObject&amp;lt;HTMLInputElement&amp;gt;; // the element that we want to bind to the listener
};

/**
 * Add a event listener for a specific event to a specific element
 */
const useEventListener = (params: EventListenerParams): void =&amp;gt; {
  useEffect(() =&amp;gt; {
    // on init add event listener
    params.reference.current?.addEventListener(params.event, params.action);
    // on component unmounted, remove the event listener to avoid performance issues
    return () =&amp;gt;
      params.reference.current?.removeEventListener(
        params.event,
        params.action
      );
  }, [params.reference, params.event, params.action]);
};

export default useEventListener;

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

&lt;/div&gt;



&lt;p&gt;With this custom hook, You just need to pass the parameters for each element or event you want to listen for; don't forget to add the return statement to the custom hook, to remove the event listener at component unmount.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the difference between bind elements with useRef and getElementById?
&lt;/h3&gt;

&lt;p&gt;By selecting the element with &lt;code&gt;getElementById&lt;/code&gt; you will get the first one that the function finds in the DOM tree, so, if you re-use a component with this validation, it will work only for the first instance&lt;/p&gt;

&lt;p&gt;And if you use &lt;code&gt;React.createRef&lt;/code&gt; you will bind an specific instance of an element, so the biding will be unique for each instance&lt;/p&gt;

&lt;h2&gt;
  
  
  Now lets create a couple of validation functions to test our custom hook
&lt;/h2&gt;

&lt;p&gt;The first one to validate the length of an input value&lt;br&gt;
The second one to validate if the value of an input matches with a regex&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * Check if the current length of the input value is minor to a fixed length
 * @param maxLength of your input
 */
export function lengthValidator(maxLength: number) {
  return function validation(event: Event): void {
    const element = event.target as HTMLInputElement;
    // if the value length is already equals to maxLength
    if (element.value.length &amp;gt;= maxLength) {
      //  cancel the event and their side effects
      event.preventDefault();
    }
  };
}
/**
 * Check if the current value of the input plus the key pressed match with a pattern
 * @param regex to compare the input value
 */
export function matchValidator(regex: RegExp) {
  return function validation(event: Event): void {
    // get the element
    const element = event.target as HTMLInputElement;
    // get the element current value plus the input key value
    const stringToValidate = String(
      element.value + (event as KeyboardEvent).key
    );
    // if input value does not match with the regex
    if (!stringToValidate.match(regex)) {
      // cancel the event and their side effects
      event.preventDefault();
    }
  };
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Now lets add some input fields to test our creation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import "./styles.css";
import useEventListener from "./use-event-listener";
import { lengthValidator, matchValidator } from "./validations";

export default function App() {
  const inputRef = React.createRef&amp;lt;HTMLInputElement&amp;gt;();
  const inputRef2 = React.createRef&amp;lt;HTMLInputElement&amp;gt;();
  /**
   * Validates that max-length field never be longer than 10
   */
  useEventListener({
    action: lengthValidator(10),
    event: "keypress",
    reference: inputRef
  });
  /**
   * Validates that numbers-only always contains numeric characters
   */
  useEventListener({
    action: matchValidator(new RegExp("^[\\d]+$")),
    event: "keypress",
    reference: inputRef2
  });
  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;label&amp;gt;Input for with max length of 10&amp;lt;/label&amp;gt;
        &amp;lt;input
          placeholder="Enter a name with no more of 10 characters"
          type="text"
          id="max-length"
          ref={inputRef}
        /&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;label&amp;gt;Input only for numbers&amp;lt;/label&amp;gt;
        &amp;lt;input
          ref={inputRef2}
          placeholder="Enter only numbers"
          type="text"
          id="numbers-only"
        /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}


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

&lt;/div&gt;



&lt;p&gt;And that's all, now you can use the custom hook in all the components you want, and you can implement your validation functions.&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>reacthooks</category>
    </item>
    <item>
      <title>Let's create a simple Weather App with React</title>
      <dc:creator>Rick1196</dc:creator>
      <pubDate>Sat, 31 Jul 2021 21:10:09 +0000</pubDate>
      <link>https://forem.com/rick1196/let-s-create-a-simple-weather-app-with-react-4o54</link>
      <guid>https://forem.com/rick1196/let-s-create-a-simple-weather-app-with-react-4o54</guid>
      <description>&lt;h2&gt;
  
  
  App description
&lt;/h2&gt;

&lt;p&gt;Let's create a basic weather app with React(typescript), &lt;a href="https://openweathermap.org/api"&gt;Weather API&lt;/a&gt;, sass, and react hooks&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Rick1196/weather-app"&gt;Github repo&lt;/a&gt;&lt;br&gt;
&lt;a href="https://weather-app-navy-chi.vercel.app/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Let's set our workspace
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Create our react project with create-react-app
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app basic-weather-app --template typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Now let's config linter, jest, etc.
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx cra-to-nx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will config our dev tools&lt;/p&gt;
&lt;h2&gt;
  
  
  npm packages
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add axios @fortawesome/fontawesome-free react-i18next i18next i18next-browser-languagedetector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Axios for our HTTP requests&lt;/li&gt;
&lt;li&gt;fontawesome to display awesome icons&lt;/li&gt;
&lt;li&gt;i18next to add internationalization to our app

&lt;ul&gt;
&lt;li&gt;i18next-browser-languagedetector to detect the users default lang and set it as our defalt language&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Folder structure
&lt;/h2&gt;

&lt;p&gt;NX create a larger folder structure, but This is the final structure of our project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ─src
    ├───assets
    │   ├───design -&amp;gt; Design system
    │   │   ├───components
    │   │   ├───fonts
    │   │   ├───globals
    │   │   └───util
    │   ├───i18n -&amp;gt; Translations
    │   │   ├───en
    │   │   └───es
    │   └───images
    ├───components
    │   └───landing
    ├───custom-hooks
    ├───functions
    ├───interfaces
    └───services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Add weather Api
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Let's create an account at &lt;a href="https://home.openweathermap.org/users/sign_up"&gt;Weather API&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;After creating our account, let's create an API key for &lt;a href="https://openweathermap.org/current"&gt;Current Weather Data&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Note: you will need to wait like 2 hours for your api key to be activated&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Let's add our i18next config
&lt;/h3&gt;

&lt;p&gt;(assets/i18n)&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;I just add a basic translations files for EN and ES, you can find them at &lt;a href="https://github.com/Rick1196/weather-app/tree/main/apps/know-weather/src/assets/i18n"&gt;src/assets/i18n&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's add our weather services to our project
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;If you have not created your &lt;code&gt;services&lt;/code&gt; folder, create it and  inside it, let's create a new &lt;code&gt;ts&lt;/code&gt; file named &lt;code&gt;weather-service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Lest create our interfaces
The interfaces will serve us as data models for the Weather API responses and some other purposes&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;CurrentWeatherI (interfaces/current-weatherI.ts)
The data model of the response of the weather API's&lt;/li&gt;
&lt;li&gt;WeatherPropertiesI (interfaces/weather-properties.ts)
The data model of requests to  weather API's
(interfaces/)
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;now let's create 3 functions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;currentWeather&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This function will retrieve weather data by coordinates&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;getWeatherCity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This function will retrieve weather data by city name&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;getWeatherIcon&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The currentWeahter and getWeatherCity will return an icon code in their properties, this code will serve us to retrieve an icon image to display in our app&lt;br&gt;
(services/weather-services.ts)&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now that we have our services for the app, let's create a function to get the correct background image depending on the current weather&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To achieve this, first, we need to check their current weather API documentation for their weather code at &lt;a href="https://openweathermap.org/weather-conditions"&gt;weather codes&lt;/a&gt;, i decided to group the codes by range, but you can go deeper.&lt;/p&gt;

&lt;p&gt;(functions/weather-background.ts)&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You can use the same images as me, you can find them at my source code at &lt;a href="https://github.com/Rick1196/weather-app.git"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or search for your own, i found my images at &lt;a href="https://unsplash.com/"&gt;unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Our next step is to build a custom hook to get the client lat and long
&lt;/h3&gt;

&lt;p&gt;For this we are gonna use window.navigator.geolocation&lt;br&gt;
(custom-hook/use-position.ts)&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This hook will provide us with the current location of our user, so now we can request the weather of the current location.&lt;/p&gt;

&lt;h3&gt;
  
  
  Now let's create our main component
&lt;/h3&gt;

&lt;p&gt;(components/landing.tsx)&lt;/p&gt;

&lt;p&gt;In this component, we are gonna use the next element&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 buttons, one to search the location input and another to return to the current location weather&lt;/li&gt;
&lt;li&gt;1 input field to search places&lt;/li&gt;
&lt;li&gt;A cards deck to display the weather info&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use our custom hook use-position
&lt;/h4&gt;

&lt;p&gt;The first step to build  our component is to connect our use position custom hook to get the user position and ask for the current weather&lt;br&gt;
Now that we have the position stored, let's pass it as a dependency to an useEffect hook, so every time that the position variable changes, the effect will execute the getWeather function; The getWeather function will call the getWeather callBack, await for the service response then results will be store at the weather state; then the functions getWeatherIcon and readWeatherImage will be call and this functions will update the watherIcon and weatherImage state respectively, the change at weatherImage will trigger the effect to set the image as the body tag background image property value.&lt;/p&gt;

&lt;p&gt;Now that we have the weather, the weatherImage and the weatherIcon, we can use this data to show it to the user.&lt;/p&gt;

&lt;p&gt;(components/landing/landing.tsx)&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Where to know more about the topics to build a basic project like this?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;(react hooks)[&lt;a href="https://reactjs.org/docs/hooks-intro.html"&gt;https://reactjs.org/docs/hooks-intro.html&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;(react custom hooks)[&lt;a href="https://reactjs.org/docs/hooks-custom.html"&gt;https://reactjs.org/docs/hooks-custom.html&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;(geolocation api)[&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;(react-18n-next)[&lt;a href="https://react.i18next.com/"&gt;https://react.i18next.com/&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;(react-form-hooks)[&lt;a href="https://react-hook-form.com/get-started"&gt;https://react-hook-form.com/get-started&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;(Nx)[&lt;a href="https://nx.dev/latest/react/getting-started/intro"&gt;https://nx.dev/latest/react/getting-started/intro&lt;/a&gt;]&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wher is the sass explanation??
&lt;/h2&gt;

&lt;p&gt;I will write a second post to cover the design of the project&lt;/p&gt;

&lt;p&gt;&lt;a href=""&gt;Let's create a simple weather app - Part 2&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
