Utilizando "props.children" no React - Tipos e manipulação de dados



Neste tutorial vamos mostrar o conceito básico e como utilizar a props.children no React. O uso de props.children é muito empregado no React pois facilita a manipulação de dados entre componentes.

Observações:

a) O exemplos apresentados neste tutorial são aplicáveis quando se usa o React instalado no seu computador (Windows, Linux e Mac) ou quando se deseja adicionar o React em apenas algumas partes de um site. Para instalar o React no Windows, leia o tutorial: Como instalar e utilizar o React no Windows e para adicionar elementos do React em um site leia: Como adicionar elementos do React em um site.

b) Para um melhor entendimento deste artigo é recomendável a leitura dos tutoriais: Como criar componentes e usar "props" no React (instalado via NPM) e Como criar componentes e usar "props" no React adicionado em um site.

c) Utilizamos neste tutorial a extensão JSX. Portanto é recomendável a leitura do artigo: Usando JSX no React (instalado via NPM).

d) Por ser bastante apropriado para o React, utilizamos o editor Visual Studio Code neste tutorial. Para instalar o Visual Studio Code, acesse o link: https://code.visualstudio.com/

O que são componentes no React?

Conceitualmente os componentes são como funções/classes JavaScript que aceitam entradas (denominadas "props") e retornam elementos React que definem o que deve ser renderizado na tela.

É importante frisarmos que os componentes podem possuir diferentes formatos, desde um simples botão até uma página ou um sistema completo.

O que são props?

Props são propriedades/atributos de uma classe ou função JavaScript que podem ser passados aos seus componentes filhos. As props podem ter diferentes tipos de dados, como números, strings, funções, objetos e até mesmo outros componentes React. Portanto, a utilização das props é a forma principal de comunicação entre componentes.

As props são parte fundamental da criação de um componente. Por isso é extremamente importante aprender como usá-los. São ferramentas necessárias para desenvolver componentes únicos e personalizados para cada situação diferente que você desejar.

O que é props.children?

A props.children é uma prop especial que passa os elementos filho do componente diretamente para a sua respectiva saída renderizada. Isso permite que outros componentes também possam passar seus elementos filhos no próprio JSX.

Portanto, a props.children é uma propriedade especial do React que contém qualquer elemento filho definido no componente. Para entendermos melhor isso, veremos a seguir alguns exemplos práticos de como utilizar essa propriedade.

Obs.: É importante lembrar que embora o React seja uma biblioteca com base no JavaScript, children e props.children possuem estruturas de dados um pouco diferente:

a) A propriedade do JavaScript children retorna um array que contém todos os elementos filho (child) do elemento HTML no qual foi chamado. Veja o artigo Usando a propriedade children no JavaScript.

b) Já props.children retorna o tipo dados correspondente ao elemento filho do componente que ela contém, podendo ser uma string, um array, uma função ou um objeto. Por isso, props.children possui uma estrutura de dados denominada genérica ou opaca.

1. Entendendo a utilização da props.children

1.1. Como definimos anteriormente, podemos dizer que a props.children contém todo o conteúdo de um componente, ou seja, contém tudo o que está entre as tags JSX de abertura e fechamento do componente. Veja no exemplo abaixo:

<Welcome>Eu sou o elemento filho</Welcome>

1.1.1. Portando, a string "Eu sou o elemento filho" fica disponível na props.children do componente Welcome. É importante reforçar, que a props.children recebe todo o conteúdo que está entre as tags <Welcome></Welcome>.

1.1.2. Atenção: Quando um componente não tem elementos filhos, pode ser definido apenas com a tag <NomeComponente />. Exemplo: <Welcome />

1.2. Para renderizarmos o conteúdo disponível na props.children, vamos definir o componente Welcome a partir de uma função:

function Welcome(props) {
    return <p>{props.children}</p>
}

1.2.1. Observe que definimos a função do componente Welcome para receber a props.children dentro de um parágrafo (<p><p/>) e retorná-la como saída para a renderização.

1.2.2. Atenção: Na extensão JSX um componente deve retornar um único elemento raiz. Portanto, tudo o que se pretende retornar em uma função ou classe deve estar dentro de uma tag. No exemplo acima, o elemento está dentro da tag <p></p>. Quando utilizamos vários elementos, podemos definir o elemento raiz utilizando a expressão: return(<> conteúdo do componente </>)

1.2.2.1. O parêntesis utilizado na expressão acima é opcional. Podemos utilizá-lo apenas para melhorar a organização do código. As tags <></> podem ser substituídas por <div></div>.

1.3. Se desejar, você poderá definir o componente Welcome a partir de uma classe:

class Welcome extends React.Component {
    render() {
        return 

1.3.1. Observe que quando utilizamos classes para definir um componente, precisamos utilizar o atributo "this". O "this" é utilizado neste caso para indicar que a propriedade props.children se refere a classe proprietária, ou seja, a classe que define o próprio componente.

 1.4. Veja abaixo o código completo do App.js, caso você esteja utilizando o React instalado em um servidor:

1.4.1. No exemplo abaixo, definimos o componente Welcome a partir de uma função.

import React from 'react';

// define o componente Welcome a partir de uma função
function Welcome(props) {
  return <p>{props.children}</p>
}

function App() {
  return(<>
    <Welcome>Eu sou o elemento filho</Welcome>
  </>)
}

export default App;

1.4.2. Veja o resultado abaixo:

1.5. Caso você queira apenas adicionar elementos do React em em um site, veja o exemplo abaixo:

<!-- Adicione nosso componente React. -->
<script  type="text/babel">

    // Criando o componente Welcome() a partir de uma função
	function Welcome(props)  {
    		return <p>{props.children}</p> 
	} 

    function App() {
    	return (<>
        	<Welcome>Eu sou o elemento filho</Welcome>
        </>)
    }

    ReactDOM.render(
        <App />,
        document.getElementById("root")
    ) 
    
</script>

1.5.1. Para ver o código completo acesse o link: Squids Editor. Clique em Executar para testar o código.

2 . Passando elementos JSX, elementos JavaScript e Componentes com props.children

2.1. No exemplo anterior mostramos como passar uma string do componente para a função ou classe através da props.children. Mas no React, podemos usar a props.children para passar qualquer conteúdo para que seja renderizado, seja ele elementos JSX, elementos JavaScript e até mesmo outros componentes. Veja os exemplos a seguir:

2.2. Exemplo 1 - Passando elementos JSX

// define o componente Exemplo a partir de uma função
function Exemplo(props) {
  return (<>
    <p><b>Categoria: {props.categoria}</b></p>
    Elementos Filhos ({props.children.length}):
    {props.children}
  </>)     
}   

function App() {
return(<>
   <h1>Usando props.children</h1>
    <hr/>    
   <h2>Primeiro exemplo: </h2>
   <Exemplo categoria= {"frutas"}>
     <div>Laranja</div>
     <div>Maça</div>
     <div>Banana</div>
   </Exemplo>
   <h2>Segundo exemplo com filhos diferentes: </h2>
   <Exemplo categoria = {"letras"}>
     <div>A</div>
     <div>B</div>
     <div>C</div>
     <div>D</div>
   </Exemplo>
</>)
}

2.2.1. Para ver o código completo acesse o link: Squids Editor.

2.2.2. Veja o resultado abaixo:

 2.2.3. Observe que utilizamos neste exemplo a propriedade  length do JavaScript para obter o número de elementos JSX filhos que foram passados pela props.children. É importante termos em mente que neste caso a props.children se comportou como um array. Veremos mais a frente que nem sempre a props.children se comportará desta forma.

Obs.: No JavaScript a propriedade length é utilizada para obter o tamanho de uma string ou de um array.

2.2.3. Neste exemplo utilizamos também props para passar os nomes das categorias frutas e letras.

2.3. Exemplo 2 - Passando elementos JavaScript

// define o componente Exemplo a partir de uma função
function Exemplo(props) {
  let lista = []
  for (let i in props.children) {
     lista.push(<li>Item {(parseInt(i)+1)} = {props.children[i]}</li>)    			
  }
  return (<>
    <h2>{props.cat}</h2>
    <b>Elementos Filhos ({props.children.length}): </b>
    {lista}
  </>)     
} 

function App() {
return(<>
   <h1>Usando props.children</h1>
	<hr/>
    <Exemplo cat={"frutas"}>{["laranja","limão","uva"]}</Exemplo>
    <Exemplo cat={"Letras"}>{["A","B","C"]}</Exemplo>
    <Exemplo cat={"Animais"}>{["Cachorro","Gato","Coelho","Tartaruga"]}</Exemplo>
</>)
}

2.3.1. Para ver o código completo acesse o link: Squids Editor.

2.3.2. Veja o resultado abaixo:

 2.3.3. Observe que podemos também passar elementos JavaScript usando props.children. No exemplo acima, transferimos elementos do tipo array que foram manipulados na função de definição do componente, renderizando-os em uma lista com os seus respectivos itens.

2.3.4. No processo de manipulação foram utilizados os método push(), para adicionar um novo item na última posição do array lista, e o método parseInt() para converter o valor de i de string para número inteiro.

2.4. Exemplo 3 - Passando Componentes

2.4.1. Da mesma forma que passamos elementos JSX e JavaScript via props.children, podemos também passar outros componentes. Veja o exemplo abaixo:

// define o componente Foo a partir de uma função
const Foo = (props) => (
  <div>
    <p>Eu sou o componente {Foo.name}</p>
    <p>Minha props "numeros": {props.numeros}</p>
    <p>Eu tenho {props.children.length} elementos filhos (componentes).</p>
    <p>Eles são: {props.children}.</p>
    <p>{Array.isArray(props.children) ? 'Meus filhos são um array.' : ''}</p>
  </div>
)

const Baz = () => <span>o <b>{Baz.name}</b> e</span>;
const Bar = () => <span> o <b>{Bar.name}</b></span>; 

function App() {
	return(<>
   		<h1>Usando props.children</h1>
		<hr/>
		<Foo numeros = {123}>
  			<Baz />
  			<Bar />
		</Foo>
</>)
}

2.4.2. Para ver o código completo acesse o link: Squids Editor.

2.4.3. Veja o resultado abaixo:

2.4.4. Observe que nesse exemplo definimos os componentes utilizando expressões de função com função anônima combinada com arrow functions. Leia Criando funções através de uma Expressão de Função em JavaScript - Função Anônima e O que são Arrow Functions e como usar no JavaScript.

2.4.5. Para exibirmos o nome do componente basta utilizar a expressão {Nome do Componente.name}.

2.4.6. Para verificar se a props.children é um array, utilizamos o método JavaScript Array.isArray(). O método nativo Array.isArray() retorna true se um objeto é uma array, e false se não é.

3. Tipos de props.children (estrutura de dados opaca)

3.1. Agora que já vimos como passar elementos do componente para a função ou classe que o define, vamos identificar os principais tipos de dados que a props.children pode assumir neste processo.

3.1.1. Diferentemente da propriedade children, que sempre é um array no JavaScript, a props.children se comporta no React como uma estrutura de dados opaca, ou seja, ora pode ser uma string, um array, uma função, um objeto ou qualquer outro tipo de dados JavaScript. A props.children é, portanto, uma caixa genérica que assume o tipo do elemento filho do componente que ela contém.

3.2. Veja no exemplo abaixo onde a props.children pode passar tipos diferentes de dados:

// Criando o componente Welcome() a partir de uma função
function Welcome(props)  {
	return (<>
    	<p>Meu conteúdo é: <b>{props.children}</b></p>
        <p>Tenho {props.children.length} elementos</p>
        <p>Meu tipo é {typeof props.children}</p>
        <p>{Array.isArray(props.children) ? "(Sou um array)" : null}</p>
        <p>Meu segundo elemento é: {props.children[1]}</p>
        <hr/>
	</>)    
}
    
// Criando o componente Function() a partir de uma função
function Fuctions(props) {
	return (<>
    	<p>Meu conteúdo é: <b>{props.children()}</b></p>
        <p>Tenho {props.children.length} elementos</p>
        <p>Meu tipo é {typeof props.children}</p>                
        <hr/>
    </>)
}
    
function App() {
	return (<>
      <h1>Tipos de props.children</h1>
      <hr/>
      <Welcome>Eu sou o elemento filho</Welcome>
      <Welcome>
          <div>A</div>
          <div>B</div>
          <div>C</div>
      </Welcome>
      <Welcome>{["laranja","limão","uva"]}</Welcome>
      <Fuctions>{() => {return "hello world!"}}</Fuctions>                
    </>)
}

3.2.1. Para ver o código completo acesse o link: Squids Editor.

3.2.2. Veja o resultado abaixo:

Observações:

3.3. Veja no exemplo que obtivemos props.children com tipos diferentes de dados: string, object (array) e function, demonstrando que a props.children possui uma estrutura de dados opaca.

3.3.1. Foi utilizado o operador typeof para retornar uma string indicando o tipo de dados da props.children.

3.3.2. Quando o tipo de dados for um array o operador typeof retornará o valor object. Para confirmar, usamos o método nativo Array.isArray() que retorna true se um objeto for uma array, e false se não for.

3.4. Utilizamos a propriedade length para obter o tamanho da props.children (quantidade de caracteres ou quantidade de elementos de um array).

3.5. Portanto, a propriedade length irá retornar os valores conforme os seguintes casos do nosso exemplo:

3.5.1. No caso da props.children conter uma string, a propriedade length irá contar o número de caracteres dessa string. Isso ocorre apenas quando o componente tiver apenas filhos tipo string sem nenhuma tag JSX. Exemplo: <Welcome>Eu sou o elemento filho</Welcome>

3.5.2. No caso da props.children conter um array, a propriedade length irá contar o número de elementos desse array.

3.5.3. No caso da props.children conter uma função a propriedade length irá retornar zero.

3.6. Vimos anteriormente que podemos utilizar props.children como strings, arrays e funções, sendo:

3.6.1. No primeiro caso, como string, a props.children retorna a própria string.

3.6.2. No segundo caso, a props.children retorna um array com elementos JSX. Como resultado temos apenas a exibição do que foi compilado no transpilador JavaScript, de acordo com a extensão JSX. Leia: Usando JSX no React (instalado via NPM) e Como adicionar elementos do React em um site.

3.6.3. No terceiro caso, como array, a props.children retorna uma string com os elementos do array.

3.6.4. No último caso, como uma função, a props.children executa e retorna o resultado da função anônima.

3.7. É importante frisarmos que podemos executar uma função JavaScript que foi passada pela props.children apenas utilizando a expressão {props.children()}, ou seja, acrescentando parêntesis.

3.7.1. Também é possível passar parâmetros com o uso das funções.

4. Contando elementos da props.children

4.1. Como vimos no exemplo anterior, a propriedade length pode retornar valores diferentes de acordo com cada tipo de dados props.children. Assim, se props.children for uma string, irá contar o número de caracteres e se for um array, por exemplo, irá contar o número de elementos do array.

4.2. Para resolver isso, vamos precisar lançar mão de uma função utilitária disponível no React e fazer a contagem dos elementos props.children de forma correta e padrão.

4.2.1. O React dispõe de API's (interface de programação de aplicações) para várias utilizações. Dentre elas, temos a React.Children que provê funções utilitárias para lidar com a estrutura de dados opaca props.children.

4.3. Portanto, para contar o número de elementos da props.children podemos utilizar a função utilitária React.Children.count() que está disponível na API React.Children do React. Veja no exemplo a seguir onde mostramos a diferença entre o uso da propriedade length e o uso do utiliário React.Children.count():

// Criando o componente Welcome() a partir de uma função
function Welcome(props)  {
	return (<>
    	<p>Meu conteúdo é: <b>{props.children}</b></p>
        <p>Tenho {props.children.length} elemento(s) (propriedade length)</p>
        <p>Tenho {React.Children.count(props.children)} elemento(s) (utilitário)</p>
        <p>Meu tipo é {typeof props.children}</p>
        <p>{Array.isArray(props.children) ? "(Sou um array)" : null}</p>
        <hr/>
	</>)    
}
    
function App() {
	return (<>
      <h1>Contanto elementos props.children</h1>
      <hr/>
      <Welcome>Eu sou o elemento filho</Welcome>
      <Welcome>
          <div>A</div>
          <div>B</div>
          <div>C</div>
      </Welcome>
      <Welcome>{["laranja","limão","uva"]}</Welcome>                
    </>)
}

3.3.1. Para ver o código completo acesse o link: Squids Editor.

3.3.2. Veja o resultado abaixo:

Documentação Oficial

1. [https://pt-br.reactjs.org/docs/components-and-props.html] » Componentes e Props - React

2. [https://reactjs.org/docs/react-api.html#reactchildren] » Glossário - props.children - React

3. [https://pt-br.reactjs.org/docs/jsx-in-depth.html#string-literals-1] » Elementos Filhos em JSX - React

4. [https://pt-br.reactjs.org/docs/react-api.html#reactchildren] » React.Children - React

O anúncio abaixo ajuda manter o Portal Visual Dicas

Comentários

×

Infomações do site / SEO