En la parte de hoy de la traducción del tutorial React, hablaremos sobre las propiedades de los componentes. Este es uno de los conceptos más importantes reflejados en esta biblioteca.

→
Parte 1: descripción general del curso, razones de la popularidad de React, ReactDOM y JSX→
Parte 2: componentes funcionales→
Parte 3: archivos de componentes, estructura del proyecto→
Parte 4: componentes principales y secundarios→
Parte 5: inicio del trabajo en una aplicación TODO, los fundamentos del estilo→
Parte 6: sobre algunas características del curso, JSX y JavaScript→
Parte 7: estilos en línea→
Parte 8: trabajo continuo en la aplicación TODO, familiaridad con las propiedades de los componentes→
Parte 9: propiedades del componente→
Parte 10: Taller sobre trabajo con propiedades de componentes y estilo→
Parte 11: generación de marcado dinámico y método de matrices de mapas→
Parte 12: taller, tercera etapa de trabajo en una aplicación TODO→
Parte 13: componentes basados en clases→
Parte 14: taller sobre componentes basados en la clase, estado de los componentes.→
Parte 15: talleres de componentes de salud→
Parte 16: la cuarta etapa de trabajo en una aplicación TODO, manejo de eventos→
Parte 17: quinta etapa de trabajo en una aplicación TODO, modificando el estado de los componentes→
Parte 18: la sexta etapa de trabajo en una aplicación TODO→
Parte 19: métodos del ciclo de vida de los componentes.Parte 20: la primera lección de representación condicional→
Parte 21: segunda lección y taller sobre representación condicional→
Parte 22: la séptima etapa de trabajo en una aplicación TODO, descargando datos de fuentes externas→
Parte 23: primera lección sobre trabajar con formularios→
Parte 24: Segunda lección de formularios→
Parte 25: Taller sobre trabajo con formularios→
Parte 26: arquitectura de la aplicación, patrón de contenedor / componente→
Parte 27: proyecto del cursoLección 19. Propiedades del componente en React
→
OriginalCree un nuevo proyecto usando
create-react-app
y cambie el código de varios archivos estándar de la carpeta
src
.
Aquí está el código para el archivo
index.js
:
import React from "react" import ReactDOM from "react-dom" import "./index.css" import App from "./App" ReactDOM.render(<App />, document.getElementById("root"))
Estos son los estilos que se describen en el archivo
index.css
:
body { margin: 0; } .contacts { display: flex; flex-wrap: wrap; } .contact-card { flex-basis: 250px; margin: 20px; } .contact-card > img { width: 100%; height: auto; } .contact-card > h3 { text-align: center; } .contact-card > p { font-size: 12px; }
Aquí está el código que se encuentra en el archivo
App.js
:
import React from "react" function App() { return ( <div className="contacts"> <div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/400/200"/> <h3><font color="#3AC1EF">▍Fluffykins</font></h3> <p>Phone: (212) 555-2345</p> <p>Email: fluff@me.com</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/400/300"/> <h3><font color="#3AC1EF">▍Destroyer</font></h3> <p>Phone: (212) 555-3456</p> <p>Email: ofworlds@yahoo.com</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/200/100"/> <h3><font color="#3AC1EF">▍Felix</font></h3> <p>Phone: (212) 555-4567</p> <p>Email: thecat@hotmail.com</p> </div> </div> ) } export default App
Así es como se verá esta aplicación en un navegador.
Página de aplicación en el navegadorDespués de analizar el código y la apariencia de la aplicación, podemos concluir que sería bueno usar componentes especiales para mostrar tarjetas con información sobre animales. Ahora estos elementos se forman mediante el componente de
App
. Teniendo en cuenta lo que hablamos en las clases anteriores, puede ir más allá: piense en un componente universal que se puede personalizar pasándole atributos o propiedades.
En nuestra aplicación hay tarjetas con imágenes de gatos, sus nombres e información de contacto de sus dueños (o tal vez ellos mismos): un teléfono y una dirección de correo electrónico. Para crear un componente que luego se convierta en la base de todas esas tarjetas, puede tomar uno de los fragmentos de marcado devueltos por el componente de la
App
. Por ejemplo, esto:
<div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div>
La aplicación devuelve cuatro de esos bloques, cada uno de los cuales podría usarse para crear un componente independiente, pero este enfoque no nos conviene. Por lo tanto, crearemos un componente que se convertirá en la base de todas las tarjetas que muestra la aplicación. Para hacer esto, cree un nuevo archivo de componente en la carpeta
src
-
ContactCard.js
y coloque un código que devuelva el primer elemento
<div>
devuelto por el componente de la
App
, cuyo código se proporciona arriba. Aquí está el código para el componente
ContactCard
:
import React from "react" function ContactCard() { return ( <div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div> ) } export default ContactCard
Está claro que si crea varias instancias de este componente, todas contendrán los mismos datos, ya que estos datos están codificados en el código del componente. Y nos gustaría, al crear diferentes instancias de este componente, sería posible personalizar los datos que muestra. El punto es que el componente podría pasar ciertas propiedades, que luego puede usar.
Trabajamos con componentes funcionales, que son funciones JS ordinarias, en las que, gracias a la biblioteca React, se pueden utilizar construcciones especiales. Como sabes, las funciones pueden tomar argumentos, aunque pueden usarse sin argumentos. Un
ContactCard
nuestro componente
ContactCard
, en la forma en que ahora existe, puede ser una función tan simple que, sin aceptar nada, simplemente devuelve la suma de dos números:
function addNumbers() { return 1 + 1 }
Se puede usar para encontrar la suma de los números 1 y 1, pero, por ejemplo, para sumar 1 y 2, usando funciones que no aceptan ninguna entrada, tendríamos que escribir una nueva función. Es bastante obvio que este enfoque generará grandes inconvenientes si necesita agregar números diferentes, por lo que en tal situación sería aconsejable crear una función universal para agregar números que tome dos números y devuelva su suma:
function addNumbers(a, b) { return a + b }
Lo que devuelva dicha función dependerá de los argumentos que se le pasen cuando se le llame. Al crear componentes React podemos ir exactamente de la misma manera.
Importamos el componente
App.js
ContactCard
y devolvemos cuatro de sus instancias, sin eliminar el código que forma las tarjetas en la página de la aplicación por ahora:
import React from "react" import ContactCard from "./ContactCard" function App() { return ( <div className="contacts"> <ContactCard /> <ContactCard /> <ContactCard /> <ContactCard /> <div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/400/200"/> <h3><font color="#3AC1EF">▍Fluffykins</font></h3> <p>Phone: (212) 555-2345</p> <p>Email: fluff@me.com</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/400/300"/> <h3><font color="#3AC1EF">▍Destroyer</font></h3> <p>Phone: (212) 555-3456</p> <p>Email: ofworlds@yahoo.com</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/200/100"/> <h3><font color="#3AC1EF">▍Felix</font></h3> <p>Phone: (212) 555-4567</p> <p>Email: thecat@hotmail.com</p> </div> </div> ) } export default App
Ahora trabajemos en el código utilizado para instanciar el componente
ContactCard
. Al crear elementos HTML regulares, podemos personalizar sus atributos que afectan su comportamiento y apariencia. Los nombres de estos atributos están codificados por el estándar. En el caso de los componentes, puede utilizar exactamente el mismo enfoque, con la única diferencia de que nosotros mismos obtenemos los nombres de los atributos y decidimos por nosotros mismos cómo se utilizarán en el código del componente.
Cada una de las tarjetas contiene cuatro piezas de información que, de una tarjeta a otra, pueden cambiar. Esta es una imagen de un gato y su nombre, así como un teléfono y una dirección de correo electrónico. Deje que el nombre del gato esté contenido en la propiedad del
name
, la dirección de la imagen en la propiedad
imgURL
, el teléfono en la propiedad del
phone
y la dirección de correo electrónico en la propiedad del
email
.
Establecemos estas propiedades en las instancias de los componentes de
ContactCard
y, a medida que transferimos datos del código que ya está en la
App
, eliminaremos sus fragmentos correspondientes. Como resultado, el código del componente de la
App
se verá así:
import React from "react" import ContactCard from "./ContactCard" function App() { return ( <div className="contacts"> <ContactCard name="Mr. Whiskerson" imgUrl="http://placekitten.com/300/200" phone="(212) 555-1234" email="mr.whiskaz@catnap.meow" /> <ContactCard name="Fluffykins" imgUrl="http://placekitten.com/400/200" phone="(212) 555-2345" email="fluff@me.com" /> <ContactCard name="Destroyer" imgUrl="http://placekitten.com/400/300" phone="(212) 555-3456" email="ofworlds@yahoo.com" /> <ContactCard name="Felix" imgUrl="http://placekitten.com/200/100" phone="(212) 555-4567" email="thecat@hotmail.com" /> </div> ) } export default App
Es cierto que la mera transferencia de propiedades a un componente no es suficiente para que se utilicen en él. La página, que estará formada por el componente de la
App
anterior, contendrá cuatro tarjetas idénticas, cuyos datos se establecen en el código del componente
ContactCard
, que aún no sabe qué hacer con las propiedades que se le transfieren.
Los datos de la tarjeta están codificados en el código; el componente no puede funcionar con las propiedades que se le pasanAsí que ahora es el momento de hablar sobre cómo el componente
ContactCard
puede funcionar con las propiedades que se le pasan cuando se instancia.
Procedemos a resolver este problema indicando, al declarar la función
ContactCard
, que acepta el parámetro
props
. En este caso, el código del componente se verá así:
import React from "react" function ContactCard(props) { return ( <div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div> ) } export default ContactCard
De hecho, este parámetro puede llamarse como desee, pero en React es habitual llamarlo
props
, y las propiedades de las que estamos hablando aquí a menudo se denominan simplemente "props".
El parámetro
props
es un objeto. Las propiedades de este objeto son las propiedades que se pasan al componente cuando se instancia. Es decir, por ejemplo, en nuestro objeto
props
habrá una propiedad
props.name
contiene el nombre del gato pasado al componente cuando se instancia. Además, tendrá propiedades
props.imgUrl
,
props.phone
,
props.email
. Para verificar esto, agregue el comando
console.log(props)
al comienzo de la función
ContactCard
.
import React from "react" function ContactCard(props) { console.log(props) return ( <div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div> ) } export default ContactCard
Esto traerá el objeto de
props
recibido por el componente a la consola.
Objetos de accesorios de consolaAquí puede ver la salida de cuatro objetos de
ContactCard.js
. Hay tantos porque creamos cuatro instancias del componente
ContactCard
.
Todo esto nos da la oportunidad de usar en el código del componente, en lugar de valores codificados, lo que se le pasó al crear su instancia, disponible en forma de
props
de
props
de
props
.
¿Qué pasa si intentamos usar la propiedad
props.imgUrl
esta manera?
<img align="center" src=props.imgUrl/>
A primera vista, tal construcción podría funcionar, pero recuerde que aquí necesitamos usar una entidad de JavaScript en código JSX. Hablamos sobre cómo se hace esto en una de las clases anteriores. Es decir, en nuestro caso, la propiedad del objeto debe estar entre llaves:
<img align="center" src={props.imgUrl}/>
Procesamos los otros elementos devueltos por el componente de la misma manera, después de lo cual su código tomará la siguiente forma:
import React from "react" function ContactCard(props) { return ( <div className="contact-card"> <img align="center" src={props.imgUrl}/> <h3><font color="#3AC1EF">▍{props.name}</font></h3> <p>Phone: {props.phone}</p> <p>Email: {props.email}</p> </div> ) } export default ContactCard
Tenga en cuenta que en los campos para mostrar el teléfono y la dirección de correo electrónico dejamos los textos
Phone:
y
Email:
con espacios a continuación, ya que estos textos se utilizan en todos los componentes. Si ahora mira la página de la aplicación, notará que contiene cuatro tarjetas diferentes.
Página formada usando un componente universalNuestro componente acepta solo cuatro propiedades. ¿Qué sucede si un componente necesita pasar, por ejemplo, 50 propiedades? Quizás pasar cada una de estas propiedades como una línea separada, como se hace en el componente de la
App
, será inconveniente. En tales casos, puede usar otra forma de transferir propiedades a los componentes. Consiste en el hecho de que al crear una instancia de un componente, no se transfiere una lista de propiedades, sino un objeto con propiedades. Así es como podría verse en el ejemplo del primer componente:
import React from "react" import ContactCard from "./ContactCard" function App() { return ( <div className="contacts"> <ContactCard contact={{ name: "Mr. Whiskerson", imgUrl: "http://placekitten.com/300/200", phone: "(212) 555-1234", email: "mr.whiskaz@catnap.meow" }} /> <ContactCard name="Fluffykins" imgUrl="http://placekitten.com/400/200" phone="(212) 555-2345" email="fluff@me.com" /> <ContactCard name="Destroyer" imgUrl="http://placekitten.com/400/300" phone="(212) 555-3456" email="ofworlds@yahoo.com" /> <ContactCard name="Felix" imgUrl="http://placekitten.com/200/100" phone="(212) 555-4567" email="thecat@hotmail.com" /> </div> ) } export default App
Esto no quiere decir que este enfoque reduzca significativamente la cantidad de código utilizado para describir la instancia del componente. El hecho es que las propiedades pasadas al componente todavía están codificadas en el código, aunque solo pasamos un componente al componente. Las ventajas de este enfoque se pueden sentir en situaciones donde los datos para el componente se obtienen de algunas fuentes externas. Por ejemplo, de un archivo JSON.
Durante la modificación del código del componente de la
App
utilizado para crear la primera instancia del componente
ContactCard
, se interrumpió el funcionamiento correcto de la aplicación. Así es como se verá su página ahora.
Mal funcionamiento de la aplicación¿Cómo se puede arreglar esto? Para entender esto, será útil analizar lo que está sucediendo usando el
console.log(props)
.
Análisis del objeto de utileríaComo puede ver, el objeto de
props
del primer componente es diferente del mismo objeto del segundo y del siguiente componente.
En el componente
ContactCard
usamos el objeto
props
basado en el supuesto de que tiene el
name
,
imgUrl
y otras propiedades. Aquí, el primer componente recibe solo una propiedad:
contact
. Esto lleva al hecho de que el objeto
props
tiene solo una propiedad:
contact
, que es el objeto, y el código del componente no proporciona trabajo con dicha estructura.
Convertir nuestro componente al modelo de usar solo una propiedad de un objeto de
contact
que contiene otras propiedades es bastante simple. Para esto, por ejemplo, para acceder a la propiedad de
name
, es suficiente usar una construcción del formulario
props.contact.name
en el código del componente. Diseños similares nos permiten trabajar correctamente con otras propiedades que necesitamos.
Reciclemos el código del componente, teniendo en cuenta la transferencia de un solo
contact
propiedad-objeto, que contiene otras propiedades:
import React from "react" function ContactCard(props) { console.log(props) return ( <div className="contact-card"> <img align="center" src={props.contact.imgUrl}/> <h3><font color="#3AC1EF">▍{props.contact.name}</font></h3> <p>Phone: {props.contact.phone}</p> <p>Email: {props.contact.email}</p> </div> ) } export default ContactCard
El primer componente ahora debería mostrarse normalmente, pero no lo veremos en esta etapa del proyecto, ya que el sistema nos informará de muchos errores relacionados con el hecho de que varias instancias del componente
ContactCard
creado en el componente de la
App
no reciben la propiedad. objeto de
contact
Al ejecutar el código, esta propiedad será
undefined
. Como resultado, se intenta hacer referencia a una determinada propiedad del valor
undefined
, lo que conduce a un error. Lo arreglaremos procesando el código del componente de la
App
responsable de la formación de los componentes de
ContactCard
:
import React from "react" import ContactCard from "./ContactCard" function App() { return ( <div className="contacts"> <ContactCard contact={{ name: "Mr. Whiskerson", imgUrl: "http://placekitten.com/300/200", phone: "(212) 555-1234", email: "mr.whiskaz@catnap.meow" }} /> <ContactCard contact={{ name: "Fluffykins", imgUrl: "http://placekitten.com/400/200", phone: "(212) 555-2345", email: "fluff@me.com" }} /> <ContactCard contact={{ name: "Destroyer", imgUrl: "http://placekitten.com/400/300", phone: "(212) 555-3456", email: "ofworlds@yahoo.com" }} /> <ContactCard contact={{ name: "Felix", imgUrl: "http://placekitten.com/200/100", phone: "(212) 555-4567", email: "thecat@hotmail.com" }} /> </div> ) } export default App
Ahora la página de la aplicación se verá igual que antes.
Como de costumbre, se recomienda que experimente con los conceptos que ha aprendido hoy para comprenderlos mejor. Por ejemplo, puede trabajar con el código, agregar nuevas propiedades que se pasan al componente e intentar usarlas en el componente.
Resumen
Hoy presentamos el concepto de propiedades que se pueden pasar a los componentes React para controlar su comportamiento y apariencia. Estas propiedades se parecen a los atributos de los elementos HTML, pero, utilizando las propiedades de los componentes, el programador decide independientemente qué significado tienen y qué hacer exactamente con ellos en el componente. La próxima vez tendrá una lección práctica sobre cómo trabajar con propiedades de componentes y estilo.
Estimados lectores! ¿Cómo experimentó con el código del ejemplo de hoy para comprender mejor las propiedades de los componentes React?