React — Renderizando componentes condicionales (if, if/else, ternary, &&, switch, múltiples condiciones)
Temario
- Introducción
- Condicional
if
- Condicional
if-else
- Operador
ternary
- Operador lógico
&&
- Condicional
switch
- Múltiples condiciones
i. Introducción
Hay veces que en React dependiendo el estado debemos renderizar un elemento u otro. Por ejemplo, cuando vamos por datos a una API[ref] mostramos el elemento Loading
y cuando obtenemos los datos mostramos el elemento List
.
Con React poder renderizar un componente de acuerdo a una condición, es bastante sencillo, ya que podemos aprovechar los operadores de JavaScript (if, if-else, switch, etc
).
Nota: Te recomiendo que inicialices un proyecto con
create-react-app
o encodesandbox.io
[ref] para hacer los ejemplos…
ii. Condicional if
— Ejemplos
:: Ejemplo 1
Imagina que tenemos un Login, que dependiendo de una bandera va a permitir al usuario iniciar sesión o cerrar sesión.
Tenemos los siguientes componentes:
SignIn
— Componente que va a permitir al usuario iniciar sesión.Logout
— Componente que va a permitir al usuario cerrar sesión.Login
— Componente que dependiendo de la banderaisLoggedIn
va a mostrar el elementoSignIn
oLogout
Vamos a crear el componente SignIn
:
Cuando se le da click al botón vamos a mandar al evento handleEvent
el valor de true
, indicando que ha iniciado sesión.
Vamos a crear el componente Logout
:
Cuando se le da click al botón vamos a mandar al evento handleEvent
el valor de false
, indicando que ha cerrado sesión.
Ahora el componente Login
:
Lo que hacemos es validar, que si isLoggedIn=false
va a mostrar el componente SignIn
de lo contrario Logout
.
:: Ver ejemplo completo
:: Ejemplo 2
Para el siguiente ejemplo, vamos a utilizar la API swapi[ref]. La idea es obtener la lista de los personajes principales[ref] y mostrarlos dentro de un componente, pero en lo que el servicio responde vamos a mostrar un componente que indique que está cargando.
Tenemos los siguientes componentes:
Loading
— Componente que va a mostrar el texto “Loading…”List
— Componente que va a mostrar la lista de personajesApp
— Componente principal, que se va a encargar de consumir el servicio y de controlar que componente se va a mostrar.
Vamos a crear el componente Loading
:
Ahora crearemos el componente List
:
Recibe como propiedad items
, que se va a encargar de recorrerlos y mostrarlos.
Nos vamos al componente App
, para hacer la invocación al servicio, vamos a utilizar useEffect
, la API fetch
, y el useState
para controlar el estado de la lista.
Primero vamos a importar los componentes que hemos creado previamente:
Vamos a crear el estado List
, donde la inicializamos con un arreglo vacío, y hacemos la validación:
Si ejecutamos nuestra aplicación, veremos lo siguiente:
Podemos observar en la imagen, que solo se muestra el elemento Loading
. Entonces, vamos a invocar el servicio, para cargar la lista y así se muestre el elemento List
:
Si ejecutamos nuestra aplicación, veremos lo siguiente:
Podemos observar en la animación, que mientras el estado list
no tenga datos va a mostrar el elemento Loading
, y hasta que tiene datos es cuando se muestra el elemento List
.
:: Ver ejemplo completo
iii. Condicional if-else
— Ejemplos
:: Ejemplo 1
Vamos a añadirle un poco de complejidad al ejemplo anterior. La idea es agregarle un título, y en la parte de abajo hacer el funcionamiento actual, algo así:
En este caso, vamos a usar variables para almacenar elementos, esto es bastante útil, ya que React solo va a renderizar la parte que cambia y no todo el componente, adaptemos el ejemplo:
Estamos creando la variable component=null
donde le asignamos el elemento Loading
o List
(dependiendo de la condición), y al final es agregada al JSX
del componente.
:: Ver ejemplo completo
Podemos utilizar solo el if
:
Lo que hacemos es que la variable component
la inicializamos con el elemento Loading
, y hasta que el estado list
tenga datos lo cambiamos por el elemento List
.
:: Ejemplo 2
Imagina que tenemos un texto que dice “OFF” y cuando le damos click a un botón cambia a “ON”, si le damos de nuevo click al botón cambiará a “OFF” de nuevo…
También se puede ajustar a un if
.
:: Ver ejemplo completo
iv. Operador ternary
La alternativa para if-else
dentro del código JSX
es utilizar el operador condicional ternario :condición ? true : false
[ref].
— Ejemplo 1
El mismo ejemplo de if-else
, pero con el operador ternario:
Esta línea es la importante:
- El operador está entre llaves, y las expresiones pueden contener
JSX
, opcionalmente podemos agregar paréntesis()
para mejorar la legibilidad. - Si
list.length === false
entonces va renderizar el elementoLoading
caso contrarioList
. - Además la validación está dentro del
JSX
, lo cual evita generar variables extras al componente.
:: Ejemplo 2
Vamos a convertir el ejemplo de “OFF/ON” a ternario:
Mucho mejor ¿no?…
:: Ver ejemplo completo
v. Operador lógico &&
Es muy común que a veces vamos a renderizar un componente o null
, ya aprendimos que usar la sentencia if
es una buena forma de renderizar condicionalmente un componente, inclusive aprendimos a usar el operador ternario condicion?true:false
, pero hay otra forma de hacer que la sintaxis sea más corta.
— Cómo funciona el operador &&
Para entender cómo funciona el operador &&
, es necesario entender el concepto de coerción [ref]…Para hacer coerción implícita es usando los operador lógico &&
.
Importante: Los operadores lógicos hacen conversiones booleanas internamente, pero en realidad devuelven el valor de los operadores especificados, inclusive si no son booleanos.
Entonces, siguiendo la lógica de los ejemplos de arriba, sabemos que:
En React podemos aprovechar este comportamiento, si la condición es true
, la expresión después del operador &&
será la salida, caso contrario React ignora y omite la expresión.
— Ejemplos
:: Ejemplo 1
Imagina que tenemos el componente Welcome
, donde recibe la propiedad name
, la idea es de que si se manda debemos mostrar el componente, caso contrario null
.
Vamos a crear el componente Welcome
:
Ahora vamos a hacer la validación desde la App
…
Primero con if
:
El mismo ejemplo con ternary
:
Ahora con el operador &&
:
:: Ver ejemplo completo
Utilizar el operador &&
no siempre va a ser lo mejor, vamos a cambiar de lugar la validación, en vez de hacerla en la App
, la haremos dentro del componente Welcome
.
La App
queda de la siguiente manera:
Veamos el ejemplo con if
:
El mismo ejemplo con ternary
:
Ahora con el operador &&
:
Como podemos observar para los casos de ternary
y el operador &&
fue necesario agregar el componente Fragment
para lograr el retorno como null
:: Ver ejemplo completo
vi. Condicional switch
Habrá veces que dependiendo de la validación será el componente que va a renderizar.
— Ejemplos
:: Ejemplo 1
Imagina que tenemos un componente Notification
, donde va a recibir dos propiedades status
y text
; dependiendo de la propiedad status
, es el componente que va a mostrar Info
, Warning
, Error
o Success
.
Vamos a crear los componentes : Info
, Warning
, Error
, Success
Veamos primero el ejemplo con if
:
Ahora con switch
:
Finalmente en la App
:
:: Ver ejemplo completo
Cuando mandamos el status
, debemos de tener cuidado. Imagina el siguiente caso:
Resultado:
Podemos observar en el código:
info
— Es correcto, por lo que el mensaje si renderiza el componente.Success
— No es correcto, ya que laS
está en mayúscula, no renderiza el componente.WARNING
— No es correcto ya que se está mandando todo en mayúsculas, no renderiza el componente.
Para evitar este tipo de errores (que son bastante comunes), tenemos dos formas de hacerlo:
PropTypes
[ref]- Enumeraciones con objetos
— Con PropTypes
Si mandamos alguno mal, nos arroja una advertencia:
:: Ver ejemplo completo (Revisar consola para ver la advertencia)
Pero, qué pasaría si después todos los textos deben iniciar con mayúscula, y quizás más adelante todos los textos deben ser en mayúsculas… creo que se empieza a complicar la situación, ya que debemos de hacer el cambio en el componente Notification
y en TODOS los que estén usando el componente.
— Enumeraciones con objetos
Un objeto JavaScript con pares de valores clave para una asignación se denomina enumeración.
Entonces, el primer paso es crear la carpeta src/enums
y dentro crearemos el archivo enum.js
que va a quedar de la siguiente manera:
Lo importamos en los componentes donde se utiliza, en este caso App
y Notification
, y aprovechamos a hacer los cambios:
El objeto notificationTypes
es ahora es una implementación de una enumeración con cuatro valores posibles. Además hemos mejorado nuestro código de las siguientes maneras:
- Consistencia — Al momento de importar el objeto, ya no es necesario preguntarnos si va con mayúsculas o minúsculas, ya que la mayoría de los editores de texto nos ayudan a completar.
- El manejo de errores — Sí hay errores ortográficos, la aplicación fallará de una manera predecible.
- Cambio en la descripción —Mientras que la clave se conserve, no hay problema si la descripción cambia.
Se recomienda usar siempre y cuando se tengan un número definido de valores fijos para cualquier variable.
vii. Múltiples condiciones
Habrá veces que que será necesario utilizar la lógica que tiene la condicional switch
pero dentro del código JSX
, para lograrlo, vamos a usar enumeración con objetos, veamos el mismo ejemplo:
La clave de propiedad nos ayuda a recuperar el valor del objeto, creo que es más legible que usar switch
.
:: Ver ejemplo completo
Cada una de las opciones mencionadas arriba tienen sus ventajas y desventajas, la elección de cuál usar dependerá del caso de uso, yo te recomiendo aplicar:
- El tamaño de código que representará la condición.
- El número de condiciones o resultados posibles.
- Lo que sea más legible y fácil de mantener.
- Usar la condicional
if
— Para situaciones que no queremos renderizar el componentenull
o mostrar el componente completo. - Usar el operador ternario — En lugar de
if-else
, y se pueda usar dentro delJSX
. - Usar el operador
&&
— Cuando solo hay un resultado (componente onull
), cuando se necesite dentro delJSX
- Usar la condicional
switch
— Para el caso de 2 o más validaciones, y se requiera mantener separado el código. - Usar enumeración con objetos — Para el caso de 2 o más validaciones, pero se requiera dentro del
JSX
.
En la siguiente entrega vamos a ver React — Hooks [useRef, useCallback, useMemo, useReducer, customHook](Parte II)
La entrega pasada vimos React — Formas de diseñar componentes de React, desde estilos en línea hasta CSS in JS
Bibliografía y links que te puede interesar…