19

Protección de componentes con React PropTypes

49090Puntos

hace 3 años

Profesionalizarte en React implica enfrentarse a proyectos cada vez más retadores. Por el camino podrás notar que muchas veces tu código falla por recibir una prop de un tipo diferente al esperado (por ejemplo, un string en lugar de un number).

JavaScript es un lenguaje débilmente tipado. Aunque en React hay varias formas de tipar las props de tus componentes.

Hoy te enseñaré a hacerlo con PropTypes. Esta librería antes venía incluida de manera nativa en el framework, hasta la versión 15.5. Hoy debemos agregarla de forma independiente a nuestros proyectos con npm:

npm install--save prop-types

Este paquete es muy intuitivo y a continuación verás por qué.

import React from"react";
import PropTypes from"prop-types";

exportconst MyComponent = ({ name = "Platzinauta" }) =><h1>Hola {name}h1>;

MyComponent.propTypes = {
  name: PropTypes.string,
};

Solo debes declarar la propiedad propTypes en tu componente y tipar cada prop que esperes recibir.

Algo a recalcar es que, en este caso, la propiedad name es opcional. Para hacerla obligatorio solo debes agregar un isRequired al final del tipado.

MyComponent.propTypes = {
  name: PropTypes.string.isRequired,
};

Si estás en modo desarrollo, agregar PropTypes a tu proyecto te desplegará un error en consola cada vez que una prop tenga un tipo diferente al esperado o no pases una de estas al componente donde es requerida. Aunque en producción no afectará para nada.

Utilidades de las PropTypes

Más allá de verificar los tipos básicos de las props, esta librería también nos ayuda a documentar nuestro código. Si trabajas en equipo, puedes explicar lo que espera recibir tu componente de manera implícita.

Recuerda que puedes consultar la documentación oficial para conocer aún más sobre las PropTypes.

Si tienes una prop que puede llegar siendo de dos tipos diferentes, pero no quieres causar ningún error en tu componente, simplemente la declaras con oneOfType:

MyComponent.propTypes = {
  number: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
  // De no ser requerido, puedes eliminar  el "isRequired"
};

La librería también te facilita el comprobar si una prop pertenece a una clase en específico con instanceOf:

MyComponent.propTypes = {
  dog: PropTypes.instanceOf(Animal).isRequired,
};

En el caso de recibir un objeto, puedes definir el tipo de cada uno de sus atributos con shape y combinarlo con otras validaciones.

MyComponent.propTypes = {
  students: PropTypes.shape({
    ages: PropTypes.arrayOf(PropTypes.number).isRequired,
    // arrayOf verifica que el array solo contenga elementos de cierto tipo
    group: PropTypes.string.isRequired,
    total: PropTypes.number.isRequired,
  }),
};

Valida los tipos de un blog de Platzi

¡Es hora de practicar lo aprendido hasta aquí! Debes examinar un componente de tu home en Platzi y agregarle un par de features.

Por ahora nos enfocaremos en las props. Los estilos y estructura del componente te quedan como reto. 😄

Antes de escribirlo en código, analicemos nuestro componente y enlistemos sus props:

PropType
ImgString
TitleString
AuthorObject
timeObject
Likes_countNumber o String
Comments_countNumber o String
ResumeString
TagsArray

Estos dos últimos son agregados por nosotros.

Blog entry

Con toda la información recopilada hasta ahora puedes entrar de lleno al código de las props:

BlogEntry.propTypes = {
  img: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  resume: PropTypes.string,
  //Puedes poner o no un resumen, en caso de tenerlo, lo desplegarás debajo del título

  author: PropTypes.shape({
    // Como notaste, shape ayuda a definir los tipos dentro de un objeto
    name: PropTypes.string,
    rol: PropTypes.oneOf(["student", "teacher", "team"]),
    /* 
    El rol es muy específico, por lo cual se limitará a solo estos 3
    en caso de no pasarlo, lo asignas como "team" dentro del componente 
    */

    img: PropTypes.string,
    // Si no llega la img como prop puedes poner el logo de Platzi como default.
  }).isRequired,
  time: PropTypes.instanceOf(Date).isRequired,
  /*
   time tiene que ser una instancia de la clase Date, de esa forma puedes 
   acceder a varios de sus métodos.
   */

  likes_count: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
    .isRequired,
  comments_count: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
    .isRequired,
  /*
	No realizarás ningun tipo de operación con el prop que recibamos en likes_count o
	comments_count, por lo que puede ser tanto number como string.
  */

  tags: PropTypes.arrayOf(PropTypes.string).isRequired,
  /* Los tags son un array de strings requerido para poder iterar en cada uno de ellos */
};

En este Codepen está el componente completo

Como te mencioné, el pasar un prop de diferente tipo al esperado se te desplegara un mensaje como este en consola.

Blog error

Usa propTypes para crear cualquier otro componente

Refuerza todo lo aprendido en este blog aplicando propTypes en cualquier proyecto que ya tengas o toma como reto recrear un componente de Platzi desde 0 con este feature.

Recuerda que puedes aprender React.js sin importar tu nivel con todos los cursos de Platzi:

#NuncaParesDeAprender

Leonardo de los angeles
Leonardo de los angeles
LeoCode0

49090Puntos

hace 3 años

Todas sus entradas
Escribe tu comentario
+ 2
Ordenar por:
3
17378Puntos

Uff muy buen blog, recien he visto algunas cositas de react y se ve muy potente, gracias!

2
6838Puntos

super! muy bueno el articulo 😄

TypeScript tambien parece una gran alternativa… para aprender a incorporar TypeScript a un projecto de JavaScript, que path recomiendan? 🤔

1
6838Puntos
2 años
Solo hasta ahora lo veo 😅. Gracias por tu aporte @LeoCode0
1

Muy bueno, me gusta porque así documentamos nuestro componente, pero hay una alternativa y es usar typeScript que alguien me corrija si me equivoco gracias!

1
21156Puntos
3 años

Justo eso estaba pensando, usar TypeScript es una alternativa.

¿Para gustos los sabores?

4
49090Puntos
3 años

En efecto, TypeScript es una alternativa un poco más interesante, de la cual se vendrá contenido muy pronto en el blog😉