[Ricky and Morty Characters Wiki] — Parte 3.1 — Personagens — Card

Wallyson Galvão
3 min readJan 21, 2023

--

Photo by Michael Marais on Unsplash

Caso tenha caído aqui por acidente, essa é a parte 1 de uma serie de posts para implementação de uma aplicação inspirada no post Rick and Morty Character Wiki do Joy Shaeb:

0 — Rick and Morty Character Wiki

Vamos criar nosso componente de Card para mostrar nossos personagens que estão retornando da API, para isso vamos começar implementando duas libs:

# instale as dependências no projeto
yarn add react-native-fast-image react-native-responsive-fontsize

# instale as dependências para ios
cd ios && pod install

Vamos aos arquivos:

src/components/Card/index.tsx:

import React from 'react';

import { Character } from '~/types/common';

type CardProps = {
character: Character;
};

import * as S from './styles';

export const Card = ({ character }: CardProps) => {

return (
<S.Container>
<S.Image source={{ uri: character.image }} />
<S.Badge status={character.status}>
<S.BadgeText>{character.status}</S.BadgeText>
</S.Badge>
<S.InfoContainer>
<S.Name>{character.name}</S.Name>
<S.LastLocation>Last Location</S.LastLocation>
<S.LocationName>{character.location.name}</S.LocationName>
</S.InfoContainer>
</S.Container>
);
};

src/components/Card/styles.ts:

import styled, { css, DefaultTheme } from 'styled-components/native';
import FastImage from 'react-native-fast-image';
import { RFValue } from 'react-native-responsive-fontsize';

import { Status } from '~/types/common';

export const Container = styled.TouchableOpacity`
${({ theme }) => css`
width: ${RFValue(40)}%;
border-width: ${RFValue(1)}px;
border-color: ${theme.colors.blue}
border-radius: ${RFValue(10)}px;
margin-bottom: ${RFValue(10)}px;
`}
`;

export const Image = styled(FastImage)`
width: 100%;
height: ${RFValue(150)}px;
border-top-right-radius: ${RFValue(10)}px;
border-top-left-radius: ${RFValue(10)}px;
align-self: center;
`;

const badgeModifiers = {
Alive: (theme: DefaultTheme) => css`
background-color: ${theme.colors.forestgreen};
`,
Dead: (theme: DefaultTheme) => css`
background-color: ${theme.colors.red};
`,
unknown: () => css``,
};

export const Badge = styled.View<{ status: Status }>`
${({ theme, status }) => css`
top: 5px;
right: 5px;
position: absolute;
padding: 5px;
border-radius: 5px;
background-color: gray;

${!!status && badgeModifiers[status](theme)}
`}
`;

export const InfoContainer = styled.View`
margin-left: 5px;
margin-bottom: 5px;
`;

export const Name = styled.Text`
font-weight: bold;
margin-top: 5px;
margin-bottom: 10px;
`;

export const LastLocation = styled.Text`
margin-vertical: 5px;
font-size: 12px;
`;

export const LocationName = styled.Text``;

export const BadgeText = styled.Text`
${({ theme }) => css`
color: ${theme.colors.white}
font-weight: bold;
`}
`;

Alterando nosso arquivo de personagens src/screens/Characters/index.tsx e adicionando nosso Card:

import React from 'react';
import { useInfiniteQuery } from '@tanstack/react-query';
import { SafeAreaView } from 'react-native-safe-area-context';

// Importação do nosso componente de Card
import { Card } from '~/components/Card';

import { Character } from '~/types/common';
import { getCharacters } from '~/services/requests/characters/queries';

import * as S from './styles';

const Characters = () => {
const { data } = useInfiniteQuery(['characters'], () => getCharacters());

const keyExtractor = (item: Character) => item.id.toString();

// Aqui adicionamos nosso componente de Card criado
const renderItem = ({ item }: { item: Character }) => (
<Card character={item} />
);

return (
<SafeAreaView>
<S.CharacterList
data={data?.pages.flatMap(page => page.results)}
keyExtractor={keyExtractor}
renderItem={renderItem}
/>
</SafeAreaView>
);
};

export default Characters;

Com isso temos:

Parte 3.2 — Listagem infinita

--

--