Tutorial Reagir Parte 9: Propriedades do componente

Na parte de hoje da tradução do tutorial do React, falaremos sobre propriedades de componentes. Este é um dos conceitos mais importantes refletidos nesta biblioteca.

imagem

Parte 1: visão geral do curso, razões para a popularidade do React, ReactDOM e JSX
Parte 2: componentes funcionais
Parte 3: arquivos de componentes, estrutura do projeto
Parte 4: componentes pai e filho
Parte 5: início do trabalho em um aplicativo TODO, noções básicas de estilo
Parte 6: sobre alguns recursos do curso, JSX e JavaScript
Parte 7: estilos embutidos
Parte 8: trabalho contínuo na aplicação TODO, familiaridade com as propriedades dos componentes
Parte 9: propriedades do componente
Parte 10: Workshop sobre como trabalhar com propriedades e estilo de componentes
Parte 11: geração dinâmica de marcação e método de matrizes de mapas
Parte 12: workshop, terceira etapa do trabalho em uma aplicação TODO
Parte 13: componentes baseados em classe
Parte 14: workshop sobre componentes baseados em classe, status dos componentes
Parte 15: oficinas de saúde componentes
Parte 16: a quarta etapa do trabalho em um aplicativo TODO, manipulação de eventos
Parte 17: quinta etapa do trabalho em um aplicativo TODO, modificando o estado dos componentes
Parte 18: a sexta etapa do trabalho em um aplicativo TODO
Parte 19: métodos do ciclo de vida dos componentes
Parte 20: a primeira lição sobre renderização condicional
Parte 21: segunda lição e workshop sobre renderização condicional
Parte 22: sétima etapa do trabalho em um aplicativo TODO, baixando dados de fontes externas
Parte 23: primeira lição sobre como trabalhar com formulários
Parte 24: Segunda lição sobre formulários
Parte 25: Workshop sobre como trabalhar com formulários
Parte 26: arquitetura do aplicativo, padrão Container / Component
Parte 27: projeto do curso

Lição 19. Propriedades do componente no React


Original

Crie um novo projeto usando create-react-app e altere o código de vários arquivos padrão da pasta src .

Aqui está o código para o arquivo index.js :

 import React from "react" import ReactDOM from "react-dom" import "./index.css" import App from "./App" ReactDOM.render(<App />, document.getElementById("root")) 

Aqui estão os estilos descritos no arquivo 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; } 

Aqui está o código encontrado no arquivo 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 

Aqui está a aparência deste aplicativo em um navegador.


Página do aplicativo no navegador

Após analisar o código e a aparência do aplicativo, podemos concluir que seria bom usar componentes especiais para exibir cartões com informações sobre animais. Agora esses elementos são formados por meio do componente App . Considerando o que falamos nas aulas anteriores, você pode ir além - pense em um componente universal que pode ser personalizado passando atributos ou propriedades para ele.

Em nosso aplicativo, existem cartões com imagens de gatos, seus nomes e informações de contato de seus proprietários (ou talvez deles mesmos) - um telefone e um endereço de e-mail. Para criar um componente que mais tarde se tornará a base para todos esses cartões, você pode usar um dos fragmentos de marcação retornados pelo componente App . Por exemplo - isto:

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

O aplicativo retorna quatro desses blocos, cada um dos quais poderia ser usado para criar um componente independente, mas essa abordagem não nos convém. Portanto, criaremos um componente que se tornará a base de todos os cartões exibidos pelo aplicativo. Para fazer isso, crie um novo arquivo de componente na pasta src - ContactCard.js e insira um código que retorne o primeiro elemento <div> retornado pelo componente App , cujo código é fornecido acima. Aqui está o código para o 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 

É claro que, se você criar várias instâncias desse componente, todas elas conterão os mesmos dados, pois esses dados são codificados no código do componente. E gostaríamos de, ao criar instâncias diferentes desse componente, seria possível personalizar os dados exibidos por ele. O ponto é que o componente pode receber certas propriedades, que ele pode usar.

Trabalhamos com componentes funcionais, que são funções JS comuns, nas quais, graças à biblioteca React, construções especiais podem ser usadas. Como você sabe, as funções podem receber argumentos, embora possam ser usadas sem argumentos. Um ContactCard nosso componente ContactCard , na forma em que ele existe agora, pode ser uma função tão simples que, sem aceitar nada, simplesmente retorna a soma de dois números:

 function addNumbers() {   return 1 + 1 } 

Ele pode ser usado para descobrir a soma dos números 1 e 1, mas, por exemplo, para adicionar 1 e 2, usando funções que não aceitam nenhuma entrada, teríamos que escrever uma nova função. É bastante óbvio que essa abordagem levará a enormes inconvenientes se você precisar adicionar números diferentes; portanto, em tal situação, seria sensato criar uma função universal para adicionar números que usem dois números e retornem sua soma:

 function addNumbers(a, b) {   return a + b } 

O retorno de tal função dependerá de quais argumentos foram passados ​​para ela quando chamados. Ao criar componentes React, podemos seguir exatamente da mesma maneira.

Importamos o componente App.js ContactCard e retornamos quatro de suas instâncias, sem excluir o código que forma os cartões na página do aplicativo por enquanto:

 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 

Agora vamos trabalhar no código usado para instanciar o componente ContactCard . Ao criar elementos HTML regulares, podemos personalizar seus atributos que afetam seu comportamento e aparência. Os nomes desses atributos são codificados pelo padrão. No caso de componentes, você pode usar exatamente a mesma abordagem, com a única diferença de que nós mesmos inventamos os nomes dos atributos e decidimos por nós mesmos como eles serão usados ​​no código do componente.

Cada um dos cartões contém quatro informações, que, de cartão para cartão, podem ser alteradas. Esta é uma imagem de um gato e seu nome, além de um telefone e endereço de email. Deixe o nome do gato contido na propriedade name , o endereço da imagem na propriedade imgURL , o telefone na propriedade phone e o endereço de email na propriedade email .

Definimos essas propriedades para instâncias dos componentes do ContactCard e, ao transferir dados do código que já está no App , excluiremos os fragmentos correspondentes. Como resultado, o código do componente App ficará assim:

 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 

É verdade que a mera transferência de propriedades para um componente não é suficiente para serem usadas nele. A página, que será formada pelo componente App acima, conterá quatro cartões idênticos, cujos dados são definidos no código do componente ContactCard , que ainda não sabe o que fazer com as propriedades transferidas para ele.


Os dados do cartão são codificados no código; o componente não pode funcionar com as propriedades passadas para ele

Portanto, agora é hora de falar sobre como o componente ContactCard pode funcionar com as propriedades que são passadas para ele quando é instanciado.

Procedemos para resolver esse problema indicando, ao declarar a função ContactCard , que ele aceita o parâmetro props . Nesse caso, o código do componente terá a seguinte aparência:

 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 fato, esse parâmetro pode ser chamado como você quiser, mas no React é habitual chamá-lo de props , e as propriedades sobre as quais estamos falando aqui são frequentemente chamadas simplesmente de “adereços”.

O parâmetro props é um objeto. As propriedades deste objeto são as propriedades que são passadas para o componente quando ele é instanciado. Ou seja, por exemplo, em nosso objeto props haverá uma propriedade props.name contendo o nome do gato passado para o componente quando ele foi instanciado. Além disso, ele terá propriedades props.imgUrl , props.phone , props.email . Para verificar isso, adicione o comando console.log(props) no início da função 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 

Isso trará o objeto de props recebido pelo componente para o console.


Objeto de objetos do console

Aqui você pode ver a saída de quatro objetos do ContactCard.js . Existem muitos deles porque criamos quatro instâncias do componente ContactCard .

Tudo isso nos dá a oportunidade de usar no código do componente, em vez de valores codificados, o que foi passado ao criar sua instância, disponível na forma de props objeto props .

E se tentarmos usar a propriedade props.imgUrl esta:

 <img align="center" src=props.imgUrl/> 

À primeira vista, essa construção pode funcionar, mas lembre-se de que aqui precisamos usar uma entidade do JavaScript no código JSX. Falamos sobre como isso é feito em uma das classes anteriores. Ou seja, no nosso caso, a propriedade do objeto deve estar entre chaves:

 <img align="center" src={props.imgUrl}/> 

Processamos os outros elementos retornados pelo componente da mesma maneira, após o qual seu código assumirá o seguinte formato:

 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 

Observe que nos campos para exibir o telefone e o endereço de e-mail, deixamos os textos Phone: e Email: com espaços a seguir, pois esses textos são usados ​​em todos os componentes. Se você agora olhar para a página do aplicativo, notará que ela contém quatro cartões diferentes.


Página formada usando um componente universal

Nosso componente aceita apenas quatro propriedades. E se um componente precisar passar, por exemplo, 50 propriedades? Talvez passar cada propriedade como uma linha separada, como é feito no componente App , seja inconveniente. Nesses casos, você pode usar outra maneira de transferir propriedades para componentes. Consiste no fato de que, ao criar uma instância de um componente, não é transferida uma lista de propriedades, mas um objeto com propriedades. Veja como isso pode parecer no exemplo do primeiro 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 

Isso não quer dizer que essa abordagem reduziu significativamente a quantidade de código usada para descrever a instância do componente. O fato é que as propriedades passadas para o componente ainda são codificadas no código, embora apenas passemos um componente para o componente. As vantagens dessa abordagem podem ser sentidas em situações em que os dados para o componente são obtidos de algumas fontes externas. Por exemplo, de um arquivo JSON.

Durante a modificação do código do componente App usado para criar a primeira instância do componente ContactCard , a operação correta do aplicativo foi interrompida. É assim que a página dele ficará agora.


Mau funcionamento do aplicativo

Como isso pode ser corrigido? Para entender isso, será útil analisar o que está acontecendo usando o console.log(props) .


Análise do objeto props

Como você pode ver, o objeto props do primeiro componente é diferente do mesmo objeto do segundo e do próximo componente.

No componente ContactCard usamos o objeto props base na suposição de que ele possui o name imgUrl e outras propriedades. Aqui, o primeiro componente recebe apenas uma propriedade - contact . Isso leva ao fato de que o objeto props possui apenas uma propriedade - contact , que é o objeto, e o código do componente não fornece trabalho com essa estrutura.

Converter nosso componente no modelo de uso de apenas uma propriedade de um objeto de contact contendo outras propriedades é bastante simples. Para fazer isso, por exemplo, para acessar a propriedade name , basta usar uma construção do formulário props.contact.name no código do componente. Projetos semelhantes nos permitem trabalhar adequadamente com outras propriedades de que precisamos.

Vamos reciclar o código do componente, levando em consideração a transferência para ele de um único contact propriedade-objeto que contém outras propriedades:

 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 

O primeiro componente agora deve ser exibido normalmente, mas não veremos isso nesta fase do projeto, pois o sistema nos informará sobre muitos erros relacionados ao fato de que várias instâncias do componente ContactCard criadas no componente App não recebem a propriedade objeto de contact . Ao executar o código, essa propriedade será undefined . Como resultado, é feita uma tentativa de se referir a uma determinada propriedade de valor undefined , o que leva a um erro. Corrigiremos isso processando o código do componente App responsável pela formação dos componentes 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 

Agora a página do aplicativo terá a mesma aparência de antes.

Como sempre, é recomendável que você experimente os conceitos que aprendeu hoje para entendê-los melhor. Por exemplo, você pode trabalhar com o código, adicionar novas propriedades que são passadas para o componente e tentar usá-las no componente.

Sumário


Hoje, introduzimos o conceito de propriedades que podem ser passadas para os componentes React, a fim de controlar seu comportamento e aparência. Essas propriedades se assemelham aos atributos dos elementos HTML, mas, usando as propriedades dos componentes, o programador decide independentemente qual o significado que eles têm e o que exatamente fazer com eles no componente. Da próxima vez, você terá uma lição prática sobre como trabalhar com propriedades e estilo de componentes.

Caros leitores! Como você experimentou o código do exemplo de hoje para entender melhor as propriedades dos componentes do React?

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


All Articles