kb.erickguedes.com
TanStack: Ecossistema de Bibliotecas

TanStack Virtual e Charts

Aula 5 de 5

TanStack Virtual

O TanStack Virtual (antigo React Virtual) permite renderizar apenas os elementos visíveis em listas grandes, mantendo performance mesmo com milhões de itens.

useVirtualizer — Lista Vertical

import { useVirtualizer } from '@tanstack/react-virtual'
import { useRef } from 'react'

function VirtualList() {
  const parentRef = useRef<HTMLDivElement>(null)

  const items = Array.from({ length: 100000 }, (_, i) => ({
    id: i,
    text: `Item ${i + 1}`,
  }))

  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 50, // altura estimada em px
    overscan: 5, // itens extras fora da viewport
  })

  return (
    <div ref={parentRef} style={{ height: '500px', overflow: 'auto' }}>
      <div style={{ height: `${virtualizer.getTotalSize()}px`, position: 'relative' }}>
        {virtualizer.getVirtualItems().map(virtualItem => (
          <div
            key={virtualItem.key}
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              height: `${virtualItem.size}px`,
              transform: `translateY(${virtualItem.start}px)`,
            }}
          >
            {items[virtualItem.index].text}
          </div>
        ))}
      </div>
    </div>
  )
}

Virtualização Horizontal

import { useVirtualizer } from '@tanstack/react-virtual'

const virtualizer = useVirtualizer({
  horizontal: true,
  count: items.length,
  getScrollElement: () => parentRef.current,
  estimateSize: () => 200,
})

Dynamic Measurements

import { useVirtualizer } from '@tanstack/react-virtual'

const virtualizer = useVirtualizer({
  count: messages.length,
  getScrollElement: () => parentRef.current,
  estimateSize: () => 80,
  measureElement: (el) => el.getBoundingClientRect().height, // mede altura real
})

Smooth Scroll e Scroll to Index

// Scroll suave para um índice específico
virtualizer.scrollToIndex(5000, { align: 'center', smoothScroll: true })

// Detectar fim da lista (infinite scroll)
useEffect(() => {
  const lastItem = virtualizer.getVirtualItems().at(-1)
  if (lastItem && lastItem.index >= items.length - 2) {
    loadMore()
  }
}, [virtualizer.getVirtualItems()])

TanStack Charts

TanStack Charts (ex React Charts) é a biblioteca de gráficos headless do ecossistema TanStack — totalmente customizável e extensível.

Configuração

npm install @tanstack/react-charts

Gráfico de Barras

import { Chart } from '@tanstack/react-charts'

const data = [
  { month: 'Jan', vendas: 4000 },
  { month: 'Fev', vendas: 3000 },
  { month: 'Mar', vendas: 5000 },
]

function BarChart() {
  return (
    <Chart
      options={{
        data: {
          labels: data.map(d => d.month),
          datasets: [
            {
              label: 'Vendas',
              data: data.map(d => d.vendas),
            },
          ],
        },
        series: { type: 'bar' },
        axes: [
          { type: 'category', position: 'bottom' },
          { type: 'linear', position: 'left' },
        ],
        tooltip: { show: true },
      }}
    />
  )
}

Gráfico de Linha com Múltiplas Séries

const data = [
  { month: 'Jan', receita: 4000, custo: 2500 },
  { month: 'Fev', receita: 3000, custo: 2000 },
  { month: 'Mar', receita: 5000, custo: 3100 },
]

function LineChart() {
  return (
    <Chart
      options={{
        data: {
          labels: data.map(d => d.month),
          datasets: [
            { label: 'Receita', data: data.map(d => d.receita) },
            { label: 'Custo', data: data.map(d => d.custo) },
          ],
        },
        series: { type: 'line' },
        axes: [
          { type: 'category', position: 'bottom' },
          { type: 'linear', position: 'left', min: 0 },
        ],
        tooltip: { show: true },
        responsive: true,
      }}
    />
  )
}

Gráfico de Pizza

<Chart
  options={{
    data: {
      labels: ['Frontend', 'Backend', 'Mobile'],
      datasets: [{ data: [12, 8, 5] }],
    },
    series: { type: 'pie' },
    tooltip: { show: true },
  }}
/>

Responsividade e Customização de Eixos

<Chart
  options={{
    responsive: true,
    maintainAspectRatio: false,
    axes: [
      {
        type: 'time',
        position: 'bottom',
        ticks: { maxTicksLimit: 10 },
      },
      {
        type: 'linear',
        position: 'left',
        title: 'Valor (R$)',
        grid: { color: '#e2e8f0', dashed: true },
      },
    ],
    tooltip: {
      show: true,
      render: ({ title, items }) => (
        <div className="custom-tooltip">
          <strong>{title}</strong>
          {items.map(item => <div key={item.label}>{item.label}: {item.value}</div>)}
        </div>
      ),
    },
  }}
/>

Lab: Dashboard com Virtualização e Gráficos

npm create vite@latest dashboard-full -- --template react-ts
cd dashboard-full
npm install @tanstack/react-virtual @tanstack/react-charts
// Construa um dashboard:
// 1. Lista virtualizada de 10000 transações
// 2. Gráfico de linha mostrando receita mensal
// 3. Gráfico de barras comparativo por categoria
// 4. Tooltip customizado no gráfico
// 5. Scroll suave para topo via scrollToIndex

TanStack Virtual + Charts oferecem performance e flexibilidade totais para dashboards ricos, renderizando milhões de itens sem degradação.