PropType

Debido a que los componentes no tienen el control sobre las props que se le envía, y el tipo de datos, React proporciona un mecanismo que nos ayuda a validar este tipo de aspectos. Mediante PropTypes es posible definir las propiedades que debe de recibir un componente, el tipo de datos, estructura e incluso si son requeridas o no. Definir los PropTypes es tan simple cómo:

1<component>.propTypes = {  
2    <propName>: <propType>  
3    ...  
4}

Donde:

  • <Component>: nombre de la clase
  • <propName>: nombre de la propiedad a validar
  • <propType>: regla de validación

Adicional, tenemos que importar la clase PropTypes de la siguiente manera:

1import PropTypes from 'prop-types'

Ahora bien, regresaremos al ejemplo de la lista de productos, para definir el PropType para validar la estructura del producto:

1import React from 'react'
2import Image from 'next/image'
3import PropTypes from 'prop-types'
4
5class ItemList extends React.Component{
6
7    constructor(props){
8    super(props)
9    }
10
11    render(){
12    return(
13        <li>{this.props.product.name} - {this.props.product.price}</li>
14    )
15    }
16}
17
18ItemList.propTypes = {
19    product: PropTypes.shape({
20    name: PropTypes.string.isRequired,
21    price: PropTypes.number.isRequired
22    }).isRequired
23}
24
25export default ItemList

En este ejemplo, el componte ItemList espera una propiedad llamada product, la cual está definida con una estructura (shape) que debe de tener name de tipo String y es obligatoria (isRequired), también debe de tener un price de tipo numérico (number) y también es obligatoria (isRequired).

tip

isRequired es opcional

Si marcamos una propiedad como isRequired, React validará que el campo haya sido enviado durante la creación del componente, sin embargo, si no lo pones, le indicamos que es un parámetro esperado, pero no es obligatorio.

Por otra parte, el componente App debe de mandar la propiedad product con la estructura exacta que se está solicitando, respetando los nombre y los tipos de datos.

1import React from 'react'
2import Image from 'next/image'
3import {render} from 'react-dom'
4import ItemList from './ItemList'
5
6class App extends React.Component{
7
8    render(){
9    return (
10        <ItemList product={{ name: 100, price: 100 }} />
11    )
12    }
13}
14
15render(<App />, document.getElementById('root'));

Observemos que he enviado un 100 en el campo name, el cual es inválido, ya que se espera un string. Veamos qué pasa cuando ejecutamos la aplicación.

Probando los shape propsTypes
Probando los shape propsTypes

Observemos que si bien, la página se muestra correctamente, se lanza un error en el log que indica que el campo product.name es inválido.

tip

Validación con propTypes

Un error común es creer que con tener propTypes nos aseguramos de que el usuario siempre mande la información correcta, lo cual no es correcto, ya que los propTypes nos sirve como primera línea de defensa al indicarnos cuando hemos mandado un valor incorrecto, sin embargo, no puede impedir que manden valores en tipo o formato incorrecto.

Validaciones avanzadas

Ya hemos visto que es posible validar las propiedades de un componente, para ayudar a que las personas que utilicen nuestros componentes, envíen las propiedades correctas, es por ello que React ofrece un sistema muy completo de validaciones que nos permitirán definir estructuras robustas que validen a la perfección las propiedades.

Tipos de datos soportados:

La siguiente tabla muestra todos los tipos de datos que es posible validar con PropTypes.

Tipo de datosDescripción
PropTypes.string

Valida que la propiedad sea tipo String

Eje:

1{ name: PropTypes.string}

PropTypes.number

Valida que la propiedad sea numérica

Eje:

1{ checked: PropTypes.bool}

PropTypes.object

Valida que la propiedad sea un objeto con cualquier estructura

Eje:

1{ product: PropTypes.object}

PropTypes.objectOf

Valida que la propiedad sea un objeto con propiedades de un determinado tipo

Eje:

1{ tels: PropTypes.objectOf(PropType.string)}

PropTypes.shape

Valida que la propiedad sea un objeto de una estructura determinada

Eje:

1{ product: PropTypes.shape({
2                    name: PropTypes.string,
3    price: PropTypes.number
4})}

PropTypes.array

Valida que la propiedad sea un arreglo

Eje:

1{ tels: PropTypes.array}

PropTypes.arrayOf

Valida que la propiedad sea un arreglo de un terminado tipo de dato

Eje:

1{ tels: PropTypes.arrayOf(PropType.string)}

PropTypes.oneOfType

Valida que la propiedad sea de cualquier de los tipos de datos especificado (es decir, puede ser de uno o de otro tipo)

Eje:

1{ tel: PropTypes.oneOfType([
2  PropTypes.string,
3  PropTypes.number,
4  PropTypes.arrayOf(PropTypes.string)
5])}

PropTypes.func

Valida que la propiedad sea una función

Eje:

1{ save: PropTypes.func}

PropTypes.node

Valida que la propiedad sea cualquier valor que pueda ser renderizado en pantalla.

Eje:

1{ node: PropType.node}

PropTypes.element

Valida que la propiedad sea cualquier elemento de React

Eje:

1{ element: PropType.element}

PropTypes.instanceOf

Valida que la propiedad sea la instancia de una clase determinada

Eje:

1{ product: PropType.instanceOf(Product) }

PropTypes.oneOf

Valida que el valor de la propiedad este dentro de una lista de valores permitidos (Igual que una Enumeración)

Eje:

1{ status: PropType.oneOf([ACTIVO,INACTIVO])}

PropTypes.any

Le indica a React que la propiedad puede ser de cualquier tipo

Eje:

1{ object: PropType.any }

Acerca de este libro

Aplicaciones reactivas con React, NodeJS & MongoDB

Todo lo que acabas de ver en este artículo es solo una pequeña parte del libro Aplicaciones reactivas con React, NodeJS & MongoDB, El libro más completo en español para aprender a crear aplicaciones web completas con las tecnologías más potentes de la actualidad, desde el Frontend con React, hasta el Backend con un poderoso API REST con NodeJS y Express y persistiendo todo en MongoDB. te invito a que veas mi libro:

Ver libro
Todos los derechos reservados ©
Reactive programming
LinkedinYoutubeTwitterFacebook

© 2021, Copyright - Oscar Blancarte. All rights reserved.