An open API service indexing awesome lists of open source software.

https://github.com/jay-ubisse/tanstack-query-table

Este projeto demonstra como integrar as bibliotecas **TanStack Query** para buscar dados de uma API ou banco de dados e **TanStack Table** para exibir, filtrar e ordenar esses dados em uma tabela interativa.
https://github.com/jay-ubisse/tanstack-query-table

css reactjs tanstack-react-query tanstack-table vite

Last synced: 11 months ago
JSON representation

Este projeto demonstra como integrar as bibliotecas **TanStack Query** para buscar dados de uma API ou banco de dados e **TanStack Table** para exibir, filtrar e ordenar esses dados em uma tabela interativa.

Awesome Lists containing this project

README

          

# Mini Projeto: Integração de TanStack Query e TanStack Table

Este projeto demonstra como integrar as bibliotecas **TanStack Query** para buscar dados de uma API ou banco de dados e **TanStack Table** para exibir, filtrar e ordenar esses dados em uma tabela interativa.

## Funcionalidades

- Busca de dados usando o **TanStack Query**.
- Exibição dos dados em uma tabela usando o **TanStack Table**.
- Recursos de filtragem e ordenação na tabela.

## Tecnologias Utilizadas

- **React**: Framework principal para construção da interface.
- **TanStack Query**: Gerenciamento de dados assíncronos (fetching e caching).
- **TanStack Table**: Criação de tabelas avançadas e interativas.

## Pré-requisitos

Certifique-se de ter o seguinte instalado:

- Node.js (v14 ou superior)
- npm ou yarn

## Configuração do Projeto

1. Clone o repositório:

```bash
git clone https://github.com/Jay-Ubisse/tanstack-query-table.git
cd tanstack-query-table
```

2. Instale as dependências:

```bash
npm install
# ou
yarn install
```

3. Execute o projeto:

```bash
npm run dev
# ou
yarn dev
```

4. Abra no navegador em `http://localhost:5173`.

## Estrutura de Arquivos

```plaintext
src/
├── components/table
│ ├── table-instance.jsx # Componente principal da tabela (usando Tanstack table)
│ ├── index.jsx # Componente para carregamento dos dados (usando Tanstack query)
├── providers/
│ ├── react-query.tsx # Hook para poder usar o react-query no projecto (usando no main.tsx)
├── App.jsx # Componente principal
├── main.jsx # Arquivo de entrada
├── index.css # Estilos globais
```

## Como Funciona

### 1. Busca de Dados com TanStack Query

Usamos o hook `useQuery` do TanStack Query para buscar dados de uma API:

```javascript
import { useQuery } from "@tanstack/react-query";
import { getUsers } from "../../services/users";
import { TableInstance } from "./table-instance";

export function TanstckTable() {
const { isPending, error, data } = useQuery({
queryKey: ["repoData"],
queryFn: () => getUsers(),
});

if (isPending) return "Loading...";

if (error) return "An error has occurred: " + error.message;

if (!data || data.length === 0 || data.length < 0)
return "No available data to display";

return (




);
}
```

### 2. Configuração da Tabela com TanStack Table

Criamos as colunas e definimos os dados para exibição:

```javascript
import { useEffect, useMemo, useReducer, useState } from "react";
import {
Column,
ColumnDef,
ColumnFiltersState,
RowData,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { UserProps } from "../../types/users";

declare module "@tanstack/react-table" {
//allows us to define custom properties for our columns
interface ColumnMeta {
filterVariant?: "text" | "range" | "select";
}
}

export function TableInstance({ data }: { data: UserProps[] }) {
const [columnFilters, setColumnFilters] = useState([]);
const rerender = useReducer(() => ({}), {})[1];

const columns = useMemo[]>(
() => [
{
accessorKey: "id",
header: "ID",
cell: (info) => info.getValue(),
},
{
accessorFn: (row) => row.name,
id: "name",
cell: (info) => info.getValue(),
header: () => Name,
},
{
accessorFn: (row) => row.email,
id: "email",
cell: (info) => info.getValue(),
header: () => Email,
},
{
accessorFn: (row) => row.phone,
id: "phone",
cell: (info) => info.getValue(),
header: () => Phone,
},
{
accessorFn: (row) => row.website,
id: "website",
cell: (info) => info.getValue(),
header: () => Website,
},
{
accessorKey: "username",
header: "Username",
meta: {
filterVariant: "select",
},
},
],
[]
);

const table = useReactTable({
data,
columns,
filterFns: {},
state: {
columnFilters,
},
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(), //client side filtering
getSortedRowModel: getSortedRowModel(),
getPaginationRowModel: getPaginationRowModel(),
debugTable: true,
debugHeaders: true,
debugColumns: false,
});

return (




{table.getHeaderGroups().map((headerGroup) => (

{headerGroup.headers.map((header) => {
return (

{header.isPlaceholder ? null : (
<>

{flexRender(
header.column.columnDef.header,
header.getContext()
)}
{{
asc: " 🔼",
desc: " 🔽",
}[header.column.getIsSorted() as string] ?? null}

{header.column.getCanFilter() ? (



) : null}
>
)}

);
})}

))}


{table.getRowModel().rows.map((row) => {
return (

{row.getVisibleCells().map((cell) => {
return (

{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}

);
})}

);
})}




table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
>
{"<<"}

table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
{"<"}

table.nextPage()}
disabled={!table.getCanNextPage()}
>
{">"}

table.setPageIndex(table.getPageCount() - 1)}
disabled={!table.getCanNextPage()}
>
{">>"}


Page


{table.getState().pagination.pageIndex + 1} of{" "}
{table.getPageCount()}



| Go to page:
{
const page = e.target.value ? Number(e.target.value) - 1 : 0;
table.setPageIndex(page);
}}
className="border p-1 rounded w-16"
/>

{
table.setPageSize(Number(e.target.value));
}}
>
{[10, 20, 30, 40, 50].map((pageSize) => (

Show {pageSize}

))}


{table.getPrePaginationRowModel().rows.length} Rows


rerender()}>Force Rerender


console.log("Add a function to refresh data")}>
Refresh Data



{JSON.stringify(
{ columnFilters: table.getState().columnFilters },
null,
2
)}


);
}

function Filter({ column }: { column: Column }) {
const columnFilterValue = column.getFilterValue();
const { filterVariant } = column.columnDef.meta ?? {};

return filterVariant === "range" ? (



{/* See faceted column filters example for min max values functionality */}

column.setFilterValue((old: [number, number]) => [value, old?.[1]])
}
placeholder={`Min`}
className="w-24 border shadow rounded"
/>

column.setFilterValue((old: [number, number]) => [old?.[0], value])
}
placeholder={`Max`}
className="w-24 border shadow rounded"
/>



) : filterVariant === "select" ? (
column.setFilterValue(e.target.value)}
value={columnFilterValue?.toString()}
>
{/* See faceted column filters example for dynamic select options */}
All
Samantha
Bret
Antonette

) : (
column.setFilterValue(value)}
placeholder={`Search...`}
type="text"
value={(columnFilterValue ?? "") as string}
/>
// See faceted column filters example for datalist search suggestions
);
}

// A typical debounced input react component
function DebouncedInput({
value: initialValue,
onChange,
debounce = 500,
...props
}: {
value: string | number;
onChange: (value: string | number) => void;
debounce?: number;
} & Omit, "onChange">) {
const [value, setValue] = useState(initialValue);

useEffect(() => {
setValue(initialValue);
}, [initialValue]);

useEffect(() => {
const timeout = setTimeout(() => {
onChange(value);
}, debounce);

return () => clearTimeout(timeout);
}, [value]);

return (
setValue(e.target.value)}
/>
);
}

```

### 3. Integração no Componente Principal

```javascript
import { TanstckTable } from "./components/table";

function App() {
return (
<>

>
);
}

export default App;
```

## Recursos Adicionais

- [TanStack Query Documentation](https://tanstack.com/query/latest/docs/framework/react/overview)
- [TanStack Table Documentation](https://tanstack.com/table/latest/docs/introduction)
- [Vite Documentation](https://vitejs.dev/)

---

[Link para visualização do projecto](https://tanstack-query-table.vercel.app/)
Desenvolvido com ❤️ por [Jay-Ubisse](https://github.com/Jay-Ubisse/).