Tutorial React Parte 9: Propiedades del componente

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.

imagen

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 curso

Lección 19. Propiedades del componente en React


Original

Cree 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 navegador

Despué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 pasan

Así 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 consola

Aquí 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 universal

Nuestro 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ía

Como 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?

Source: https://habr.com/ru/post/es436032/


All Articles