¿Una mejor introducción a React?
Desafortunadamente, la mayoría de los tutoriales de React no tienen en cuenta las mejores prácticas y no siempre te enseñan la manera «correcta» de hacer React.
En este tutorial, repasaré los conceptos básicos de React y las prácticas incorrectas más comunes que podría encontrar.
Este tutorial va a ser largo, ¡así que asegúrate de conseguir algo de café!
¿Por qué elegir reaccionar?
Antes de comenzar, detengámonos un momento y veamos por qué React es la mejor opción.
Declarativo
En Reaccionar, usted describe qué debe renderizar (en lugar de decirle al navegador cómo hacerlo). Esto también significa que la cantidad de boilerplate se reduce considerablemente. En Reaccionar, simplemente inicie la codificación, no tiene ningún
componente que deba generar.
Hay algunas configuraciones involucradas, pero cuando se trata de los componentes, puedes expresarlos como funciones puras.
Sintaxis clara
JSX en React se siente como HTML, no hay una sintaxis especial para aprender:
Curva de aprendizaje
La curva de aprendizaje es muy importante al elegir un marco de interfaz de usuario.React tiene las menos abstracciones.
Si conoces JavaScript, probablemente puedas comenzar a escribir el código React en un solo día.
Sí, toma tiempo recoger las mejores prácticas, pero podrá comenzar muy rápido.
Funcional
En mi opinión, la mayor fortaleza de React proviene del hecho de que ni siquiera estás obligado a usar clases.
Las clases exageran la base de código sin proporcionar ningún beneficio.
En React, toda la interfaz de usuario se puede expresar como un conjunto de funciones puras, y el uso de funciones puras para hacer que la interfaz de usuario se sienta como una bocanada de aire fresco.
¡Vamos a empezar a programar!
Node.js
Node.js es un entorno de ejecución de JavaScript que nos permite compilar el código React.
En primer lugar, asegurémonos de tener instalado Node.js.
Si no, puede descargarlo desde aquí:
https://nodejs.org/en/download
crear-reaccionar-aplicación
Usaremos la aplicación crear-reaccionar de Facebook para apoyar nuestra aplicación.
Esta es la forma más popular de configurar su entorno y comenzar a codificar.
Viene con muchas herramientas necesarias integradas, lo que nos ayuda a eliminar muchas decisiones.
Para instalar la aplicación create-react-global:
npm i -g crear-reaccionar-aplicación
Luego, para andamiar su primera ejecución de proyecto:
crear-reaccionar-aplicación reaccionar-intro
¡Eso es todo!
Ahora, para iniciar la aplicación:
cd reaccion-intro
npm start
Esto abrirá un servidor de desarrollo y le permitirá abrir la nueva y brillante aplicación React yendo a
http: // localhost: 3000 / en su navegador.
Bajo el capó
Ahora, veamos cómo funcionan las cosas bajo el capó.
Usando el IDE de su elección (recomiendo
Visual Studio Code ) abra el proyecto recién creado.
index.html
Dentro del proyecto vaya al public/index.html
archivo.
Esto es lo que verás:
La parte que nos interesa es la <div id="root"></div>
.
Aquí es donde irá nuestra aplicación React.
La división raíz completa simplemente se reemplazará con el contenido de nuestra aplicación React.
Todo lo demás se mantendrá sin cambios.
index.js
Ahora vamos a abrir src/index.js
.
Este es el archivo que arranca la aplicación React completa.
Y, por cierto, todo nuestro código fuente React entrará en el src
directorio.
La línea que hace la magia es:
ReactDOM.render (<App />, document.getElementById (‘root’));
Esta línea es una forma de decirle a React que tome nuestro componente de la Aplicación (lo discutiremos un poco) y lo colocará dentro del root
div que se definió anteriormente dentro del index.html
archivo.
Centrémonos ahora en la <App />
parte.
Esto se parece mucho a HTML, ¿no es así?
Esto se llama JSX y es una sintaxis especial de JavaScript que React usa para hacer su magia.
Tenga en cuenta que comienza con un capital A
, es <App />
, no <app />
.
Esta es una convención utilizada por React, que le permite desambiguar entre las etiquetas HTML normales y los componentes React que hemos creado.
Si no inicia sus componentes con una letra mayúscula, React no podrá procesar sus componentes.
Siempre que usemos JSX, siempre debemos importar React agregando la siguiente línea dentro de nuestro .js
archivo:
importar reaccionar desde ‘reaccionar’;
App.js
Ahora estamos listos para echar un vistazo a nuestro primer componente.
Vamos a abrir src/app.js
:
Para crear un componente React, tenemos que crear una clase que herede React.Component
.
Eso es exactamente lo que hace la línea class App extends Component
.
Todos los componentes de React deben implementar un render
método; como puede haber adivinado, toda la representación se realiza dentro de este método.
El render
método tiene que devolver el marcado a ser renderizado.
Una pequeña nota al margen: el className
atributo es equivalente al class
atributo en HTML y se usa para asignar clases CSS para el estilo. class
es una palabra clave reservada en JavaScript y no se puede utilizar para un nombre de atributo.
Recapitulemos:
El componente se llama App (mayúscula A)
Se extiende la React.Component
clase
Tiene que implementar el render
método, que devuelve el marcado.
Mala práctica # 1 – Componentes de clase en todas partes
Hay dos formas de crear componentes en React: componentes de clase y componentes funcionales.
Como te habrás dado cuenta, el ejemplo anterior utiliza un componente de clase.
Y, desafortunadamente, la mayoría de los tutoriales de React para principiantes fomentan el uso de los Componentes de la Clase.
¿Qué pasa con los componentes de clase?
Son difíciles de probar, tienden a crecer mucho, son propensos a una separación pobre de preocupaciones, combinan la lógica con la presentación (lo que hace que la depuración y las pruebas sean más difíciles).
En general, te dispararás en el pie usando Componentes de Clase.
Especialmente si eres un principiante, te recomendaría que te mantengas alejado de ellos por completo.
Ok, los componentes de clase son malos, lo entiendo.
Pero cuales son las alternativas?
Componentes funcionales.
Si un componente no tiene nada más que el render
método, entonces es un gran candidato para refactorizar en un componente funcional. Veamos cómo se puede mejorar el componente de la aplicación creado por create-react-app:
¿Ves lo que hemos hecho aquí?
Hemos eliminado la clase y reemplazado el render
método con function App() {...}
.
Y si hacemos uso de las funciones de flecha de ES6, se verá aún mejor:
Hemos convertido el componente de clase en una función que devuelve el marcado que se va a representar.
Piénselo por un momento … Una función que devuelve el marcado, no hay un código innecesario, ¡solo un marcado puro!
¿No es hermoso?
El componente funcional se lee mucho mejor y tiene una mayor relación señal / ruido.
En este artículo, nos quedaremos con los Componentes de la Clase, ya que implican menos abstracciones y son más fáciles de demostrar los conceptos básicos de React.
Una vez que te sientas cómodo con los conceptos básicos de React, te recomiendo que leas mi artículo más detallado: Cómo
dominar los componentes funcionales de React con Recompose .
Introducción de accesorios
Props es un concepto central para React.
¿Qué accesorios son exactamente?
Piense por un segundo sobre los parámetros pasados a una función.
Los apoyos son solo eso: los parámetros se transmiten a un componente.
Aquí hemos creado un Greetings
componente y lo estamos utilizando para saludar a John Smith desde dentro del App
componente.
Esto resultará en el siguiente marcado:
<div>
<div> ¡Eh, tú!
John Smith! </div>
</div>
Los corchetes {props.name}
indican código JavaScript.
Se Greetings
pasó el componente firstName
y lastName
como parámetros, y simplemente los recuperamos accediendo al props
objeto.
Tenga en cuenta que el componente pasó un solo props
objeto, no dos valores para firstName
y lastName
.
Podemos simplificar aún más el código haciendo uso de la sintaxis de desestructuración de objetos de ES6:
Tenga en cuenta que (props)
fue reemplazado con ({ firstName, lastName })
.
Esto significa que solo estamos interesados en esas dos propiedades del props
objeto.
Y esto, a su vez, nos permite acceder a los
valores firstName
y lastName
directamente, sin tener que especificar explícitamente props.firstName
.
¿Qué pasa si hemos estado utilizando
componentes de clase en su lugar?
No sé sobre ti, pero para mí, ¡esto se ve mucho más hinchado!
Siempre hay que utilizar explícitamente this.props
.
Principio de Responsabilidad Única
«Cámara negra, reloj analógico redondo de color plateado, navaja negra Swiss Gear y linterna negra» de
Alexander Andrews en
Unsplash
El principio de responsabilidad única es el principio de programación más importante a seguir.
Establece que un módulo debe hacer una cosa, y debe hacerlo bien.
No seguir este principio solo puede convertir cualquier base de código en una pesadilla que es imposible de mantener.
¿Cómo podemos violar este principio?
La forma más común es colocar cosas no relacionadas en el mismo archivo.
Me referiré al principio de responsabilidad única varias veces en este tutorial.
Los principiantes usualmente colocan múltiples componentes en el mismo archivo.
Aquí hemos colocado los componentes de saludos y aplicaciones dentro del mismo archivo.
Esta es una mala práctica porque viola el principio de responsabilidad única.
Incluso los componentes más pequeños (como el componente Saludos anterior) deben colocarse en un archivo separado.
Coloquemos el componente Greetings en su propio archivo:
Y luego usarlo dentro del App
componente:
importar saludos desde «./Saludos»;
const App = () => (
…
);
Asegúrese de que el nombre del archivo coincida con el nombre del componente. App
el componente se debe colocar en App.js
, el Greetings
componente se debe colocar en Greetings.js
, y así sucesivamente.
Introduciendo estado
El estado es otro concepto central para reaccionar.
Aquí es donde desea mantener sus datos, cosas que pueden cambiar.
¿Almacenar el valor escrito en un elemento de formulario?
Usa estado
¿Mantener un registro de puntuación dentro de su juego?
Usa estado
Construyamos una forma simple que tome el primer nombre del usuario.
Tenga en cuenta que estoy utilizando a propósito un
componente de clase para demostrar el concepto.
Demuestro la refactorización de un componente de clase en un componente funcional en mi otro artículo
Mastering React Functional Components with Recompose .
Ok, el usuario puede escribir su correo electrónico en el formulario, lo que es genial!
Si has prestado atención, entonces has notado que no importa qué, el nombre de John se usará en el saludo.
¿Qué pasa si no todos los nombres de nuestros usuarios son John?
Nos colocaríamos en una situación muy incómoda.
¿Cómo podemos usar el valor escrito en la entrada?
En React no se supone que consultemos directamente al DOM.
Aquí es donde entran los controladores de entrada y el estado.
El estado es básicamente un objeto JavaScript simple que se almacena como una propiedad dentro del SimpleForm
componente de clase.
Aquí estamos agregando valor firstName
a la clase.
Nuestra firstName
entrada ahora tiene el onChange
controlador de eventos.
Se dispara cada vez que el usuario escribe una clave en la entrada.
Y la propiedad this.onFirstNameChange
en nuestra clase maneja los eventos onChange.
Echemos un vistazo a la onFirstNameChange
propiedad:
this.setState (…)
Así es como actualizamos el estado de nuestros componentes.
No debemos actualizar el estado del componente directamente, solo a través del setState
método.
Y para actualizar el valor del firstName
estado, simplemente pasamos un objeto con los valores actualizados al setState
método:
{firstName: event.target.value}
En este caso, event.target.value
es el valor que se escribió en la entrada del formulario.
En este caso, este es el nombre del usuario.
Una nota al margen: no hemos definido onFirstNameChange
como un método.
Esto es extremadamente importante para definirlo como una propiedad de función de flecha en la clase, y no como un método.
Si en su lugar lo hubiéramos definido como un método, entonces this
estaríamos vinculados a la entrada del formulario que llamó al método, no a la clase como habríamos esperado.
Este pequeño detalle a menudo hace tropezar a los principiantes.
Esta es otra razón para evitar clases en JavaScript.
Validación de formularios
»
IMac de plata encendida» por
Brennan Burling en
Unsplash
Ahora implementemos una validación de formulario simple usando expresiones regulares. Aseguremos que el primer nombre tenga al menos tres caracteres y contenga solo letras.
Agregaremos otro controlador de eventos para el onBlur
evento: se activará cuando el usuario deje la entrada.
También agregaremos otra propiedad al estado - firstNameError
.
Y luego mostraremos el error de validación justo debajo de la entrada (si hay errores presentes).
Estado
Primero, hemos agregado una firstNameError
propiedad al estado:
state = {
…
firstNameError: «»,
};
Función de validación
La validación en sí misma está ocurriendo en la validateName
función de flecha anterior.
Simplemente prueba el nombre de entrada contra la expresión regular:
validateName = nombre => {
const regex = / [A-Za-z] {3,} /;
volver! regex.test (nombre)
?
«El nombre debe contener al menos tres letras …»
: «»;
}
Si la validación falla, devolvemos el error de validación.
Si la validación tiene éxito, devolvemos una cadena vacía (lo que significa falta de error).
Estamos utilizando expresiones ternarias de JavaScript aquí para hacer que el código terser.
gestor de eventos onBlur
Echemos un vistazo al onBlur
controlador de eventos (se activa cada vez que el usuario deja la entrada):
onFirstNameBlur = () => {
const {firstName} = this.state;
const firstNameError = this.validateName (firstName);
devuelve this.setState ({firstNameError});
};
Aquí extraemos el firstName
estado utilizando la sintaxis de desestructuración de objetos ES6.
La primera línea es equivalente a:const firstName = this.state.firstName;
Luego ejecutamos la función de validación definida anteriormente con el firstName
, y luego establecemos la firstNameError
propiedad de estado con el error devuelto.
Si la validación falla, firstNameError
se establecerá.
Si tiene éxito, entonces se establecerá en una cadena vacía.render
método
Y ahora echemos un vistazo al render()
método:
render () {
const {firstNameError, firstName} = this.state;
…
}
Aquí nuevamente estamos utilizando la desestructuración de objetos ES6 para extraer valores del estado.
<input
…
onBlur = {this.onFirstNameBlur}
/>
Esta línea asigna la onFirstNameBlur
función como el controlador de eventos para el onBlur
evento.
{firstNameError && <div> {firstNameError} </div>}
Aquí estamos usando la función de evaluación de cortocircuito de JavaScript.
El div que contiene la firstNameError
voluntad se procesará solo si el valor en sí es verdadero.
Estilo
“Escaleras de caracol vacías en fotografía de ángulo bajo” por
Maxime Lebrun en
Unsplash
Si lo has estado siguiendo, es posible que hayas notado que nuestro formulario no es particularmente bonito … ¡Cambiemos eso agregando un poco de estilo en línea!
Los estilos en React se agregan simplemente pasando los estilos en el style
atributo.
Admito que no soy un diseñador, pero el arte de mi programador se ve mucho mejor ahora.
Aquí está el formulario con error de validación:
Mala práctica # 3 – estilo dentro del componente
Aquí hemos encontrado otra mala práctica, que desafortunadamente es demasiado común: colocar los estilos dentro del render
método de nuestros componentes.
¿Por qué es esto malo?
Esto viola el principio de responsabilidad única.
También desordena nuestro componente con estilos, lo que afecta significativamente la legibilidad.
¿Cuáles son los remedios?
Crea un style
objeto
especial
que contendrá todos nuestros estilos.
Se considera una buena práctica colocar el styles
archivo en un archivo separado:
Y luego usarlo dentro de nuestro SimpleForm
componente:
¡Esto se ve mucho más limpio!
Para llevar: coloca tus estilos en un archivo separado.
Añadiendo más campos de formulario
Hagamos el formulario un poco más interesante agregando un campo para ingresar el apellido:
No ha cambiado mucho aquí, simplemente hemos duplicado el código para la firstName
entrada y también
hemos
duplicado sus controladores de eventos.
¿Acabo de decir
duplicado ?
El código duplicado es un gran NO en el desarrollo de software y debe evitarse a toda costa.
Mala práctica # 4 – no dividir tus componentes.
Esta mala práctica vuelve una vez más a la violación del Principio de Responsabilidad Única.
Un buen código escrito debe leerse como un poema, y apuesto a que el método de renderizado de nuestro componente no se lee como un poema.
Vamos a cambiar eso.
Las entradas son casi idénticas, y ambas requieren algún tipo de validación.
Apliquemos un poco de refactor-fu a nuestro componente y creamos un TextField
componente
reutilizable
:
Simplemente extraje uno de los componentes del render
método, lo convertí en un componente funcional y le pasé cosas que cambian como accesorios:
Bien, esto se lee mucho mejor ahora!
Incluso podemos ir un paso más allá y crear TextField
componentes
dedicados
para el nombre y el apellido:
Aquí simplemente estamos devolviendo un componente prefabricado para mostrar el primer nombre.
Esta ({...rest})
es la nueva sintaxis de Restricción de objetos, lo que significa que todo lo que se pase como apoyo se guardará en el rest
objeto.
Luego, para pasar los accesorios a la TextField
sintaxis de la Distribución del objeto {...rest}
.
Esto toma el rest
objeto, distribuye sus propiedades y las pasa al TextField
componente.
En otras palabras: tomamos lo que fue pasado FirstNameField
y lo pasamos sin cambios a TextField
.
Y similarmente, el LastNameField
:
Así es como se ve nuestra forma ahora:
¡Mucho mejor!
¿Por qué los componentes de clase son tan malos de todos modos?
Los componentes de clase son difíciles de probar (a diferencia de los componentes funcionales).
Mala separación de preocupaciones: si estamos siendo perezosos, seguiremos poniendo todo en una sola clase, lo que puede crecer hasta convertirse en una monstruosidad de 1000 líneas con el tiempo (lo he visto suceder varias veces).
Los componentes de clase tienden a poner la lógica y la presentación juntas en una sola clase.
Lo que una vez más es malo para la separación de preocupaciones.
Los componentes de clase no son puros, y son difíciles de razonar.
Los componentes funcionales, por otro lado, son puros: siempre darán como resultado el mismo marcado para los mismos apoyos de entrada.
Los componentes funcionales hacen cumplir un buen diseño.
Te ves obligado a pensar en el diseño.
No es necesaria la this
palabra clave, que siempre ha sido una fuente importante de confusión.
Código fuente
El código fuente que lo acompaña se puede encontrar en
GitHub
¿Que sigue?
Este tutorial se ha vuelto un poco más largo de lo que esperaba.
Todavía hay mucho que cubrir, especialmente en relación con la organización de códigos, y algunas otras mejores prácticas.
Déjame saber si estás interesado en escuchar más en los comentarios.
Si realmente desea dominar React, le recomiendo que consulte mi otro artículo:
Mastering React Functional Components with Recompose .
¡Asegúrate de seguirme para más artículos sobre React y JavaScript!