Criando um custom hook pra paginação 📖
Tags: react, reactnative, webdev, tutorial
Published: 2023-03-24 12:50:49

Você recebeu uma lista muito grande e agora precisa implementar uma paginação. Você tem alguma ideia de como fazer isso? 🤔
Nesse artigo, vou mostrar como você pode implementar um custom hook pra te auxiliar na paginação!

## Criando o hook

Primeiro vamos pensar em alguns requisitos que a gente precisa em uma paginação:

1. Definir o número de items por página.
2. Navegar pra próxima página ou pra página anterior.
3. Pular pra uma página qualquer.
4. Retornar os dados da lista da página atual.

### Primeiro passo

Vamos criar a estrutura do nosso hook, passando o array de items que a gente precisa paginar e a quantidade de items por página que nós queremos.

```jsx
import { useState } from "React"

export const usePagination = (data, itemsPerPage) => {
  const [currentPage, setCurrentPage] = useState(1);
  const maxPage = Math.ceil(data.length / itemsPerPage);
}
```

### Segundo passo

Agora vamos implementar as funções de navegar entre as nossas páginas.

⚠️ *Não podemos ir para uma página menor do que 1 e nem exceder o número máximo de páginas*

```jsx
import { useState } from "React"

export const usePagination = (data, itemsPerPage) => {
  const [currentPage, setCurrentPage] = useState(1);
  const maxPage = Math.ceil(data.length / itemsPerPage);

  const goToNextPage = () => setCurrentPage((current) => Math.min(current + 1, maxPage));

  const goToPreviousPage = () => setCurrentPage((current) => Math.min(current - 1, 1));

  const jumpToPage = (page) => {
    const pageNumber = Math.max(1, page);
    setCurrentPage((currentPage) => Math.min(pageNumber, maxPage));
  }
}
```

- `goToNextPage` -> Passa pra próxima página, mas sem exceder o número máximo de páginas.
- `goToPreviousPage` -> Volta uma página, mas sem ultrapassar a primeira página.
- `jumpToPage` -> Vai direto pra uma página específica.

### Terceiro passo

Um dos passos mais importantes é retornar os dados baseados na página atual.
Pra isso utilizaremos o hook `useMemo` pra guardar os dados da página atual.

```jsx
const currentData = useMemo(() => {
  const begin = (currentPage - 1) * itemsPerPage;
  const end = begin + itemsPerPage;
  return data.slice(begin, end);
},[currentPage, data, itemsPerPage]);

```

### O que expor pro componente?

No fim, basta você expor o que quiser que o componente consuma.
Pra esse exemplo, vou externar todos os estados e funções do hook, então o código final deve ser algo parecido com isso:

```jsx
import { useState, useMemo } from "React";

export const usePagination = (data, itemsPerPage) => {
  const [currentPage, setCurrentPage] = useState(1);
  const maxPage = Math.ceil(data.length / itemsPerPage);

  const currentData = useMemo(() => {
    const begin = (currentPage - 1) * itemsPerPage;
    const end = begin + itemsPerPage;
    return data.slice(begin, end);
  }, [currentPage, data, itemsPerPage]);

  const goToNextPage = () =>
    setCurrentPage((current) => Math.min(current + 1, maxPage));

  const goToPreviousPage = () =>
    setCurrentPage((current) => Math.min(current - 1, 1));

  const jumpToPage = (page) => {
    const pageNumber = Math.max(1, page);
    setCurrentPage((_) => Math.min(pageNumber, maxPage));
  };

  return {
    currentPage,
    currentData,
    goToNextPage,
    goToPreviousPage,
    jumpToPage,
  };
}
```

### Agora é só utilizar 🎉
Com o nosso hook criado, basta você utilizar nos componentes que precisam de paginação, passando os dados e a quantidade de items por página.

Espero que tenha te ajudado!
Já salva na lista de leitura pra você implementar quando precisar.

👋🏼 Até a próxima.