<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Ghers Fisman - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Descubre miles de cursos de programación escritos por expertos. Aprende Desarrollo Web, Ciencia de Datos, DevOps, Seguridad y obtén asesoramiento profesional para desarrolladores. ]]>
        </description>
        <link>https://www.freecodecamp.org/espanol/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Ghers Fisman - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/espanol/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 25 Jun 2026 09:38:48 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/espanol/news/author/ghers/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Cómo prepararse para las entrevistas de React - Guía de entrevistas técnicas para Front-End ]]>
                </title>
                <description>
                    <![CDATA[ Una entrevista técnica es una oportunidad que tiene un empleador potencial de evaluar tus habilidades y conocimientos de desarrollo web. El entrevistador te hará preguntas sobre tu experiencia y habilidades en HTML, CSS, y JavaScript. También te preguntarán, probablemente, preguntas específicas de frameworks como React, Angular, Vue o cualquier otro ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/prepararse-para-las-entrevistas-de-react/</link>
                <guid isPermaLink="false">63244d0e70a5cb0907d689bf</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ghers Fisman ]]>
                </dc:creator>
                <pubDate>Mon, 23 Jan 2023 20:33:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/09/Build-a-React-Code-Editor-That-Compiles-and-Executes-in-10--Languages--2-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/prepare-for-react-technical-interviews/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Prepare for React Interviews –&nbsp;Front-End Technical Interview Guide</a>
      </p><p>Una entrevista técnica es una oportunidad que tiene un empleador potencial de evaluar tus habilidades y conocimientos de desarrollo web.<br><br>El entrevistador te hará preguntas sobre tu experiencia y habilidades en HTML, CSS, y JavaScript. También te preguntarán, probablemente, preguntas específicas de frameworks como React, Angular, Vue o cualquier otro framework que utilice la empresa.<br><br>Quizás también te den un desafío de código para evaluar tus habilidades en un área específica.<br><br>Hoy, miraremos las preguntas y problemas más comunes en entrevistas técnicas de front-end, enfocándonos en React y JavaScript.</p><h2 id="lo-que-los-entrevistadores-est-n-buscando"><strong>Lo que los entrevistadores están buscando</strong></h2><p>Cuando te entrevistes para una posición como desarrollador de front-end, prepárate para discutir tus habilidades y experiencia en varios lenguajes de programación, herramientas y frameworks.<br><br>Los entrevistadores también querrán confirmar que tengas un entendimiento profundo de las últimas tendencias y tecnologías del desarrollo web.<br><br>Prepárate para hablar acerca de tus proyectos anteriores y como afrontaste la resolución de problemas de todo tipo.<br><br>Asegúrate de mostrar tus habilidades de resolución de problemas discutiendo como afrontaste las dificultades durante el proceso de desarrollo.<br><br>Por último, no olvides resaltar tus fortalezas.</p><h2 id="preguntas-m-s-frecuentes-en-entrevistas-t-cnicas-de-front-end"><strong>Preguntas más frecuentes en entrevistas técnicas de Front-End</strong></h2><p>Los problemas de entrevistas técnicas de front-end son directos y comunes. Si has estado programando por al menos 6 meses, estarás familiarizado con la mayoría de los conceptos que se preguntan.</p><p>Una vez practiques las preguntas adecuadas con un enfoque basado en el tiempo, deberías poder pasar las entrevistas.</p><p>Echemos un vistazo a las preguntas más frecuentes.</p><h2 id="map-foreach-filter-y-reduce"><strong>Map, ForEach, Filter y Reduce</strong></h2><p>Las preguntas más frecuentes (generalmente al principio de las entrevistas) son acerca de métodos de arreglos (<code>array methods</code>). El entrevistador querrá evaluar que tan cómodo te sientes con manipulación de arreglos.</p><h4 id="el-m-todo-map-"><strong>El método </strong><code><strong>.map()</strong></code></h4><p>El método <code>.map()</code> itera sobre un arreglo, computa cualquier lógica que hayas escrito en el cuerpo del mapa, y retorna un <strong>NUEVO</strong> arreglo.</p><pre><code class="language-javascript">let arr = [
  { id: 1, age: 12, name: 'Manu' },
  { id: 2, age: 24, name: 'Quincy' },
  { id: 3, age: 22, name: 'Abbey' },
]

let names = arr.map((el) =&gt; el.name)
console.log(names)
// Resultado: [ 'Manu', 'Quincy', 'Abbey' ]</code></pre><h4 id="el-m-todo-foreach-"><strong>El método </strong><code><strong>.forEach()</strong></code></h4><p>ForEach es similar a<code>.map()</code> pero NO retorna un arreglo.</p><pre><code class="language-javascript">let arr = [
  { id: 1, age: 12, name: 'Manu' },
  { id: 2, age: 24, name: 'Quincy' },
  { id: 3, age: 22, name: 'Abbey' },
]

arr.forEach((el) =&gt; el.age+= 10);
console.log(arr);

// Resultado: 22 32 44</code></pre><h4 id="el-m-todo-filter-"><strong>El método </strong><code><strong>.filter()</strong></code></h4><p>El método filtró (filter), como el nombre sugiere, ayuda a filtrar los valores dentro de un arreglo basándose en una condición Booleana.</p><p>Si la condición Booleana es verdadera, el resultado será retornado y agregado al final del arreglo. Si no, será omitido. Filtro también retorna un arreglo, tal como el método <code>.map()</code>.</p><pre><code class="language-javascript">let arr = [
  { id: 1, age: 12, name: 'Manu' },
  { id: 2, age: 24, name: 'Quincy' },
  { id: 3, age: 22, name: 'Abbey' },
]

let tooYoung = arr.filter((el) =&gt; el.age &lt;= 14);
console.log(tooYoung);

// Resultado: [ { id: 1, age: 12, name: 'Manu' } ]</code></pre><h4 id="el-m-todo-reduce-"><strong>El método </strong><code><strong>.reduce()</strong></code></h4><p>En términos simples, el método <code>.reduce()</code> toma en cuenta un valor anterior, valor actual y un acumulador.</p><p>El tipo de retorno del método <code>.reduce()</code> es siempre un único valor. Es útil cuando quieres procesar todos los valores del arreglo y obtener algún tipo de valor resultado acumulado.</p><pre><code class="language-javascript">// Calcula la edad total de tres personas.
let arr = [
  { id: 1, age: 12, name: 'Manu' },
  { id: 2, age: 24, name: 'Quincy' },
  { id: 3, age: 22, name: 'Abbey' },
]

let totalAge = arr.reduce((acc, currentObj) =&gt; acc + currentObj.age, 0)
console.log(totalAge)

// Resultado: 57</code></pre><p>Aquí, <code>currentObj</code> es el objeto sobre el cual se está iterando. Así mismo, el valor &nbsp;<code>acc</code> value guarda el resultado, que luego es emitido en el arreglo totalAge.</p><h2 id="c-mo-implementar-polyfills"><strong>Cómo implementar Polyfills</strong></h2><p>Otra importante pregunta de entrevistas es cómo implementar polyfills de los métodos map y filter.</p><p>Un polyfill es un fragmento de código (en términos de arquitectura web de JavaScript) que se utiliza para funcionalidades modernas en navegadores antiguos que no lo implementan nativamente.</p><p>Puesto de manera sencilla, un polyfill es una implementación customizada de funciones nativas de JavaScript. De alguna manera, se utiliza para crear tus propios métodos <code>.map()</code> o <code>.filter()</code>.</p><h4 id="c-mo-usar-el-polyfill-map-"><strong>Cómo usar el polyfill </strong><code><strong>.map()</strong></code></h4><pre><code class="language-javascript">let data = [1, 2, 3, 4, 5];

Array.prototype.myMap = function (cb) {
  let arr = [];
  for (let i = 0; i &lt; this.length; i++) {
    arr.push(cb(this[i], i, this));
  }
  return arr;
};
const mapLog = data.myMap((el) =&gt; el * 2);
console.log(mapLog);</code></pre><p>El método myMap toma un <code>callback</code> que se ejecuta dentro del cuerpo de <code>myMap</code>. Tenemos básicamente un bucle <code>for</code> dentro del cuerpo myMap, que itera sobre <code>this.length</code>. Esto es simplemente el <code>length</code> del arreglo sobre el cual la función <code>myMap</code> es llamada.</p><p>Dado que la sintaxis de <code>map()</code> es <code>arr.map(elementoActual, índice, arreglo)</code>, la función <code>myMap()</code> toma en cuenta exactamente eso.</p><p>De la misma manera, dado que <code>map()</code> retorna un nuevo arreglo, creamos un arreglo vacío y cargamos los resultados en él. Al finalizar, retornamos el nuevo arreglo.</p><h4 id="c-mo-usar-el-polyfill-filter-"><strong>Cómo usar el polyfill </strong><code><strong>.filter()</strong></code><strong> </strong></h4><pre><code class="language-javascript">let data = [1, 2, 3, 4, 5];

Array.prototype.myFilter = function (cb) {
  let arr = [];
  for (let i = 0; i &lt; this.length; i++) {
    if (cb(this[i], i, this)) {
      arr.push(this[i]);
    }
  }
  return arr;
};
const filterLog = data.myFilter((el) =&gt; el &lt; 4);
console.log(filterLog);</code></pre><p><code>.filter()</code> es muy similar a <code>.map()</code> en términos de implementación. Pero dado que <code>filter</code> filtra los resultados basándose en un valor booleano, tendremos una condición <code>if()</code> adicional para filtrar los resultados y condicionalmente cargamos dentro del arreglo.</p><h2 id="-qu-es-el-debouncing"><strong>¿Qué es el Debouncing?</strong></h2><p>Esta es una pregunta de entrevista famosa que tiene muchos usos e implementaciones en el mundo real.</p><p><code>Debouncing</code> es un método para prevenir que una función se invoque con demasiada frecuencia, y que en lugar de esto espere cierto tiempo desde que fue llamada por última vez para invocarla de nuevo.<br><br>Piensa en Amazon. Cuando escribes cualquier cosa en la barra de búsqueda, cuando paras por AL MENOS 0.5 segundos, los resultados son descargados. Esto es exactamente lo que hace el debouncing.</p><p>Para implementar el debouncing, tomemos un ejemplo: generar un nombre de usuario basado en los aportes del usuario.</p><figure class="kg-card kg-embed-card"><iframe width="1280" height="500" src="https://codesandbox.io/embed/proud-surf-uiu2v?file=/src/index.js" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin" title="Embedded content" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; width: 1280px; height: 500px; border-radius: 4px; overflow: hidden;"></iframe></figure><pre><code class="language-javascript">import "./styles.css";
let inputEle = document.getElementById("inputElement");
let username = document.getElementById("username");

let generateUsername = (e) =&gt; {
  username.innerHTML = e.target.value.split(" ").join("-");
};
let debounce = function (cb, delay) {
  let timer;
  return function () {
    let context = this;
    clearTimeout(timer);
    timer = setTimeout(() =&gt; {
      cb.apply(context, arguments);
    }, delay);
  };
};

inputEle.addEventListener("keyup", debounce(generateUsername, 300));</code></pre><p>Aquí, estamos intentando crear un nombre de usuario customizado basado en aportes del usuario. Si el usuario comienza a escribir, no querremos crearlo inmediatamente, sino esperar 300 milisegundos antes de crear el nombre de usuario. Estamos intentando imitar un llamado al API, así que asumimos que el usuario escribe cualquier cosa, hace un llamado al API en el backend y descarga una respuesta.</p><p>La función <code>debounce()</code> toma dos valores , <code>cb</code> y <code>delay</code> . <code>cb</code> es la función callback que se ejecuta una vez el temporizador se queda sin tiempo.<br><br>Usamos <code>setTimeout()</code> para crear un temporizador, lo que significa que la función dentro del setTimeout se ejecutará luego de que haya pasado cierto tiempo.</p><p>El método <code>apply</code> se utiliza para llamar a la función callback con el objeto con el que se llamo inicialmente, aplicando argumentos y contexto al mismo.</p><h2 id="-qu-son-las-clausuras-closures-"><strong>¿Qué son las Clausuras (Closures)?</strong></h2><p>De acuerdo a la <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Closures">documentación de MDN</a> para clausuras,</p><blockquote>Una Clausura es una función que guarda referencias del estado adyacente (<strong>ámbito léxico</strong>). En otras palabras, una clausura permite acceder al ámbito de una función exterior desde una función interior. En JavaScript, las clausuras se crean cada vez que una función es creada.</blockquote><p>Para simplificar esto, tomemos un ejemplo y entendamos cómo funcionan los cierres.</p><pre><code class="language-javascript">function start() {
  var name = "Manu"; // name es una variable local creada por start()
  function displayName() {
    // displayName() es la función interna, una 'clausura'
    alert(name); // variable de uso declarada en la función padre
  }
  displayName();
}
start(); // la caja de alerta "Manu" es mostrada</code></pre><p>Aquí, una clausura se forma entre las funciones <code>start()</code> y <code>displayName()</code>. La función <code>displayName()</code> tiene acceso a la variable <code>name</code> presente en la función <code>start()</code>.</p><p>En términos simples, la función interna conocerá sus alrededores (el ambiente léxico).</p><h2 id="ganchos-hooks-de-react"><strong>Ganchos (Hooks) de React</strong></h2><p>Las preguntas mas populares en las entrevistas técnicas para roles de front-end, cuando se trata de ganchos de React, son:</p><ol><li><code>useState()</code></li><li><code>useReducer()</code></li><li><code>useEffect()</code></li><li><code>useRef()</code></li><li>Hooks customizados y su implementación.</li></ol><h3 id="-c-mo-funciona-el-hook-usestate-"><strong>¿Cómo funciona el hook <code>useState()</code>?</strong></h3><p>Para manejar un estado dentro ed tu componente, el hook <code>useState()</code> es el mecanismo ideal.<br><br>Veamos un ejemplo para entender:</p><figure class="kg-card kg-embed-card"><iframe width="1280" height="500" src="https://codesandbox.io/embed/thirsty-lewin-uo8ylh?fontsize=14&amp;hidenavigation=1&amp;theme=dark" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin" title="Embedded content" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; width: 1280px; height: 500px; border-radius: 4px; overflow: hidden;"></iframe></figure><pre><code class="language-javscript">import { useState } from "react";
import "./styles.css";

export default function App() {
  const [title, setTitle] = useState("freeCodeCamp");
  const handleChange = () =&gt; {
    setTitle("FCC");
  };
  return (
    &lt;div className="App"&gt;
      &lt;h1&gt;{title} useState&lt;/h1&gt;
      &lt;button onClick={handleChange}&gt;Change Title&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre><p>Los métodos <code>useState()</code> arrojan dos valores, la variable <code>estado</code> y <code>una función para cambiar</code> dicha variable state.</p><p>En el fragment de código mostrado arriba, estamos creando un estado <code>title</code> para guardar el título de la página. El estado inicial indicado es <code>freeCodeCamp</code>.</p><p>Al presionar click, podemos utilizar el método <code>setTitle()</code> para cambiar la variable de estado a <code>FCC</code>.</p><p>El método <code>useState()</code> es el recurso más apropiado para controlar estados en un componente funcional.</p><h3 id="-c-mo-funciona-el-hook-usereducer-"><strong>¿Cómo funciona el hook </strong><code><strong>useReducer()</strong></code><strong>?</strong></h3><p>En términos simples, <code>useReducer()</code> es la manera "cool" de controlar un estado en tu aplicación. Es más estructurado y te ayuda a mantener un estado complejo en tu aplicación.</p><p>Veamos un ejemplo para entender como funciona el hook <code>useReducer()</code> :</p><figure class="kg-card kg-embed-card"><iframe width="1280" height="500" src="https://codesandbox.io/embed/ecstatic-marco-o8wh00?fontsize=14&amp;hidenavigation=1&amp;theme=dark" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin" title="Embedded content" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; width: 1280px; height: 500px; border-radius: 4px; overflow: hidden;"></iframe></figure><pre><code class="language-javscript">import "./styles.css";
import { useReducer } from "react";

const initialState = { title: "freeCodeCamp", count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case "change-title":
      return { ...state, title: "FCC" };
    case "increment-counter":
      return { ...state, count: state.count + 1 };
    default:
      throw new Error();
  }
}

export default function App() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    &lt;&gt;
      &lt;div className="App"&gt;
        &lt;h1&gt;{state.title} CodeSandbox&lt;/h1&gt;
        &lt;button onClick={() =&gt; dispatch({ type: "change-title" })}&gt;
          Change Title
        &lt;/button&gt;
        &lt;button onClick={() =&gt; dispatch({ type: "increment-counter" })}&gt;
          Increment Counter
        &lt;/button&gt;
      &lt;/div&gt;
      &lt;p style={{ textAlign: "center" }}&gt;{state.count}&lt;/p&gt;.
    &lt;/&gt;
  );
}
</code></pre><p>El hook <code>useReducer()</code> toma dos parámetros, la función <code>reducer</code> y un valor <code>initialState</code>.<br><br>La función reducer es una implementación basada en <code>switch-case</code> que retorna el estado final que <code>useReducer()</code> utiliza internamente para proporcionar de vuelta al componente.</p><p>Los valores retornados de la función <code>useReducer()</code> son <code>state</code> y <code>dispatch</code>. El estado es el valor <code>state</code> que puede ser utilizado dentro del componente. En nuestro caso, el estado tiene dos valores: <code>title y count</code>. Estos pueden ser manipulados utilizando el método <code>dispatch()</code> que es retornado por el método <code>useReducer()</code>.</p><p>En el caso de arriba, para cambiar el título, hemos escrito un caso de <code>change-title</code> dentro de la función reducer. Esto puede detonarse (trigger) con la ayuda dela función <code>dispatch({ type: "change-title" })</code>. Esto detonará el la función change-title y cambiará el estado del atributo <code>title</code>.<br><br>Lo mismo sucede para la parte <code>count</code> que se encuentra en la aplicación.<br><br>Como dije antes, es una manera "cool" de controlar un estado dentro de tu aplicación. ?</p><h3 id="-c-mo-funciona-el-hook-useeffect-"><strong>¿Cómo funciona el hook </strong><code><strong>useEffect()</strong></code><strong>?</strong></h3><p>Piénsalo de esta manera: si quieres tener un <code>efecto secundario</code> para una variable de estado que cambia, puedes usar el hook <code>useEffect()</code> para desencadenarlo.<br><br>Por ejemplo, digamos que el <code>valor de entrada</code> (valor de entrada) de tu campo "input" cambia, y quieres llamar a un API luego de que haya cambiado. Puedes escribir la lógica del <code>API handle</code> en el bloque <code>useEffect()</code>.</p><pre><code class="language-javascript">import React, {useState, useEffect} from 'react';

export const App = () =&gt; {
    const [value, setValue] = useState('');
    useEffect(() =&gt; {
      console.log('value changed: ', value);
    }, [value])
	return &lt;div&gt;
        	&lt;input type="text" name="username" value={value} onChange={(e) =&gt; setValue(e.target.value)} /&gt;
        &lt;/div&gt;
}</code></pre><p>Aquí, tenemos un <code>campo de input</code> que tiene un valor de estado <code>value</code> adjunto. Este valor cambiará cuando el usuario intente insertar cualquier cosa.<br><br>Una vez el valor haya sido actualizado y renderizado, el bloque <code>useEffect()</code> entrará en efecto y la declaración <code>console</code> se desencadenará, arrojando como resultado el último valor de estado que este allí.<br><br>Aquí, un buen valor de uso de <code>useEffect()</code> puede ser la implementación de llamadas a la <code>API</code>. Asumamos que quieres llamar a un API a través del valor en el campo input. La función bloque useEffect será la mejor manera de hacerlo.</p><p>Otra parte de esto es el <code>arreglo de dependencia</code>, que es el segundo argumento del hook <code>useEffect()</code>. En nuestro caso, mencionamos <code>[value]</code> como el segundo argumento.</p><p>Esto básicamente significa que CADA VEZ QUE <code>value</code> CAMBIA, la función dentro de useEffect se desencadenará. Si no se pasa nada en el &nbsp;<code>arreglo de dependencia</code>, la función bloque se desencadena una vez.</p><h3 id="-c-mo-funciona-el-hook-useref-"><strong>¿Cómo funciona el hook </strong><code><strong>useRef()</strong></code><strong>?</strong></h3><p>El hook &nbsp;useRef nos da la habilidad de mutar el DOM (pero esta no es la única implicación de useRef).</p><p>De acuerdo a los documentos:</p><blockquote><em><em>useRef </em>retorna un objeto ref mutable cuya propiedad .current es inicializada al argumento pasado (initialValue). El objeto retornado persistirá por la vida completa del componente<em>.</em></em></blockquote><p>En términos simples, utilizaremos useRef si queremos persistir el valor de algo durante la vida entera del componente. La implementación básica de useRef viene con elementos DOM. Veamos un ejemplo:</p><pre><code class="language-javascript">function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () =&gt; {
    // `current` apunta al elemento de texto montado
    inputEl.current.focus();
  };
  return (
    &lt;&gt;
      &lt;input ref={inputEl} type="text" /&gt;
      &lt;button onClick={onButtonClick}&gt;Enfocar el input&lt;/button&gt;
    &lt;/&gt;
  );
}</code></pre><p>Aquí, asignaremos una propiedad <code>ref</code> al bloque <code>input</code>. Esto se asociará a la referencia <code>inputEl</code> que creamos.</p><p>Ahora este elemento <code>input</code> puede ser manipulado de la manera que queramos. Podemos modificar el atributo <code>style</code> y estilizarlo, podemos tomar la propiedad <code>value</code> para ver si está siendo ayudada por el elemento input como valor, y así sucesivamente.</p><p>En el ejemplo anterior, cuando hacemos click en el botón, el <code>input</code> está enfocado y podemos inmediatamente comenzar a escribir. podemos hacer esto con la ayuda de <code>inputEl.current.focus()</code> – esencialmente el método <code>focus()</code> presente en el objeto <code>current</code>.</p><h3 id="-qu-son-los-hooks-customizados"><strong>¿Qué son los hooks customizados?</strong></h3><p>Una de las preguntas que he observado más frecuentemente en rondas de entrevistas de front-end es <a href="https://www.algochurn.com/frontend/usekeypress-custom-hook">crear un hook customizado para eventos del teclado</a>.</p><p>Hemos visto varios hooks diferentes, pero el entrevistador te podría pedir que crees un hook por ti mismo. Esto podría ser retador para algunos pero con algo de práctica se vuelve mucho más sencillo.</p><p>Entendamos lo que es un <code>Hook</code>:</p><p>El uso básico de un hook customizado es extraer la lógica de una función a un componente propio.</p><p>Reflejando lo que pasará si tienes que escuchar la presión del botón <code>enter </code> dentro de cada uno de tus componentes. En lugar de escribir la lógica para &nbsp;<code>escuchar</code> una y otra vez, podemos extraer la lógica a un componente por sí mismo y usarlo donde queramos (de la misma forma que <code>useState()</code> o <code>useEffect()</code>).</p><p>Hay algunas condiciones para que una función pueda llamarse un <code>Hook</code>:</p><ol><li>Siempre debe empezar con la palabra <code>use</code>.</li><li>Podemos decidir que recibe como argumentos y que retorna (si es que retorna algo).</li></ol><pre><code class="language-javascript">// Custom Hook: useAvailable
function useAvailabe(resource) {
  const [isAvailable, setIsAvailable] = useState(null);

  // ...

  return isAvailable;
}

// Uso:
  const isAvailable = useAvailable(cpu);
</code></pre><p>Aquí, sin importar cuantas veces llamemos <code>useState</code> y <code>useEffects</code> dentro del hook customizado, serán completamente independientes de la función en donde usemos el hook customizado.<br><br>Tomemos un ejemplo creando un hook customizado para <code>almacenar valores locales</code>.</p><h3 id="como-crear-un-hook-customizado-ejemplo-de-uselocalstorage"><strong>Como crear un hook customizado – ejemplo de useLocalStorage</strong></h3><p>El hook customizado useLocalStorage es una manera de persistir datos dentro del almacenamiento local. Los valores get (obtener) y set (establecer) dentro del almacenamiento local utilizando pares <code>key</code> y <code>value</code> para que cuando el usuario vuelva a tu aplicación web, vean el mismo resultado que utilizaron anteriormente.</p><p>La implementación de más abajo es de un valor de etiqueta simple <code>select</code> que, una vez cambiado, persiste la data en el almacenamiento local.</p><p><code>useLocalStorage.js</code></p><pre><code class="language-javascript">// Usar el hook customizado Local Storage
import { useState } from 'react';

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() =&gt; {
    if (typeof window === 'undefined') {
      return initialValue;
    }
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.log(error);
      return initialValue;
    }
  });
  const setValue = (value) =&gt; {
    try {
      const valueToStore =
        value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      if (typeof window !== 'undefined') {
        window.localStorage.setItem(key, JSON.stringify(valueToStore));
      }
    } catch (error) {
      console.log(error);
    }
  };
  return [storedValue, setValue] as const;
}

export default useLocalStorage;
</code></pre><p><code>App.js</code></p><pre><code class="language-javascript">import * as React from 'react';
import './style.css';
import useLocalStorage from './useLocalStorate';

export default function App() {
  const [storedValue, setStoredValue] = useLocalStorage(
    'select-value',
    'light'
  );

  return (
    &lt;div&gt;
      &lt;select
        className="select"
        value={storedValue}
        onChange={(e) =&gt; setStoredValue(e.target.value)}
      &gt;
        &lt;option value="dark"&gt;Dark&lt;/option&gt;
        &lt;option value="light"&gt;Light&lt;/option&gt;
      &lt;/select&gt;
      &lt;p className="desc"&gt;
        Value from local storage: &lt;span&gt;{storedValue}&lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
  );
}</code></pre><p>Aquí, el hook <code>useLocalStorage</code> toma dos parámetros, el nombre de <code>key</code> local para almacenar, y un valor <code>default</code> que tiene que estar allí.</p><p>El hook retorna dos valores: el <code>valor de almacenamiento local</code> del key que estamos utilizando y una manera de cambiar dicho valor de <code>key</code> dándonos un método <code>setter</code>. En este caso, el método <code>setStoredValue</code>.</p><p>En el archivo <code>useLocalStorage.js</code>, primero intentamos <code>GET</code> (OBTENER) el valor de almacenamiento local con el key utilizando el método <code>localStorage.getItem()</code>. Si esto existe, estableceremos el valor. Si es encontrado, haremos <code>JSON.parse()</code> del valor y lo retornaremos. De otra fosma, el valor initialValue que fur proporcionado se establecerá como el valor default.<br><br>La función <code>setLocalStorage()</code> toma en cuenta si el valor proporcionado es una función o un valor simple variable. Así mismo, se da a la tarea de establecer el valor local utilizando la función <code>localStorage.setItem()</code>.</p><h2 id="como-destacar-como-desarrollador-a-trav-s-de-la-creaci-n-de-proyectos-paralelos"><strong>Como destacar como Desarrollador a través de la creación de proyectos paralelos</strong></h2><p>Lo que siempre me ha ayudado a destacarme son los proyectos paralelos que he construido.<br><br>En mi opinión, no tienes que construir 10 proyectos básicos. En cambio, prueba construir uno o dos proyectos verdaderamente buenos en donde implementes los conceptos de React/HTML/CSS/JavaScript y todo lo que has estado aprendiendo.<br><br>Asume que el entrevistador tiene 14 entrevistas a la semana y tiene que revisar los CV de 14 candidatos. Estarán más interesados en tu perfil porque has creado una app para acortar URLs que cobra $1 después de cada 1000 visitas al link en lugar de un clon de Amazon o Netflix.</p><p>De nuevo, no hay nada malo en crear clones y practicar tus habilidades. Pero siempre es bueno tener al menos un proyecto único que te ayude a destacar de la multitud.<br><br>Así mismo, crear proyectos paralelos te ayudará a mejorar como desarrollador. No es probable que sepas todo lo necesario cuando crees un proyectod esde cero. En el camino, tendrás que aprender muchas habilidades diferentes y mejorar en ellas.</p><h2 id="pr-ctica-pr-ctica-pr-ctica-"><strong>Práctica, Práctica, Práctica.</strong></h2><p>Hay una frase famosa que dice:</p><figure class="kg-card kg-embed-card"><iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true" class="" title="Twitter Tweet" src="https://platform.twitter.com/embed/Tweet.html?creatorScreenName=mannupaaji&amp;dnt=false&amp;embedId=twitter-widget-0&amp;features=eyJ0ZndfdGltZWxpbmVfbGlzdCI6eyJidWNrZXQiOlsibGlua3RyLmVlIiwidHIuZWUiLCJ0ZXJyYS5jb20uYnIiLCJ3d3cubGlua3RyLmVlIiwid3d3LnRyLmVlIiwid3d3LnRlcnJhLmNvbS5iciJdLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X2hvcml6b25fdGltZWxpbmVfMTIwMzQiOnsiYnVja2V0IjoidHJlYXRtZW50IiwidmVyc2lvbiI6bnVsbH0sInRmd190d2VldF9lZGl0X2JhY2tlbmQiOnsiYnVja2V0Ijoib24iLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X3JlZnNyY19zZXNzaW9uIjp7ImJ1Y2tldCI6Im9uIiwidmVyc2lvbiI6bnVsbH0sInRmd19jaGluX3BpbGxzXzE0NzQxIjp7ImJ1Y2tldCI6ImNvbG9yX2ljb25zIiwidmVyc2lvbiI6bnVsbH0sInRmd190d2VldF9yZXN1bHRfbWlncmF0aW9uXzEzOTc5Ijp7ImJ1Y2tldCI6InR3ZWV0X3Jlc3VsdCIsInZlcnNpb24iOm51bGx9LCJ0Zndfc2Vuc2l0aXZlX21lZGlhX2ludGVyc3RpdGlhbF8xMzk2MyI6eyJidWNrZXQiOiJpbnRlcnN0aXRpYWwiLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X2V4cGVyaW1lbnRzX2Nvb2tpZV9leHBpcmF0aW9uIjp7ImJ1Y2tldCI6MTIwOTYwMCwidmVyc2lvbiI6bnVsbH0sInRmd19kdXBsaWNhdGVfc2NyaWJlc190b19zZXR0aW5ncyI6eyJidWNrZXQiOiJvbiIsInZlcnNpb24iOm51bGx9LCJ0ZndfdHdlZXRfZWRpdF9mcm9udGVuZCI6eyJidWNrZXQiOiJvZmYiLCJ2ZXJzaW9uIjpudWxsfX0%3D&amp;frame=false&amp;hideCard=false&amp;hideThread=false&amp;id=1566350128767987712&amp;lang=en&amp;origin=https%3A%2F%2Fwww.freecodecamp.org%2Fnews%2Fprepare-for-react-technical-interviews%2F&amp;sessionId=ca34f55d774caf9e9e474c46af8f2d97922ff724&amp;siteScreenName=freecodecamp&amp;theme=light&amp;widgetsVersion=1bfeb5c3714e8%3A1661975971032&amp;width=550px" data-tweet-id="1566350128767987712" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; position: static; visibility: visible; width: 550px; height: 297px; display: block; flex-grow: 1;" loading="lazy"></iframe></figure><p>(Todas las entrevistas son una entrevista de práctica hasta que obtienes tu primer trabajo de front-end. - William Shakespeare).</p><p>Y es verdad en gran medida.</p><p>Yo mismo he fallado cientas de veces anes de lograr obtener mi primer trabajo. Es la retroalimentación constante y las iteraciones que tienes que hacer para obtener lo que quieres.</p><p>En nuestro caso, obtener un trabajo de front-end es fácil cuando:</p><ul><li>Tienes un conocimiento profundo de tus habilidades – React en este caso (además de HTML, CSS, y JS).</li><li>Tienes un conjunto de proyectos para mostrar, haciendo que destaques.</li><li>Estas dispuesto a dedicar el tiempo y esfuerzo para aprender más y retarte a ti mismo.</li><li>Lees el blog y preguntas prácticas de freeCodeCamp regularmente &nbsp;(?)</li></ul><h2 id="conclusi-n"><strong><strong><strong>Conclusión</strong></strong></strong></h2><p>Hay muchas preguntas para practicar para una ronda de preguntas practicas. El entrevistador puede preguntarte diferentes preguntas para probar tus habilidades.<br><br>Puedes usar <strong><strong><a href="https://algochurn.com/">Algochurn</a></strong></strong> para practicar las <a href="https://www.algochurn.com/blog/top-5-react-front-end-questions-to-practice-before-a-technical-interview-round">preguntas de entrevista más populares de JavaScript</a>, <a href="https://www.algochurn.com/frontend">preguntas de entrevista de React</a>, y <a href="https://algochurn.com/problems">preguntas de algoritmos</a> realizadas comúnmente en entrevistas técnicas de front-end así como sus soluciones y enfoques.</p><p>Si tienes preguntas, por favor conecta conmigo a través de <a href="https://twitter.com/mannupaaji">Twitter (@mannupaaji)</a> y/o mi <a href="https://manuarora.in/">página web (manuarora.in)</a></p><p>¡Buena suerte y Happy Coding! ??</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo crear un portafolio web con React ]]>
                </title>
                <description>
                    <![CDATA[ Hoy vas a crear una de las aplicaciones web más importantes que puedes construir: tu portafolio de desarrollador. Todo desarrollador de React o desarrollador web en general necesita mostrar lo que puede hacer a potenciales clientes o empleadores. Eso es exactamente lo que vamos a construir a continuación, con la ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-crear-un-portafolio-web-con-react/</link>
                <guid isPermaLink="false">63187512b1786008d5613bd1</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ghers Fisman ]]>
                </dc:creator>
                <pubDate>Thu, 20 Oct 2022 19:20:24 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/09/react-portfolio-2021.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/build-portfolio-website-react/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How To Build A Simple Portfolio Blog With Next.js</a>
      </p><p>Hoy vas a crear una de las aplicaciones web más importantes que puedes construir: tu portafolio de desarrollador.</p><p>Todo desarrollador de React o desarrollador web en general necesita mostrar lo que puede hacer a potenciales clientes o empleadores.</p><p>Eso es exactamente lo que vamos a construir a continuación, con la ayuda de herramientas estándares de la industria como React, Tailwind CSS y Netlify.</p><p>¡Empecemos!</p><h2 id="-c-mo-se-ver-el-portafolio"><strong>¿Cómo se verá el Portafolio?</strong></h2><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/06/portfolio-1-min.gif" class="kg-image" alt="portfolio-1-min" width="600" height="400" loading="lazy"></figure><p>Esta es la versión final del portafolio que estaremos creando.</p><p>Incluirá información sobre ti, los proyectos que has hecho, las habilidades técnicas que has utilizado en esos proyectos, e información de contacto para que clientes o empleadores puedan comunicarse contigo.</p><h2 id="-qu-herramientas-estaremos-utilizando"><strong>¿Qué herramientas estaremos utilizando?</strong></h2><ul><li>Utilizaremos React para crear la interfaz de usuario de la aplicación. Nos permitirá componer cada parte de nuestra página de inicio a través de componentes reutilizables y extender nuestra aplicación si quisiéramos agregar funciones adicionales, como por ejemplo un blog.</li><li>Para dar estilo a nuestra aplicación, utilizaremos Tailwind CSS. Para darle a nuestra aplicación una apariencia profesional, Tailwind nos permitirá aplicar fácilmente múltiples estilos mediante la combinación de nombres de clases de nuestros elementos de React.</li><li>Para desplegar nuestra aplicación en la web, utilizaremos el servicio gratuito de Netlify. Se podrá acceder a nuestro proyecto en un dominio personalizado a usuarios rápidamente a través de un CDN (Red de Distribución de contenido, por sus siglas en inglés).</li></ul><h2 id="c-mo-empezar"><strong>Cómo empezar</strong></h2><p><em><strong><a href="https://reedbarger.com/resources/react-portfolio-2021">Puedes descargar los archivos iniciales de nuestro proyecto aquí</a></strong></em></p><p>Cuando tengas el código, todo lo que debes hacer es arrastrar la carpeta del proyecto (descomprimido) al editor de código y ejecutar el comando:</p><pre><code class="language-bash">npm install</code></pre><p>¡Y estás listo para empezar!</p><h2 id="-qu-herramientas-necesito-para-construir-mi-portafolio"><strong>¿Qué herramientas necesito para construir mi Portafolio?</strong></h2><p>Para seguir el proceso entero de crear nuestra aplicación web desde cero al despliegue, necesitarás lo siguiente:</p><ol><li>Node.js instalado en tu computador. Puedes descargarlo en nodejs.org.</li><li>Git instalado en tu computador. Puedes descargarlo en git-scm.com.</li><li>Te recomendaría utilizar VS Code como editor de código. Puedes descargarlo en code.visualstudio.com.</li><li>Una cuenta gratuita de Netlify en netlify.com.</li><li>Una cuenta gratuita de Github en github.com.</li></ol><h2 id="c-mo-construir-la-estructura-del-portafolio"><strong>Cómo construir la estructura del Portafolio</strong></h2><p>El beneficio de utilizar React es que podremos expandir nuestra aplicación a cuantas páginas queramos, de manera muy sencilla, y agregar mucho contenido adicional.</p><p>Sin embargo, dado que estamos trabajando únicamente con una página, podremos desde dentro del componente de la aplicación determinar los diferentes componentes necesarios muy rápidamente. Tendremos una Barra de Navegación (Navbar) en el nivel superior, con todos los enlaces que nos llevarán a las diferentes secciones del Portafolio.</p><p>Posteriormente, incluiremos las siguientes secciones: Acerca de mí (About), &nbsp;Proyectos (Projects), Testimonios (Testimonials), y para finalizar un formulario de contacto (Contact).</p><p>Esta rápida planificación nos permitirá entender cómo debemos llamar a nuestros componentes y en qué orden. Podemos comenzar agregándolos todos en nuestro archivo App.js (en src):</p><pre><code class="language-js">// src/App.js

import React from "react";

export default function App() {
  return (
    &lt;main&gt;
      &lt;Navbar /&gt;
      &lt;About /&gt;
      &lt;Projects /&gt;
      &lt;Skills /&gt;
      &lt;Testimonials /&gt;
      &lt;Contact /&gt;
    &lt;/main&gt;
  );
}</code></pre><h2 id="c-mo-crear-nuestros-componentes"><strong>Cómo crear nuestros componentes</strong></h2><p>Ahora que tenemos una lista con todos estos componentes necesitaremos crearlos.</p><p>Dentro de nuestra carpeta src, crearemos una carpeta llamada componentes con todos los archivos que necesitaremos:</p><pre><code>my-portfolio
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
└── src
    ├── App.js
    ├── data.js
    ├── index.css
    ├── index.js
    └── components
        ├── About.js
        ├── Contact.js
        ├── Navbar.js
        ├── Projects.js
        ├── Skills.js
        └── Testimonials.js</code></pre><p>Luego crearemos la estructura básica de cada componente de React y lo exportaremos desde ese archivo con <code>export default</code>:</p><pre><code class="language-js">// src/components/About.js

export default function About() {}

// repeat the same basic structure for all 6 components</code></pre><p>Y finalmente nos aseguraremos de importarlo en App.js:</p><pre><code class="language-js">// src/App.js

import React from "react";
import About from "./components/About";
import Contact from "./components/Contact";
import Navbar from "./components/Navbar";
import Projects from "./components/Projects";
import Skills from "./components/Skills";
import Testimonials from "./components/Testimonials";

export default function App() {
  return (
    &lt;main&gt;
      &lt;Navbar /&gt;
      &lt;About /&gt;
      &lt;Projects /&gt;
      &lt;Skills /&gt;
      &lt;Testimonials /&gt;
      &lt;Contact /&gt;
    &lt;/main&gt;
  );
}</code></pre><p><em>Notemos que debe haber seis componentes en total.</em></p><h2 id="introducci-n-a-tailwind-css"><strong>Introducción a Tailwind CSS</strong></h2><p>Una vez hayamos hecho eso, podemos empezar a trabajar con Tailwind CSS, para dar a nuestra aplicación una apariencia básica.</p><p>El beneficio de usar Tailwind CSS es que no tenemos que escribir ningún estilo manualmente en una página de CSS. Todo lo que debemos hacer es combinar múltiples clases para darle a la página la apariencia que queremos.</p><p>Por ejemplo, para dar a nuestro portafolio un fondo oscuro con texto gris aplicado a todos nuestros componentes hijos, puedes agregar las siguientes clases al elemento <code>main</code>:</p><pre><code class="language-js">// src/App.js

import React from "react";
import About from "./components/About";
import Contact from "./components/Contact";
import Navbar from "./components/Navbar";
import Projects from "./components/Projects";
import Skills from "./components/Skills";
import Testimonials from "./components/Testimonials";

export default function App() {
  return (
    &lt;main className="text-gray-400 bg-gray-900 body-font"&gt;
      &lt;Navbar /&gt;
      &lt;About /&gt;
      &lt;Projects /&gt;
      &lt;Skills /&gt;
      &lt;Testimonials /&gt;
      &lt;Contact /&gt;
    &lt;/main&gt;
  );
}</code></pre><h2 id="c-mo-construir-el-componente-about"><strong>Cómo construir el componente About</strong></h2><p>Empecemos con nuestra primera sección, la sección "Acerca de mí". Esta consistirá de una introducción básica de nosotros y en cuáles habilidades técnicas nos especializamos.</p><p>También incluirá algunos enlaces al formulario de contacto así como a nuestros proyectos. Dado que estos enlaces serán a diferentes partes de la misma página, podremos utilizar las etiquetas: "/#projects" y "/#contact".</p><p>Para hacer que estos enlaces funcionen correctamente y así poder dirigirnos a cada sección, estableceremos el atributo <code>id</code> de la sección proyectos a "projects" y los de la sección contacto a "contact".</p><pre><code class="language-js">// src/components/About.js

import React from "react";

export default function About() {
  return (
    &lt;section id="about"&gt;
      &lt;div className="container mx-auto flex px-10 py-20 md:flex-row flex-col items-center"&gt;
        &lt;div className="lg:flex-grow md:w-1/2 lg:pr-24 md:pr-16 flex flex-col md:items-start md:text-left mb-16 md:mb-0 items-center text-center"&gt;
          &lt;h1 className="title-font sm:text-4xl text-3xl mb-4 font-medium text-white"&gt;
            Hola, soy Reed
            &lt;br className="hidden lg:inline-block" /&gt;Me encanta construir aplicaciones web.
          &lt;/h1&gt;
          &lt;p className="mb-8 leading-relaxed"&gt;
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui
            laborum quasi, incidunt dolore iste nostrum cupiditate voluptas?
            Laborum, voluptas natus?
          &lt;/p&gt;
          &lt;div className="flex justify-center"&gt;
            &lt;a
              href="#contact"
              className="inline-flex text-white bg-green-500 border-0 py-2 px-6 focus:outline-none hover:bg-green-600 rounded text-lg"&gt;
              Trabaja conmigo
            &lt;/a&gt;
            &lt;a
              href="#projects"
              className="ml-4 inline-flex text-gray-400 bg-gray-800 border-0 py-2 px-6 focus:outline-none hover:bg-gray-700 hover:text-white rounded text-lg"&gt;
              Mira mis trabajos anteriores
            &lt;/a&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div className="lg:max-w-lg lg:w-full md:w-1/2 w-5/6"&gt;
          &lt;img
            className="object-cover object-center rounded"
            alt="hero"
            src="./coding.svg"
          /&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/section&gt;
  );
}</code></pre><p>Para la imagen en el lado derecho de la sección, utilizaremos un archivo svg tomado de la carpeta <code>public</code>: coding.svg.</p><p>Esta imagen funciona simplemente como un <em>placeholder</em> (marcador de posición) temporal. Recomiendo enfáticamente utilizar una imagen real de ti mismo.</p><h2 id="c-mo-construir-el-componente-projects"><strong>Cómo construir el componente Projects</strong></h2><p>Nuestra sección de proyectos consistirá de un elemento <code>section</code> con un <code>id</code> of "projects". La sección mostrará una galería de todos los proyectos que hemos desarrollado, con imágenes incluidas.</p><p>Tendrá el título del proyecto, las tecnologías con la que lo construimos, y un enlace (si está desplegado).</p><pre><code class="language-js">// src/components/Projects.js

import { CodeIcon } from "@heroicons/react/solid";
import React from "react";
import { projects } from "../data";

export default function Projects() {
  return (
    &lt;section id="projects" className="text-gray-400 bg-gray-900 body-font"&gt;
      &lt;div className="container px-5 py-10 mx-auto text-center lg:px-40"&gt;
        &lt;div className="flex flex-col w-full mb-20"&gt;
          &lt;CodeIcon className="mx-auto inline-block w-10 mb-4" /&gt;
          &lt;h1 className="sm:text-4xl text-3xl font-medium title-font mb-4 text-white"&gt;
            Aplicaciones que he construido
          &lt;/h1&gt;
          &lt;p className="lg:w-2/3 mx-auto leading-relaxed text-base"&gt;
            Lorem ipsum, dolor sit amet consectetur adipisicing elit. Explicabo
            facilis repellat ab cupiditate alias vero aliquid obcaecati quisquam
            fuga dolore.
          &lt;/p&gt;
        &lt;/div&gt;
        &lt;div className="flex flex-wrap -m-4"&gt;
          {projects.map((project) =&gt; (
            &lt;a
              href={project.link}
              key={project.image}
              className="sm:w-1/2 w-100 p-4"&gt;
              &lt;div className="flex relative"&gt;
                &lt;img
                  alt="gallery"
                  className="absolute inset-0 w-full h-full object-cover object-center"
                  src={project.image}
                /&gt;
                &lt;div className="px-8 py-10 relative z-10 w-full border-4 border-gray-800 bg-gray-900 opacity-0 hover:opacity-100"&gt;
                  &lt;h2 className="tracking-widest text-sm title-font font-medium text-green-400 mb-1"&gt;
                    {project.subtitle}
                  &lt;/h2&gt;
                  &lt;h1 className="title-font text-lg font-medium text-white mb-3"&gt;
                    {project.title}
                  &lt;/h1&gt;
                  &lt;p className="leading-relaxed"&gt;{project.description}&lt;/p&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/a&gt;
          ))}
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/section&gt;
  );
}</code></pre><p>También utilizaremos la librería <code>@heroicons/react</code> para poder acceder a iconos SVG como componentes de React.</p><p>Estaremos importando un arreglo (array) de proyectos del archivo data.js en la misma carpeta. Allí estamos exportando un arreglo de objetos que incluirá cada uno la data individual de cada proyecto:</p><pre><code class="language-js">// src/data.js

export const projects = [
  {
    title: "React Reserve",
    subtitle: "MERN Stack",
    description:
      "Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium dolore rerum laborum iure enim sint nemo omnis voluptate exercitationem eius?",
    image: "./project-1.gif",
    link: "https://reactbootcamp.com",
  },
  {
    title: "React Tracks",
    subtitle: "React and Python",
    description:
      "Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium dolore rerum laborum iure enim sint nemo omnis voluptate exercitationem eius?",
    image: "./project-2.gif",
    link: "https://reedbarger.com",
  },
  {
    title: "DevChat",
    subtitle: "React and Firebase",
    description:
      "Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium dolore rerum laborum iure enim sint nemo omnis voluptate exercitationem eius?",
    image: "./project-3.gif",
    link: "https://jsbootcamp.com",
  },
  {
    title: "Epic Todo App",
    subtitle: "React Hooks",
    description:
      "Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium dolore rerum laborum iure enim sint nemo omnis voluptate exercitationem eius?",
    image: "./project-4.gif",
    link: "https://pythonbootcamp.com",
  },
];</code></pre><h2 id="c-mo-construir-el-componente-skills"><strong>Cómo construir el componente Skills</strong></h2><p>Completemos la sección de todas nuestras habilidades y las tecnologías que manejamos.</p><p>Esta sección consistirá de una simple lista de todas las herramientas con las que estamos familiarizados y seremos capaces de utilizar en los proyectos de nuestros empleadores o clientes.</p><p>Una vez más, importaremos un arreglo desde nuestra carpeta de data. Pero este arreglo consiste de un número de cadenas (strings) que representan cada una de las habilidades como JavaScript, React y Node:</p><pre><code class="language-js">// src/components/Skills.js

import { BadgeCheckIcon, ChipIcon } from "@heroicons/react/solid";
import React from "react";
import { skills } from "../data";

export default function Skills() {
  return (
    &lt;section id="skills"&gt;
      &lt;div className="container px-5 py-10 mx-auto"&gt;
        &lt;div className="text-center mb-20"&gt;
          &lt;ChipIcon className="w-10 inline-block mb-4" /&gt;
          &lt;h1 className="sm:text-4xl text-3xl font-medium title-font text-white mb-4"&gt;
            Habilidades y Tecnologías
          &lt;/h1&gt;
          &lt;p className="text-base leading-relaxed xl:w-2/4 lg:w-3/4 mx-auto"&gt;
            Lorem ipsum dolor sit amet consectetur, adipisicing elit. Nisi sit
            ipsa delectus eum quo voluptas aspernatur accusantium distinctio
            possimus est.
          &lt;/p&gt;
        &lt;/div&gt;
        &lt;div className="flex flex-wrap lg:w-4/5 sm:mx-auto sm:mb-2 -mx-2"&gt;
          {skills.map((skill) =&gt; (
            &lt;div key={skill} className="p-2 sm:w-1/2 w-full"&gt;
              &lt;div className="bg-gray-800 rounded flex p-4 h-full items-center"&gt;
                &lt;BadgeCheckIcon className="text-green-400 w-6 h-6 flex-shrink-0 mr-4" /&gt;
                &lt;span className="title-font font-medium text-white"&gt;
                  {skill}
                &lt;/span&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          ))}
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/section&gt;
  );
}</code></pre><h2 id="c-mo-construir-el-componente-testimonials"><strong>Cómo construir el componente Testimonials </strong></h2><p>En el componente de testimonios, crearemos una lista con testimonios de antiguos clientes u otras personas que estén familiarizadas con nuestro trabajo.</p><p>Estos consistirán de tarjetas que incluirán el testimonio, así como el autor y la compañía para la que esta persona trabaja.</p><p>También importaremos un arreglo de testimonios con un número de objetos que incluirán la cita, imagen, nombre y compañía.</p><pre><code class="language-js">// src/components/Testimonials

import React from "react";
import { TerminalIcon, UsersIcon } from "@heroicons/react/solid";
import { testimonials } from "../data";

export default function Testimonials() {
  return (
    &lt;section id="testimonials"&gt;
      &lt;div className="container px-5 py-10 mx-auto text-center"&gt;
        &lt;UsersIcon className="w-10 inline-block mb-4" /&gt;
        &lt;h1 className="sm:text-4xl text-3xl font-medium title-font text-white mb-12"&gt;
          Testimonios de clientes
        &lt;/h1&gt;
        &lt;div className="flex flex-wrap m-4"&gt;
          {testimonials.map((testimonial) =&gt; (
            &lt;div className="p-4 md:w-1/2 w-full"&gt;
              &lt;div className="h-full bg-gray-800 bg-opacity-40 p-8 rounded"&gt;
                &lt;TerminalIcon className="block w-8 text-gray-500 mb-4" /&gt;
                &lt;p className="leading-relaxed mb-6"&gt;{testimonial.quote}&lt;/p&gt;
                &lt;div className="inline-flex items-center"&gt;
                  &lt;img
                    alt="testimonial"
                    src={testimonial.image}
                    className="w-12 rounded-full flex-shrink-0 object-cover object-center"
                  /&gt;
                  &lt;span className="flex-grow flex flex-col pl-4"&gt;
                    &lt;span className="title-font font-medium text-white"&gt;
                      {testimonial.name}
                    &lt;/span&gt;
                    &lt;span className="text-gray-500 text-sm uppercase"&gt;
                      {testimonial.company}
                    &lt;/span&gt;
                  &lt;/span&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          ))}
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/section&gt;
  );
}</code></pre><h2 id="c-mo-construir-el-componente-contact"><strong>Cómo construir el componente contact</strong></h2><p>Al final de nuestra página, incluiremos un formulario de contacto para así permitir e los potenciales empleadores comunicarse con nosotros.</p><p>Este formulario tendrá tres campos: nombre, correo electrónico y mensaje.</p><p>Para recibir esta información, utilizaremos la herramienta Netlify Forms, que se encargará fácilmente de guardar estos mensajes.</p><pre><code class="language-js">// src/components/Contact.js

import React from "react";

export default function Contact() {
  return (
    &lt;section id="contact" className="relative"&gt;
      &lt;div className="container px-5 py-10 mx-auto flex sm:flex-nowrap flex-wrap"&gt;
        &lt;div className="lg:w-2/3 md:w-1/2 bg-gray-900 rounded-lg overflow-hidden sm:mr-10 p-10 flex items-end justify-start relative"&gt;
          &lt;iframe
            width="100%"
            height="100%"
            title="map"
            className="absolute inset-0"
            frameBorder={0}
            marginHeight={0}
            marginWidth={0}
            style={{ filter: "opacity(0.7)" }}
            src="https://www.google.com/maps/embed/v1/place?q=97+warren+st+new+york+city&amp;key=AIzaSyBFw0Qbyq9zTFTd-tUY6dZWTgaQzuU17R8"
          /&gt;
          &lt;div className="bg-gray-900 relative flex flex-wrap py-6 rounded shadow-md"&gt;
            &lt;div className="lg:w-1/2 px-6"&gt;
              &lt;h2 className="title-font font-semibold text-white tracking-widest text-xs"&gt;
                DIRECCIÓN
              &lt;/h2&gt;
              &lt;p className="mt-1"&gt;
                97 Warren St. &lt;br /&gt;
                New York, NY 10007
              &lt;/p&gt;
            &lt;/div&gt;
            &lt;div className="lg:w-1/2 px-6 mt-4 lg:mt-0"&gt;
              &lt;h2 className="title-font font-semibold text-white tracking-widest text-xs"&gt;
                CORREO ELECTRÓNICO
              &lt;/h2&gt;
              &lt;a className="text-indigo-400 leading-relaxed"&gt;
                reedbarger@email.com
              &lt;/a&gt;
              &lt;h2 className="title-font font-semibold text-white tracking-widest text-xs mt-4"&gt;
                NÚMERO DE TELÉFONO
              &lt;/h2&gt;
              &lt;p className="leading-relaxed"&gt;123-456-7890&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;form
          netlify
          name="contact"
          className="lg:w-1/3 md:w-1/2 flex flex-col md:ml-auto w-full md:py-8 mt-8 md:mt-0"&gt;
          &lt;h2 className="text-white sm:text-4xl text-3xl mb-1 font-medium title-font"&gt;
            ¡Contrátame!
          &lt;/h2&gt;
          &lt;p className="leading-relaxed mb-5"&gt;
            Lorem ipsum dolor sit amet consectetur, adipisicing elit. Illum
            suscipit officia aspernatur veritatis. Asperiores, aliquid?
          &lt;/p&gt;
          &lt;div className="relative mb-4"&gt;
            &lt;label htmlFor="name" className="leading-7 text-sm text-gray-400"&gt;
              Nombre
            &lt;/label&gt;
            &lt;input
              type="text"
              id="name"
              name="name"
              className="w-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 text-base outline-none text-gray-100 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
            /&gt;
          &lt;/div&gt;
          &lt;div className="relative mb-4"&gt;
            &lt;label htmlFor="email" className="leading-7 text-sm text-gray-400"&gt;
              Correo electrónico
            &lt;/label&gt;
            &lt;input
              type="email"
              id="email"
              name="email"
              className="w-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 text-base outline-none text-gray-100 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
            /&gt;
          &lt;/div&gt;
          &lt;div className="relative mb-4"&gt;
            &lt;label
              htmlFor="message"
              className="leading-7 text-sm text-gray-400"&gt;
              Mensaje
            &lt;/label&gt;
            &lt;textarea
              id="message"
              name="message"
              className="w-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 h-32 text-base outline-none text-gray-100 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out"
            /&gt;
          &lt;/div&gt;
          &lt;button
            type="submit"
            className="text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"&gt;
            Enviar
          &lt;/button&gt;
        &lt;/form&gt;
      &lt;/div&gt;
    &lt;/section&gt;
  );
}</code></pre><h2 id="c-mo-insertar-una-ubicaci-n-de-google-maps"><strong>Cómo insertar una ubicación de Google Maps</strong></h2><p>A la izquierda del formulario incluiremos un mapa de Google Maps con nuestra ubicación.</p><p>Lo haremos con la ayuda de una herramienta online: embed-map.com. Todo lo que hay que hacer es ingresar la ubicación y presionar "Generate HTML code".</p><p>Del código proporcionado por la aplicación, no debemos copiar la totalidad, sólo el atributo <code>src</code> del elemento iframe. Reemplazaremos dicho valor con el valor por defecto <code>src</code> de nuestro iframe.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/06/portfolio-2.png" class="kg-image" alt="portfolio-2" width="600" height="400" loading="lazy"></figure><p>Para enviar cualquier data del formulario a Netlify, Netlify Forms necesita reconocer un formulario como HTML estático. Dado que nuestra aplicación de React es controlada por JavaScript y no es únicamente HTML puro, necesitamos agregar un formulario escondido a nuestro archivo index.html en la carpeta public.</p><pre><code class="language-html">&lt;!-- public/index.html --&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;!-- head content skipped --&gt;
  &lt;/head&gt;
  &lt;body&gt;

  &lt;form name="contact" netlify netlify-honeypot="bot-field" hidden&gt;
    &lt;input type="text" name="name" /&gt;
    &lt;input type="email" name="email" /&gt;
    &lt;textarea name="message"&gt;&lt;/textarea&gt;
  &lt;/form&gt;
  
    &lt;noscript&gt;Necesitas activar JavaScript para correr esta aplicación.&lt;/noscript&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre><p>Tendremos que esconder este formulario, porque no debe ser visto por el usuario, solo por Netlify.</p><p>Le daremos el atributo, <code>hidden</code> así como el atributo <code>name</code> que concuerda con el formulario JSX en Contact.js. También debemos darle el atributo <code>netlify</code> para que así Netlify Forms lo reconozca. Finalmente, debemos incluir todos los campos que nuestro formulario JSX: nombre, correo electrónico y mensaje.</p><h2 id="c-mo-enviar-el-formulario-de-contacto"><strong>Cómo enviar el formulario de contacto</strong></h2><p>Una vez terminado lo anterior, regresaremos a Contact.js. Utilizaremos JavaScript para poder enviar este formulario.</p><p>Primero que nada, crearemos un estado dedicado para cada uno de los valores que se encuentran en el formulario para nombre (name), correo electrónico (email) y mensaje (message):</p><pre><code class="language-js">const [name, setName] = React.useState("");
const [email, setEmail] = React.useState("");
const [message, setMessage] = React.useState("");</code></pre><p>Almacenaremos lo que el usuario escriba en cada uno de los campos en el estado con la ayuda del manipulador (handler) <code>onChange</code>.</p><p>Para manipular el envío del formulario, le agregaremos el prop <code>onSubmit</code>. La función que se llamará, <code>handleSubmit</code>, hará una solicitud post al endpoint "/" con toda la data de nuestro formulario.</p><p>Estableceremos los encabezados de la petición para indicar que nos encontramos enviando la data del formulario. Para el cuerpo de la petición, incluiremos el nombre del formulario así como toda la data del formulario incluida en las variables de estado <code>name</code>, <code>email</code>, y <code>message</code>.</p><pre><code class="language-js">// src/components/Contact.js

import React from "react";

export default function Contact() {
  const [name, setName] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [message, setMessage] = React.useState("");

  function encode(data) {
    return Object.keys(data)
      .map(
        (key) =&gt; encodeURIComponent(key) + "=" + encodeURIComponent(data[key])
      )
      .join("&amp;");
  }

  function handleSubmit(e) {
    e.preventDefault();
    fetch("/", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: encode({ "form-name": "contact", name, email, message }),
    })
      .then(() =&gt; alert("Message sent!"))
      .catch((error) =&gt; alert(error));
  }

  return (
    &lt;section id="contact" className="relative"&gt;
      &lt;div className="container px-5 py-10 mx-auto flex sm:flex-nowrap flex-wrap"&gt;
        &lt;div className="lg:w-2/3 md:w-1/2 bg-gray-900 rounded-lg overflow-hidden sm:mr-10 p-10 flex items-end justify-start relative"&gt;
          &lt;iframe
            width="100%"
            height="100%"
            title="map"
            className="absolute inset-0"
            frameBorder={0}
            marginHeight={0}
            marginWidth={0}
            style={{ filter: "opacity(0.7)" }}
            src="https://www.google.com/maps/embed/v1/place?q=97+warren+st+new+york+city&amp;key=AIzaSyBFw0Qbyq9zTFTd-tUY6dZWTgaQzuU17R8"
          /&gt;
          &lt;div className="bg-gray-900 relative flex flex-wrap py-6 rounded shadow-md"&gt;
            &lt;div className="lg:w-1/2 px-6"&gt;
              &lt;h2 className="title-font font-semibold text-white tracking-widest text-xs"&gt;
                DIRECCIÓN
              &lt;/h2&gt;
              &lt;p className="mt-1"&gt;
                97 Warren St. &lt;br /&gt;
                New York, NY 10007
              &lt;/p&gt;
            &lt;/div&gt;
            &lt;div className="lg:w-1/2 px-6 mt-4 lg:mt-0"&gt;
              &lt;h2 className="title-font font-semibold text-white tracking-widest text-xs"&gt;
                CORREO ELECTRÓNICO
              &lt;/h2&gt;
              &lt;a className="text-indigo-400 leading-relaxed"&gt;
                reedbarger@email.com
              &lt;/a&gt;
              &lt;h2 className="title-font font-semibold text-white tracking-widest text-xs mt-4"&gt;
                NÚMERO DE TELÉFONO
              &lt;/h2&gt;
              &lt;p className="leading-relaxed"&gt;123-456-7890&lt;/p&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;form
          netlify
          name="contact"
          onSubmit={handleSubmit}
          className="lg:w-1/3 md:w-1/2 flex flex-col md:ml-auto w-full md:py-8 mt-8 md:mt-0"&gt;
          &lt;h2 className="text-white sm:text-4xl text-3xl mb-1 font-medium title-font"&gt;
            ¡Contrátame!
          &lt;/h2&gt;
          &lt;p className="leading-relaxed mb-5"&gt;
            Lorem ipsum dolor sit amet consectetur, adipisicing elit. Illum
            suscipit officia aspernatur veritatis. Asperiores, aliquid?
          &lt;/p&gt;
          &lt;div className="relative mb-4"&gt;
            &lt;label htmlFor="name" className="leading-7 text-sm text-gray-400"&gt;
              Nombre
            &lt;/label&gt;
            &lt;input
              type="text"
              id="name"
              name="name"
              className="w-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 text-base outline-none text-gray-100 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
              onChange={(e) =&gt; setName(e.target.value)}
            /&gt;
          &lt;/div&gt;
          &lt;div className="relative mb-4"&gt;
            &lt;label htmlFor="email" className="leading-7 text-sm text-gray-400"&gt;
              Correo electrónico
            &lt;/label&gt;
            &lt;input
              type="email"
              id="email"
              name="email"
              className="w-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 text-base outline-none text-gray-100 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
              onChange={(e) =&gt; setEmail(e.target.value)}
            /&gt;
          &lt;/div&gt;
          &lt;div className="relative mb-4"&gt;
            &lt;label
              htmlFor="message"
              className="leading-7 text-sm text-gray-400"&gt;
              Mensaje
            &lt;/label&gt;
            &lt;textarea
              id="message"
              name="message"
              className="w-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 h-32 text-base outline-none text-gray-100 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out"
              onChange={(e) =&gt; setMessage(e.target.value)}
            /&gt;
          &lt;/div&gt;
          &lt;button
            type="submit"
            className="text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"&gt;
            Enviar
          &lt;/button&gt;
        &lt;/form&gt;
      &lt;/div&gt;
    &lt;/section&gt;
  );
}</code></pre><p>Como puedes observar arriba, estamos codificando la data del formulario con una función especial <code>encode</code> que puedes ver aquí.</p><p>Si el mensaje es enviado correctamente, mostraremos una alerta que diga "Mensaje enviado". En caso de que haya un error, alertaremos al usuario del mismo.</p><h2 id="c-mo-construir-el-componente-navbar"><strong>Cómo construir el componente Navbar</strong></h2><p>El último paso es construir el componente de la Barra de Navegación.</p><p>Queremos que la barra de navegación se mantenga en la parte superior de la pantalla en dispositivos grandes, pero no en dispositivos móviles.</p><p>Adicionalmente, querremos incluir enlaces a cada una de las secciones relevantes: proyectos, habilidades, testimonios y formulario de contacto:</p><pre><code class="language-js">// src/components/Navbar.js

import { ArrowRightIcon } from "@heroicons/react/solid";
import React from "react";

export default function Navbar() {
  return (
    &lt;header className="bg-gray-800 md:sticky top-0 z-10"&gt;
      &lt;div className="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center"&gt;
        &lt;a className="title-font font-medium text-white mb-4 md:mb-0"&gt;
          &lt;a href="#about" className="ml-3 text-xl"&gt;
            Reed Barger
          &lt;/a&gt;
        &lt;/a&gt;
        &lt;nav className="md:mr-auto md:ml-4 md:py-1 md:pl-4 md:border-l md:border-gray-700	flex flex-wrap items-center text-base justify-center"&gt;
          &lt;a href="#projects" className="mr-5 hover:text-white"&gt;
            Trabajos anteriores
          &lt;/a&gt;
          &lt;a href="#skills" className="mr-5 hover:text-white"&gt;
            Habilidades
          &lt;/a&gt;
          &lt;a href="#testimonials" className="mr-5 hover:text-white"&gt;
            Testimonios
          &lt;/a&gt;
        &lt;/nav&gt;
        &lt;a
          href="#contact"
          className="inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0"&gt;
          ¡Contrátame!
          &lt;ArrowRightIcon className="w-4 h-4 ml-1" /&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/header&gt;
  );
}</code></pre><p>¿Cómo haremos para mantener la barra de navegación en la parte superior de la pantalla en dispositivos grandes? Con la ayuda de la clase <code>md:sticky</code> en nuestro elemento <code>header</code>.</p><p>Esta clase significa que se aplicará la regla de estilo <code>position: sticky;</code> a partir del punto de corte mediano (768px).</p><h2 id="c-mo-desplegar-tu-portafolio"><strong>Cómo desplegar tu Portafolio</strong></h2><p>Ahora, para desplegar el portafolio en la web, necesitaremos cargar (push) nuestra aplicación a GitHub.</p><p>Si no estás familiarizado con Git y GitHub, deberías tomarte unos momentos para aprender a cargar tu código en GitHub por primera vez. Es una habilidad esencial que todo desarrollador web debe tener.</p><p>Una vez estés familiarizado con este proceso, podemos crear un nuevo repositorio de GitHub. Luego, correremos los comandos <code>git add .</code>, <code>git commit -m "Despliegue"</code>, crear nuestro git remoto, y <code>git push -u origin master</code>.</p><p>Una vez nuestro proyecto esté en GitHub, podremos ir a Netlify y seleccionar la opción "Choose Site from Git" (Escoger sitio desde Git). Allí seleccionaremos GitHub para nuestros despliegues continuados, y seleccionaremos el repositorio de GitHub al que acabamos de cargar nuestro código.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/06/portfolio-3-min.gif" class="kg-image" alt="portfolio-3-min" width="600" height="400" loading="lazy"></figure><p>Luego de esto, ¡nuestro proyecto será desplegado automáticamente a la web!</p><h2 id="pr-ximos-pasos"><strong>Próximos pasos</strong></h2><p>¡Felicidades! Ya tienes tu propio portafolio personal desplegado en la web, mostrando todos tus proyectos y habilidades a potenciales empleadores.</p><p>El próximo paso será configurar un dominio personalizado, preferiblemente con tu nombre (ej. reedbarger.com). Dado que Netlify incluye un DNS (Sistema de Nombres de Dominios, por sus siglas en inglés), esto podrás hacerlo fácilmente con sus herramientas.</p><p>Piensa en quizás agregar un blog a tu aplicación de React para así presumir aún más de tus conocimientos como desarrollador ante potenciales empleadores.</p><p>Haz que tu portafolio personal sea una expresión de ti mismo y lo que te apasiona como desarrollador, y serás exitoso.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Live Server de VSCode no funciona ]]>
                </title>
                <description>
                    <![CDATA[ VSCode tiene muchas extensiones de alta calidad, y Live Server [https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer] es una de las mejores. Con solo un par de clics, Live Server te permitirá ver tu página en vivo en un navegador real. Mejor aún, cuenta con recarga en vivo (live reloading), por lo que si actualizas tu ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/live-server-de-vscode-no-funciona/</link>
                <guid isPermaLink="false">631f9fc3b1786008d5615791</guid>
                
                    <category>
                        <![CDATA[ visual studio code ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ghers Fisman ]]>
                </dc:creator>
                <pubDate>Mon, 17 Oct 2022 02:56:12 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/09/vscode_live_server.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/visual-studio-code-live-server-not-working/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Visual Studio Code Live Server Not Working</a>
      </p><p>VSCode tiene muchas extensiones de alta calidad, y <a href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer">Live Server</a> es una de las mejores.</p><p>Con solo un par de clics, Live Server te permitirá ver tu página en vivo en un navegador real. Mejor aún, cuenta con recarga en vivo (live reloading), por lo que si actualizas tu código, los cambios también se verán reflejados en el navegador.</p><p>Todo lo que debes hacer es clic derecho en el archivo HTML que quieres ver, y luego seleccionar "Abrir con Live Server" (Open with Live Server):</p><p>¿Pero y si el Live Server no abre el navegador para mostrar la página que esperas? Si esto te está sucediendo, aquí hay un para de posibles soluciones que puedes probar.</p><h2 id="reinicia-vscode"><strong>Reinicia VSCode</strong></h2><p>Algunas veces lo mejor que puedes hacer es iniciar VSCode desde cero.</p><p>Primero, guarda todo tu trabajo. Luego cierra VSCode, lo que también detendrá todas las extensiones que hayas instalado.</p><p>Luego, vuelve a abrir VSCode e intenta de nuevo - ve al archivo HTML que quieres ver, y selecciona "Abrir con Live Server".</p><h2 id="configura-el-navegador-de-live-server"><strong>Configura el navegador de Live Server</strong></h2><p>Es posible que la extensión esté funcionando, pero tu sistema no cuente con un navegador por defecto.</p><p>Incluso si configuraste el navegador por defecto para tu sistema, no estaría de más hacerle saber a Live Server cuál navegador estarás utilizando, de manera explícita.</p><p>En primer lugar, abre la paleta de comandos de VSCode (Command Palette) con F1, luego escribe <code>Preferences: Open Settings (JSON)</code> y selecciona esa opción.</p><p>Esto abrirá tu archivo <code>settings.json</code> de VSCode.</p><p>Desplázate a la parte inferior del archivo, agrega una coma después de la última configuración, y pega <code>"liveServer.settings.CustomBrowser": "chrome"</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2020/09/settings-json.gif" class="kg-image" alt="settings-json" width="600" height="400" loading="lazy"></figure><p>Ten en cuenta que también puedes utilizar <code>"firefox"</code>, <code>"safari"</code>, o cualquier otro navegador como valor para la configuración <code>"liveServer.settings.CustomBrowser"</code>.</p><p>Para finalizar, guarda el archivo <code>settings.json</code> e intenta abrir el Live Server de nuevo.</p><h2 id="configura-el-navegador-por-defecto-de-tu-sistema-operativo"><strong>Configura el navegador por defecto de tu sistema operativo</strong></h2><p>Incluso luego de indicar a Live Server cuál navegador quieres usar, es posible que aún no esté abriendo la página correctamente en ese navegador.</p><p>Lo próximo que intentaremos es configurar el navegador por defecto del propio sistema operativo.</p><p>El método exacto para hacer esto puede variar dependiendo de tu sistema operativo, así que lo mejor es investigar cómo hacer esto si no estás seguro.</p><p>Así luce la página de configuración en Windows:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/09/image-56.png" class="kg-image" alt="image-56" width="600" height="400" loading="lazy"><figcaption>Credit: <a href="https://forum.freecodecamp.org/u/Advitya-sharma" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Advitya-sharma</a></figcaption></figure><h2 id="dir-gete-a-la-p-gina-en-vivo-t-mismo"><strong>Dirígete a la página en vivo tú mismo</strong></h2><p>Si por alguna razón el Live Server sigue sin abrir automáticamente en tu navegador, no te preocupes. Siempre puedes abrir el navegador de tu preferencia y ver la página directamente.</p><p>Simplemente, abre tu navegador de preferencia y dirígete a <code>http://127.0.0.1:5500/&lt;your_file_name&gt;</code>.</p><p>Por ejemplo, si tu archivo se llama <code>index.html</code>, simplemente dirígete a <code>http://127.0.0.1:5500/index.html</code>.</p><p>Siempre que el Live Server esté corriendo, deberías poder ver tu página.</p><h2 id="para-cerrar"><strong>Para cerrar</strong></h2><p>Estas son algunas soluciones comunes que puedes probar si la extensión Live Server de VSCode no está funcionando de la manera que esperas.</p><p>Cuídate, y feliz codificación (en vivo).</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
