> For the complete documentation index, see [llms.txt](https://salvatore-academy.gitbook.io/dev-fullstack-web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://salvatore-academy.gitbook.io/dev-fullstack-web/academia/missoes-de-frontend/componentes-e-manipulacao-de-listas-em-react.md).

# Componentes Dinâmicos e Listas em React

{% hint style="info" %}
Nesta missão, vamos aprofundar no entendimento de como os componentes funcionam em React, explorando o uso de `props`, o método `map` para renderização de listas dinâmicas, e a implementação de renderização condicional. A missão é desenhada para reforçar a capacidade de manipular dados complexos e controlar o que é exibido na interface do usuário, utilizando conceitos fundamentais de JavaScript.
{% endhint %}

## Vídeo

{% embed url="<https://youtu.be/mAXcFzFicdk>" %}

**Link direto:** <https://youtu.be/mAXcFzFicdk>

## Tópicos

1. **Introdução aos Componentes e Props:**
   * Discussão sobre como os componentes permitem a reutilização de código e a modularização em React.
   * Explicação detalhada sobre como usar `props` para passar dados e eventos entre componentes.
2. **Introdução ao Flexbox para Layouts Responsivos:**
   * Introdução básica ao Flexbox, recomendando o jogo Flexbox Froggy como recurso interativo para aprendizagem.
   * Aplicação prática de Flexbox para arranjar múltiplos cards dentro de um contêiner, demonstrando o layout responsivo.
3. **JavaScript e React: Manipulação de Arrays e Objetos:**
   * Revisão sobre arrays e objetos em JavaScript, mostrando como essas estruturas são essenciais para gerenciar dados dentro dos componentes.
   * Demonstração de como transformar dados de array em componentes usando o método `map`.
4. **Renderização Condicional em Componentes:**
   * Introdução à renderização condicional em React, usando operadores como `&&` e ternário `?:` para criar interfaces que respondem a diferentes estados ou condições.
   * Exemplos práticos de como aplicar renderização condicional para melhorar a experiência do usuário.
5. **Prática com Listas Dinâmicas e Renderização Condicional:**
   * Criação de uma lista de componentes que são renderizados dinamicamente a partir de um array de dados.
   * Implementação de condições dentro da renderização para tratar listas vazias ou critérios específicos.

## Material de Apoio

### Repositório no GitHub

{% embed url="<https://github.com/SalvatoreAcademy/frontend-missao-aprendizado-iniciante-componentes-dinamicos-e-listas-em-react>" %}

### PDF para Download

{% file src="/files/5QnkVuS797UQkKeZ703b" %}

### Miro

{% embed url="<https://miro.com/app/board/uXjVNOBw03o=/?moveToWidget=3458764570069463851&cot=14>" %}

## Exercícios de Fixação

{% hint style="info" %}
Use esses exercícios para reforçar o que acabou de aprender. Se errar, leia a explicação para entender melhor o conceito.
{% endhint %}

<details>

<summary>Qual é a função principal dos <code>props</code> em um componente React?</summary>

A) Definir o estado inicial do componente.

B) Passar dados e eventos para o componente.

C) Estilizar o componente.

D) Criar novos elementos DOM.

</details>

<details>

<summary>Resposta correta</summary>

**Qual é a função principal dos `props` em um componente React?**

**Resposta Correta**: B

**Feedback**: Os `props` são usados para passar dados e eventos para os componentes filhos, permitindo que esses componentes sejam reutilizáveis e dinâmicos.

</details>

***

<details>

<summary>Complete o código para que o componente <code>Card</code> exiba o título e o conteúdo passados como <code>props</code>.</summary>

{% code lineNumbers="true" %}

```jsx
import React from 'react';

export default function Card(props) {
  return (
    <div className="card">
      <h2>{__________}</h2>
      <p>{__________}</p>
    </div>
  );
}
```

{% endcode %}

</details>

<details>

<summary>Resposta correta</summary>

**Complete o código para que o componente `Card` exiba o título e o conteúdo passados como `props`.**

**Resposta Correta**:

{% code lineNumbers="true" %}

```jsx
import React from 'react';

export default function Card(props) {
  return (
    <div className="card">
      <h2>{props.title}</h2>
      <p>{props.content}</p>
    </div>
  );
}
```

{% endcode %}

**Feedback**: O componente `Card` utiliza `props.title` e `props.content` para exibir o título e o conteúdo passados como propriedades.

</details>

***

<details>

<summary>Afirmativa: O Flexbox é utilizado para criar layouts bidimensionais em CSS.</summary>

A) Verdadeiro

B) Falso

</details>

<details>

<summary>Resposta correta</summary>

**Afirmativa: O Flexbox é utilizado para criar layouts bidimensionais em CSS.**

**Resposta Correta**: B

**Feedback**: Falso. O Flexbox é utilizado para criar layouts unidimensionais (linha ou coluna) em CSS. Para layouts bidimensionais, utiliza-se o CSS Grid.

</details>

***

<details>

<summary>Qual método usamos para adicionar um novo item ao final de um array em JavaScript?</summary>

A) `pop()`

B) `shift()`

C) `push()`

D) `unshift()`

</details>

<details>

<summary>Resposta correta</summary>

**Qual método usamos para adicionar um novo item ao final de um array em JavaScript?**

**Resposta Correta**: C

**Feedback**: O método `push()` é utilizado para adicionar um novo item ao final de um array em JavaScript.

</details>

***

<details>

<summary>Complete o código para criar uma lista de componentes `Card` a partir de um array de dados usando o método `map`.</summary>

{% code lineNumbers="true" %}

```javascript
import React from 'react';
import Card from './Card';

const items = [
  { title: 'Item 1', content: 'Conteúdo do Item 1' },
  { title: 'Item 2', content: 'Conteúdo do Item 2' },
  { title: 'Item 3', content: 'Conteúdo do Item 3' }
];

export default function App() {
  return (
    <div>
      {items.map(item => (
        <Card
          key={item.title}
          _______={item.title}
          _______={item.content}
        />
      ))}
    </div>
  );
}
```

{% endcode %}

</details>

<details>

<summary>Resposta correta</summary>

**Complete o código para criar uma lista de componentes `Card` a partir de um array de dados usando o método `map`.**

**Resposta Correta**:

{% code lineNumbers="true" %}

```jsx
import React from 'react';
import Card from './Card';

const items = [
  { title: 'Item 1', content: 'Conteúdo do Item 1' },
  { title: 'Item 2', content: 'Conteúdo do Item 2' },
  { title: 'Item 3', content: 'Conteúdo do Item 3' }
];

export default function App() {
  return (
    <div>
      {items.map(item => (
        <Card
          key={item.title}
          title={item.title}
          content={item.content}
        />
      ))}
    </div>
  );
}
```

{% endcode %}

**Feedback**: O método `map` é utilizado para transformar cada item do array `items` em um componente `Card`, passando os dados apropriados como `props`.

</details>

## Exercícios de Validação

{% hint style="info" %}
Esses exercícios testarão sua compreensão prática. Revise o feedback para melhorar suas habilidades.
{% endhint %}

### Desafio de Código

Adicione funcionalidade ao componente `Card` para que ele exiba uma mensagem "Este item não evolui" quando a propriedade `evoluiPara` for `null` ou `undefined`.

* Implemente a renderização condicional no componente `Card`.

<details>

<summary>Resposta esperada</summary>

{% code lineNumbers="true" %}

```jsx
import './Card.css'

export default function Card(props) {
  return (
    <div className="card">
      <h2>{props.item.nome}</h2>
      {props.item.evoluiPara 
        ? <p><b>Evolui para:</b> {props.item.evoluiPara}</p>
        : <p>Este item não evolui</p>}
      <img src={props.item.imagem} width="200" />
    </div>
  )
}
```

{% endcode %}

**Feedback**: A renderização condicional é usada para exibir uma mensagem específica quando `props.item.evoluiPara` não está definido, melhorando a clareza da interface para o usuário.

</details>

### Revisão de Código

{% hint style="danger" %}
**Analise o código a seguir, encontre e corrija o erro.**
{% endhint %}

{% code title="App.jsx" lineNumbers="true" %}

```jsx
import React from 'react';

export default function App() {
  const items = [
    { id: 1, nome: 'Java', imagem: 'https://example.com/java.png' },
    { id: 2, nome: 'Kotlin', imagem: 'https://example.com/kotlin.png' }
  ];

  return (
    <div>
      {items.map(item => (
        <Card key={item.id} nome={item.nome} image={item.imagem} />
      ))}
    </div>
  );
}
```

{% endcode %}

{% code title="Card.jsx" lineNumbers="true" %}

```jsx
function Card(props) {
  return (
    <div className="card">
      <h2>{props.item.nome}</h2>
      <img src={props.item.imagem} width="200" />
    </div>
  );
}
```

{% endcode %}

<details>

<summary>Resposta Correta</summary>

**Erros:**

* Exportação do componente `Card` e importação no componente `App` está faltando.
* O componente `Card` não está utilizando `props.item` para acessar as propriedades corretamente.

<pre class="language-jsx" data-title="App.jsx" data-line-numbers><code class="lang-jsx"><strong>import React from 'react';
</strong>import Card from './Card'; // Correção: Importar o componente Card

export default function App() {
  const items = [
    { id: 1, nome: 'Java', imagem: 'https://example.com/java.png' },
    { id: 2, nome: 'Kotlin', imagem: 'https://example.com/kotlin.png' }
  ];

  return (
    &#x3C;div>
      {items.map(item => (
        &#x3C;Card key={item.id} item={item} /> // Correção: Passar o item completo como prop
      ))}
    &#x3C;/div>
  );
}
</code></pre>

{% code title="Card.jsx" lineNumbers="true" %}

```jsx
export default function Card(props) {
  return (
    <div className="card">
      <h2>{props.item.nome}</h2> // Correção: Utilizar props.item para acessar as propriedades
      <img src={props.item.imagem} width="200" /> // Correção: Utilizar props.item para acessar as propriedades
    </div>
  );
}
```

{% endcode %}

**Feedback**: A propriedade `image` deve ser incluída no objeto `items` e passada como `props` para o componente `Card`.

</details>

### Projeto Prático

Crie uma aplicação React que renderize uma lista de produtos em promoção. A lista de produtos deve ser armazenada em um estado e passada para os componentes filhos como `props`. Além disso, implemente a funcionalidade para exibir o preço antigo e o novo preço com desconto. Se o produto não estiver em promoção, exiba uma mensagem "Produto não está em promoção".

#### Tarefas

1. **Criação do Projeto**:
   * Inicialize um novo projeto React.
   * Crie um componente `ProductCard` que receba `props` e exiba o nome, a imagem, o preço antigo e o novo preço com desconto de um produto.
2. **Implementação da Lista**:
   * Crie um componente `App` que armazene a lista de produtos no estado e use o método `map` para renderizar os cards.
3. **Renderização Condicional**:
   * Adicione renderização condicional para exibir a mensagem "Produto não está em promoção" se o produto não tiver desconto.

<details>

<summary>Código esperado</summary>

{% code title="App.jsx" lineNumbers="true" %}

```jsx
import React, { useState } from 'react';
import ProductCard from './ProductCard';
import './App.css';

export default function App() {
  const products = [
    { id: 1, nome: 'Produto A', imagem: 'https://example.com/produtoA.png', precoAntigo: 100, precoNovo: 80 },
    { id: 2, nome: 'Produto B', imagem: 'https://example.com/produtoB.png', precoAntigo: 200, precoNovo: 150 },
    { id: 3, nome: 'Produto C', imagem: 'https://example.com/produtoC.png', precoAntigo: 300, precoNovo: null }
  ]);

  return (
    <div className="app">
      {products.length > 0 ? (
        products.map(product => (
          <ProductCard key={product.id} product={product} />
        ))
      ) : (
        <p>Nenhum produto disponível</p>
      )}
    </div>
  );
}
```

{% endcode %}

{% code title="ProductCard.jsx" lineNumbers="true" %}

```jsx
import React from 'react';
import './ProductCard.css';

export default function ProductCard(props) {
  return (
    <div className="card">
      <h2>{props.product.nome}</h2>
      <img src={props.product.imagem} width="200" alt={props.product.nome} />
      {props.product.precoNovo 
        ? (
          <div>
            <p><b>Preço Antigo:</b> R${props.product.precoAntigo}</p>
            <p><b>Preço Novo:</b> R${props.product.precoNovo}</p>
          </div>
        ) 
        : <p>Produto não está em promoção</p>}
    </div>
  );
}
```

{% endcode %}

{% code title="ProductCard.css" lineNumbers="true" %}

```css
.card {
  border: 1px solid #ccc;
  border-radius: 8px;
  padding: 16px;
  text-align: center;
  width: 250px;
  margin: 16px;
}

.card img {
  margin-top: 16px;
}

.app {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: center;
}

```

{% endcode %}

**Feedback Detalhado**

* **Renderização de Listas**: Utilize o método `map` para renderizar uma lista de produtos dinamicamente.
* **Props**: Passe dados para componentes filhos usando `props` e acesse esses dados corretamente dentro dos componentes.
* **Renderização Condicional**: Use renderização condicional para exibir diferentes conteúdos com base no estado dos dados (por exemplo, se o produto está em promoção ou não).
* **Estilização com CSS**: Estilize os componentes para melhorar a apresentação visual, aplicando estilos básicos de CSS e utilizando Flexbox para o layout.

</details>
