[Rick and Morty Characters Wiki] — Parte 3.2 — Personagens — Lista infinita
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 implementar a listagem infinita e para isso vamos precisar alterar nossa função de requisição para a API, no método getCharacters vamos adicionar alguns parâmetros:
src/services/requests/characters/queries.ts
import api from '~/services/api';
import { CharactersResponse } from '~/types/response';
// Criamos uma tipagem para os argumentos/parâmetros do método getCharacters
type CharactersParams = {
pageParam: number;
};
// Deixamos o valor inicial do pageParam igual a 1
export async function getCharacters({ pageParam = 1 }: CharactersParams) {
// Na requisição à API adicionamos os parâmetros dentro de params
const { data } = await api.get<CharactersResponse>('/character', {
params: { page: pageParam },
});
return data;
}
Vamos a nossa lista no arquivos src/screens/Characters/index.tsx,
1 — Aqui vamos adicionar o método getNextPageParam dentro do hook useInfiniteQuery, ele é responsável por buscar o próxima página da nossa lista e retornar com os itens novos;
2 — No nosso componente de FlatList vamos adicionar onEndReachedThreshold e onEndReached que são responsáveis por disparar a ação e chamar o método onLoad para carregar mais itens para nossa lista.
import React from 'react';
import { ActivityIndicator } from 'react-native';
import { useInfiniteQuery } from '@tanstack/react-query';
import { SafeAreaView } from 'react-native-safe-area-context';
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, fetchNextPage, hasNextPage, isFetchingNextPage } =
useInfiniteQuery(
['characters'],
({ pageParam }) => getCharacters({ pageParam }),
{
getNextPageParam: lastPage => {
if (lastPage.info.next) {
const regex = new RegExp(/(page=)\w+/g);
const results = regex.exec(lastPage.info.next);
if (results?.length) {
return Number(results?.[0].split('page=')[1]);
}
}
},
},
);
const loadMore = () => {
if (hasNextPage) {
fetchNextPage();
}
};
const keyExtractor = (item: Character) => item.id.toString();
const renderItem = ({ item }: { item: Character }) => (
<Card character={item} />
);
const renderSpinner = () => <ActivityIndicator size={100} />;
return (
<SafeAreaView edges={['top']}>
<S.CharacterList
data={data?.pages.flatMap(page => page.results)}
keyExtractor={keyExtractor}
renderItem={renderItem}
onEndReachedThreshold={1}
onEndReached={loadMore}
ListFooterComponent={isFetchingNextPage ? renderSpinner : null}
/>
</SafeAreaView>
);
};
export default Characters;
Com isso temos:
Parte 3.3 — Buscar por nome