[Ricky and Morty Characters Wiki] — Parte 3.1 — Personagens — Card
3 min readJan 21, 2023
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:
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