Fundamentos de React
Tags: react, frontend, javascript, functional
Published: 2020-04-21 19:23:33

---
series: react-fundamentals
---

# Tabla de contenido
1. [Introducción](#introduccion)
2. [¿Qué son los componentes web?](#que-son-los-componentes)
3. [Componentes funcionales con React](#componentes-funcionales)
4. [Múltiples componentes](#multiples-componentes)
5. [Comunicación entre componentes](#comunicacion)
6. [Comunicación de hijos a padres, eventos y... ¡Hooks!](#hijos-padres-hooks)
7. [El fin :(](#fin)

##Introducción<a name="introduccion">

¡Hey! El día de hoy vamos a continuar con el tutorial de React, si no tuviste la oportunidad de leer mi artículo anterior [aquí](https://dev.to/izakntun/introduccion-a-react-5hl2) te lo dejo, el cual fue una  introducción a React, realmente no profundizamos mucho pero fue suficiente para comprender el funcionamiento de nuestra librería favorita.

En esta ocasión vamos a continuar trabajando en nuestro archivo `app.js`, si recordamos como se miraba nuestro `app.js`:

```react

const greeting = 'Hola React!'
const element = <h1>{greeting}</h1>

ReactDOM.render(
    element,
    document.getElementById('root')
)
```

Vamos a seguir sobre el mismo camino. **ACLARACIÓN** esta serie de artículos solo son tutoriales básicos, la implementación no debería usarse para producción, aclarado esto, continuemos.

##¿Qué son los componentes web? <a name="que-son-los-componentes">

Una de las características de las librerías y frameworks actuales como [React](https://reactjs.org), [Vue](https://vuejs.org) o [Angular](https://angular.io) entre otros, es el paradigma que siguen y este se llama _basado_ _en_ _componentes_, pero ¿qué son los componentes?, según la [Wikipedia](https://es.wikipedia.org/wiki/Programaci%C3%B3n_orientada_a_componentes), define un componente de la siguiente manera:

>#### Definición de componente
> Un componente de software es un elemento de un sistema que ofrece un servicio predefinido, y es capaz de comunicarse con otros componentes.

No vamos a entrar a detalle para no extendernos más con la teoría y para explicarlo mejor nos vamos directo al código, entonces tenemos la siguiente línea:

```react
const element = <h1>{greeting}</h1>
```

Prácticamente eso podría ser un "componente", sin embargo vamos a entrar en materia, existen dos formas de crear componentes en React, la primera y la que en su momento fue la mas usada son los componentes de clase,hoy en día y según la documentación oficial de [React](https://reactjs.org/docs/hooks-intro.html#gradual-adoption-strategy), todos deberíamos comenzar a migrar a la segunda forma que son los componentes funcionales, y aunque no hay planes **AÚN** de remover los componentes de clase, los creadores de React nos sugieren dejar de usarlos y en su lugar utilizar los _functional_ _components_ haciendo uso de _hooks_, y por eso en esta serie de tutoriales los usaremos.

## Componentes funcionales con React<a name="componentes-funcionales">

Como vimos en el bloque anterior tenemos asignada una etiqueta `h1` a nuestra constante `element`, vamos a convertir eso en un componente funcional de la siguiente manera:
```react
const Element = () => (<h1>{greeting}</h1>)
```

Bien, en este tutorial haremos uso de las nuevas (_ni_ _tan_ _nuevas_) características que nos ofrece la especificación EcmaScript y deberías estar familiarizado con ella, bueno, definimos una función que retorna nuestra etiqueta `h1`, los paréntesis son la forma en la que podemos retornar elementos `JSX`, pero ¿cómo hacemos uso de este nuevo componente que hemos creado?, nuestro código se vería de la siguiente manera:

```react
const greeting = 'Hola React!'
const Element = () => (<h1>{greeting}</h1>)

ReactDOM.render(
    <Element />,
    document.getElementById('root')
)
```

Como puedes observar dentro del método `render` de la clase `ReactDOM` sustituimos nuestra constante `element`, por la función `Element` que acabamos de crear, en React todos los componentes deben empezar con mayúscula y utilizando `camel case`, el elemento `<Element />` es el método que acabamos de construir, solo que esta expresado en sintaxis `JSX`, como puedes ver crear componentes con React es muy sencillo, sin embargo podemos hacer mucho mas que eso.

## Múltiples componentes<a name="multiples-componentes">

Podemos crear múltiples componentes que pueden ser usados dentro de otros componentes, sí continuamos con nuestro ejemplo vamos a crear otro componente de la siguiente manera:

```react
const Button = () => (<button>click me</button>)
```

Hemos creado un componente `Button` que en este momento no hace absolutamente nada, pero aún así lo vamos a ocupar, vamos a realizar unos cambios a nuestro componente `Element` para poder usar nuestro componente `Button` en él:

```react
const Element = () => {
    return (
        <React.Fragment>
            <h1>{greeting}</h1>
            <Button />
        </React.Fragment>
    )
}
```

Ok, vamos a explicar algunas cosas que podemos observar en las modificaciones que realizamos, la primera, estamos retornando en nuestro `jsx` la etiqueta `h1` y nuestro componente `Button`, pero si eres observador puedes darte cuenta que están dentro de una etiqueta `<React.Fragment></React.Fragment>`, esto es porque todos los componentes en React necesitan tener una etiqueta padre, esto quiere decir que nosotros no podemos solo retornar dos o mas elementos `jsx` o _componentes_ que estén al nivel mas alto, es por eso que hemos envuelto nuestro `h1` y nuestro componente `Button` con una etiqueta `<React.Fragment></React.Fragment>`, pudimos haberlo echo con una etiqueta `div`, la diferencia es que `<React.Fragment></React.Fragment>`, no nos crea ningún elemento `html`, solo nos ayuda a cumplir la regla, de modo que si lo hiciéramos con una etiqueta `div`, esta se renderizaría en nuestro `html` y realmente no la necesitamos, puedes leer en la [documentación oficial](https://es.reactjs.org/docs/fragments.html) de React acerca de esto. Si vamos al navegador podemos observar que nuestro componente `Button` se esta renderizando correctamente:

![componente button](https://i.ibb.co/2tsRD9G/button-componente.png)

Y, si inspeccionamos nuestro `html` no existe ningún elemento más que nuestro `h1` y nuestro `button`:

![inspeccion](https://i.ibb.co/QF7mLzT/inspeccion.png)


## Comunicación entre componentes<a name="comunicacion">

Otra característica de los componentes en React es que pueden comunicarse entre ellos como decía la definición de [este bloque](#que-son-los-componentes), entonces vamos ahí, todos los componentes al final de cuentas son funciones, por eso se llaman componentes funcionales, entonces por defecto todos pueden recibir un parámetro llamado `props`, el cual contiene todos los "_mensajes_" de los componentes _padre_, vamos a jugar con esto un poco, que tal si yo quisiera usar mi componente `Button` en muchos otros lugares, pero el texto del botón no siempre será el mismo, entonces podemos hacer que el texto sea una propiedad dinámica de la siguiente manera:

```react
const Button = props => {
    return (
        <button>{props.text}</button>
    )
}
```

Bien, nuestro componente esta listo, pero ¿cómo le pasamos esa propiedad?, lo hacemos de la siguiente manera en nuestro componente `Element`:

```react
const Element = () => {
    return (
        <React.Fragment>
            <h1>{greeting}</h1>
            <Button text="click me"/>
        </React.Fragment>
    )
}
```

Como puedes observar lo pasamos como si se tratara de un atributo `html`, muy sencillamente lo hemos logrado, si revisas tu navegador el texto sigue siendo _click_ _me_.

## Comunicación de hijos a padres, eventos y... ¡Hooks!<a name="hijos-padres-hooks">

En el bloque anterior, aprendimos a enviar "_mensajes_" a los componentes hijos desde el padre, por medio de `props`, pero también hay la probabilidad de que tu necesites que en el padre algo se actualice, desde el hijo y esto lo realizamos por medio de funciones, de una manera muy sencilla, antes de terminar este articulo vamos a escribir un ejemplo clásico y muy básico de un contador, utilizaremos un `hook` de React llamado `useState`, los `hooks` son parte de una nueva `API`, que nos facilitan el trabajo con _functional_ _components_, anteriormente nuestros componentes funcionales no contaban con un estado, solo nuestros componentes de clase, ya que el `state`, la función `setState`, el ciclo de vida de los componentes, etc... se encontraba en la clase `React.Component`, de la cual heredaban todos nuestros componentes de clase, entonces un componente funcional al no poder heredar de ella, pues perdíamos todas estas características, pero esto ha cambiado para las últimas versiones de React con la llegada de los `hooks`, en este ejemplo solo utilizaremos uno como mencione antes, usaremos `useState` para proveer a nuestro _functional_ _component_ de un estado local. 

Antes de continuar rápidamente te explico que es el `state` así como los `props`contiene información que puede ser usada por el componente, la diferencia es que el `state` cuando "cambia", el componente es renderizado nuevamente en el _virtual_ _DOM_, el estado es _inmutable_, osea que no puede ser modificado directamente y para cambiarlo tenemos que hacer uso de una función, pero te lo explico en un momento.

vamos directo a los `hooks`, dentro de nuestro componente `Element` agregamos lo siguiente:

```react
const [count, setCount] = React.useState(0)
```

Como ves estamos haciendo uso de un `hook` llamado `useState`, el parámetro que le pasamos a `useState` es la inicialización de nuestro estado, en este caso hacemos `destructuring` de `useState`, para obtener como primer valor del `array` nuestro contador del `state` de nuestro componente y el segundo valor es una función que nos ayudará a cambiar el valor de `count`, continuamos, entonces ¿cómo modificamos el estado de nuestra aplicación?, como explicaba mas arriba vamos a ocupar que nuestro componente hijo (`Button`) modifique el estado del componente padre (`Element`) y la manera de hacerlo es por medio de una función de la siguiente forma:

```react
const Element = () => {

    const [count, setCount] = React.useState(0)

    const handleClick = () => console.log('click!!')

    return (
        <React.Fragment>
            <h1>{greeting}</h1>
            <Button handleClick={handleClick} text="click me"/>
        </React.Fragment>
    )
}

const Button = ({text, handleClick}) => {
    return (
        <button onClick={handleClick}>{text}</button>
    )
}
```

Vamos paso a paso, primero en nuestro componente `Element` agregué una función llamada `handleClick` que será la responsable de actualizar el `state` desde el hijo, después pasamos `handleClick` como un `prop` con el mismo nombre a nuestro componente `Button`, otro cambio que realizamos es, en nuestro componente `Button`, recibíamos `props` como parámetro, eso podemos cambiarlo haciendo `destructuring` de `props` y solo obteniendo lo que nos interesa, en este caso obtuvimos `text` y `handleClick`, ya dentro de nuestra etiqueta `button` que esta en nuestro componente `Button` ejecutamos `handleClick` a través de un evento `JavaScript`, en React el manejo de eventos es sencillo solo escribes el evento como si de un atributo se tratara, en este caso estamos usando `onClick`, si quieres conocer mas acerca de los eventos en React puedes mirar la [documentación oficial](https://es.reactjs.org/docs/handling-events.html), si hacemos click varias veces en nuestro botón y vamos a la consola de nuestro navegador, podemos ver que la función se esta ejecutando:

![habemus click](https://i.ibb.co/d0LJH3b/click.png)

Para terminar nuestro ejemplo, hagamos algo útil con nuestra función ya que imprimir algo en consola no es el objetivo, modificamos `handleClick` de a siguiente manera:

```react
const handleClick = e => {
    setCount(count + 1)
}
```

Si observamos, estamos haciendo uso de nuestra función `setCount` que obtenemos de `useState` para modificar el estado de nuestro componente, le pasamos como parámetro nuestra variable `count` y le sumamos `1` al valor que actualmente tiene ya que cada que hacemos click en el botón nuestro estado se actualiza, vamos a terminar nuestro ejemplo agregando en nuestro componente `Element` lo siguiente:

```react
const Element = () => {

    const [count, setCount] = React.useState(0)

    const handleClick = e => {
        setCount(count + 1)
    }

    return (
        <React.Fragment>
            <h1>{greeting} {count}</h1>
            <Button handleClick={handleClick} text="click me"/>
        </React.Fragment>
    )
}
``` 

Solo agregamos `count` a nuestro `h1` como puedes ver hemos terminado, si vamos a nuestro navegador y hacemos click en el botón podemos observar que `count` se esta actualizando sin problemas:

![successfully](https://i.ibb.co/D11JfyW/click-count.png)

## El fin :(<a name="fin">

Hemos terminado esta serie de dos artículos, en los cuales aprendimos bastantes cosas interesantes de React, con esto siéntete listo para ir por temas más avanzados, estos artículos están orientados a programadores que nunca han utilizado React y que desean un vistazo rápido, agradezco mucho el tiempo que tomaste para leerlos, en el futuro planeo escribir más artículos con temas más avanzados, aunque déjame decirte que hemos utilizado las características más importantes de React y no ha sido poco, aunque quizá fue un ejemplo pequeño, creo que fue bastante completo para comenzar de lleno con esta maravillosa librería de `JavaScript`. Antes terminar quiero dejarte el código completo de nuestro ejemplo, decidí no subirlo a [github](https://github.com) ya que solo fueron dos archivos, así que aquí te lo dejo:

```html
<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React - Basic Example</title>
</head>
<body>
    <div id="root"></div>

    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script src="app.js" type="text/babel"></script>
</body>
</html>
```

```react
/** app.js **/

const greeting = 'Hola React!'

const Element = () => {

    const [count, setCount] = React.useState(0)

    const handleClick = e => {
        setCount(count + 1)
    }

    return (
        <React.Fragment>
            <h1>{greeting} {count}</h1>
            <Button handleClick={handleClick} text="click me"/>
        </React.Fragment>
    )
}

const Button = ({text, handleClick}) => {
    return (
        <button onClick={handleClick}>{text}</button>
    )
}

ReactDOM.render(
    <Element />,
    document.getElementById('root')
)
```

Hasta la próxima, saludos!!