Criando Pokedéx com React – Parte 3

Começando a parte 3 do nosso tutorial, criaremos os primeiros componentes Stateless. Configuraremos o PokeList e renderizaremos todas as PokeCells com seus sprites. Vamos começar!

PokeList:

Na pasta componentes, criaremos um arquivo chamado PokeList.js e, na pasta styles, criaremos um arquivo chamado PokeList.css.

Os componentes stateless têm uma configuração mais curta. Esses tipos de componentes são funções JavaScript que retornam jsx.

No seu arquivo PokeList.js, você irá:

  1. Importar o react;
  2. Importar o pokelist.css;
  3. Criar uma função chamada PokeList;
  4. Retornar uma seção vazia com a className “poke-list”;
  5. Exportar a função recém-criada.
import React from 'react';
import './styles/PokeList.css';

const PokeList = () => {
    return (
        <section className="poke-list">

        </section>
    )
}
  

Vá para o PokeList.css e adicione o seguinte css:

.poke-list {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
    align-items: center;
    width: 50%;
    height: 80%;
    padding: 10px;
    margin-right: 10px;
    background-color: #BFF9FF;
    box-shadow: inset 0 0 20px rgba (0, 0, 0, 0.5);
    overflow: scroll;
}

Usamos o display: flex para tirar proveito da funcionalidade de quebra automática. Definimos a largura para 50% para preencher a metade esquerda do componente do aplicativo e também incluímos rolagem de estouro porque nem todas as PokeCells serão exibidas de uma só vez.

Agora, precisamos voltar ao nosso App.js e importar o componente PokeList. Para renderizá-lo, colocaremos o componente PokeList como uma tag html dentro do elemento pai. Veja só:

PokeCell:

Construiremos um componente PokeCell que funcionará como um modelo para cada um dos 150 Pokémons que renderizaremos no PokeList. Crie um arquivo PokeCell.js na pasta componentes e, na pasta styles, um arquivo PokeCell.css.

No arquivo PokeCell.js:

  1. Importe o React;
  2. Importe o PokeCell.css;
  3. Crie uma nova função chamada PokeCell;
  4. Retorne um botão vazio com o className “poke-cell”;
  5. Exporte a função recém-criada:
import React from 'react';
import './styles/PokeCell.css';

const PokeCell = () => {
    return <button className='poke-cell'></button>
};

export default PokeCell;

Vá para o arquivo PokeCell.css e adicione o seguinte css:

.poke-cell {
    width: 120px;
    height: 120px;
    margin: 10px;
    background-color: #FFF;
    background-repeat: no-repeat;
    border: none;
    border-radius: 5px;
    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16);
}

Finalmente, importaremos o PokeCell dentro do nosso PokeList.js e renderizaremos algumas células na lista colocando-os dentro do elemento pai como um html.

Sprites e Renderização de Matriz:

Faça o download desses recursos:

Sprites

pokeClasses

A imagem sprites é uma coleção dos primeiros 151 sprites Pokemon. Exibiremos cada Sprite usando o componente PokeCell e algumas propriedades de plano de fundo do CSS (background-image, background-position).

As background-positions podem ser achadas no arquivo pokeClasses.js, que possuem um array de objetos contendo o id e posição de cada Pokemón para cada Sprite.

  1. Dentro do diretório src, insira o arquivo pokeClasses.js;
  2. Cria uma pasta chamada assets dentro deste diretório, e coloque a imagem de sprites dentro da pasta assets.

Dentro do arquivo PokeList.js, importe o pokeClasses:

import React from 'react';
import PokeCell from './PokeCell';
import { pokeClasses } from '../pokeClasses';
import './styles/PokeList.css';

const PokeList = () => {
    return (
        <section className="poke-list">
            <PokeList />
            <PokeList />
            <PokeList />
        </section>
    )
}

export default PokeList;

Precisamos renderizar a lista de todos os 151 PokeCells com os dados corretos neles. No nosso código, crie um array de PokeCells com as informações de cada elemento do array pokeClasses.

Para isso, utilizaremos o array prototype map ao nosso array pokeClasses e, para cada elemento do array, retornará uma tag PokeCell. Em seguida, armazene esse array em uma nova constante chamada cells.

const cells = pokeClasses.map(pokeClass => <PokeCell />)

Vamos usar props para passer o objeto pokeClass para cada PokeCell. Podemos nomear props da maneira que quisermos e passar qualquer tipo de variável (string, número, objeto, função) por eles. Para fazer isso, adicione um novo prop chamado pokeClass dentro da tag PokeCell. Em seguida, atribua a ele o argumento pokeClass do retorno de chamada do map. Sempre que incluirmos JavaScript regular em um jsx, precisamos envolve-lo com chaves:

const cells = pokeClasses.map(pokeClass => <PokeCell pokeClass = {pokeClass}/>)

Cada pokeClass contém um valor de ID, que podemos usar como nosso valor exclusivo da prop. O resultado será:

import React from 'react';
import PokeCell from './PokeCell';
import { pokeClasses } from '../pokeClasses';
import './styles/PokeList.css';

const PokeList = () => {
    const cells = pokeClasses.map(pokeClass => {
        return (
            <PokeCell 
                key = {pokeClass.id}
                pokeClass={pokeClass}
            />
        );
    });

    return (
        <section className="poke-list">

        </section>
    )
}

export default PokeList;

E agora que temos nosso vetor PokeCells, renderizaremos ele colocando a variável cells dentro do elemento pai, envolto em chaves:

import React from 'react';
import PokeCell from './PokeCell';
import { pokeClasses } from '../pokeClasses';
import './styles/PokeList.css';

const PokeList = () => {
    const cells = pokeClasses.map(pokeClass => {
        return (
            <PokeCell 
                key = {pokeClass.id}
                pokeClass={pokeClass}
            />
        );
    });

    return (
        <section className="poke-list">
            {cells}
        </section>
    )
}

export default PokeList;

E a saida será:

Renderizando Sprites:

Agora que passamos o objeto pokeClass para cada PokeCell, usaremos esses dados para determinar a posição de cada Sprite na imagem do Sprite e renderizá-lo no fundo de cada botão.

No seu arquivo PokeCell.js, passaremos props para o PokeCell, precisamos incluir um argumento de props na função PokeCell. Como sabemos que o objeto props contém o objeto pokeClass, podendo desconstruir o argumento props para acessar o objeto pokeClass.

const PokeCell = ({pokeClass}) => {
    const {id, backgroundPosition} = pokeClass;
    
    return <button className='poke-cell'></button>
};

Em seguida, importe a imagem dos sprites:

import sprites from '../assets/sprites.png';

Para adicionar o sprite como uma imagem de plano de fundo, usaremos o estilo embutido no elemento button. Crie um novo objeto de estilos com duas propriedades: backgroundImage e backgroundPosition. Usaremos a função css url:

const style = {backgroundImage: `url (${sprites})`, backgroundPosition};

E ficaria assim o código:

import React from 'react';
import sprites from '../assets/sprites.png';
import './styles/PokeCell.css';
const PokeCell = ({ pokeClass }) => {
  const { id, backgroundPosition } = pokeClass;
  const style = { backgroundImage: `url(${sprites})`, backgroundPosition};

  return <button style={style} className="poke-cell"></button>
};

export default PokeCell;

E assim será a sua saída:

E assim termina a parte 3 da nossa sequência de artigos! Comente abaixo!

Referências: https://blog.cloudboost.io/lets-build-a-pokedex-with-react-part-3-5d0114361424