tanstack

``

  • Backend
  • TanStack High Quality Open-Source Software for Web Developers-

Qué es TanStack

TanStack es un conjunto de bibliotecas open-source de alta calidad para desarrollo web, diseñadas para ser flexibles, performantes y fáciles de integrar en distintos frameworks. Se centra principalmente en la gestión de estado, datos y renderizado de tablas y listas complejas.

Principales librerías de TanStack

  • TanStack Query
    • Manejo de datos asincrónicos y caché de manera eficiente.
    • Facilita la sincronización del estado remoto con la UI.
    • Soporta consultas y mutaciones, con reintentos automáticos y refetching.
    • Ejemplo básico:

      Ejemplo: TanStack Query

import { useQuery } from '@tanstack/react-query';

function fetchUser() {
	return fetch('/api/user').then(res => res.json());
}

export default function User() {
	const { data, error, isLoading } = useQuery(['user'], fetchUser);

	if (isLoading) return 'Cargando...';
	if (error) return 'Error al cargar usuario';

	return <div>{data.name}</div>;
}
  • TanStack Table
    • Herramienta para construir tablas altamente personalizables y performantes.
    • Permite sorting, filtering, pagination y virtualización de filas.
    • Totalmente agnóstico del framework de UI.
    • Ejemplo básico:

Ejemplo: TanStack Table

import { useReactTable, getCoreRowModel } from '@tanstack/react-table';

const data = [{ name: 'Eduardo', age: 30 }];
const columns = [{ accessorKey: 'name', header: 'Nombre' }, { accessorKey: 'age', header: 'Edad' }];

const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel() });

return (
	<table>
		<thead>
			{table.getHeaderGroups().map(headerGroup => (
				<tr key={headerGroup.id}>
					{headerGroup.headers.map(header => <th key={header.id}>{header.isPlaceholder ? null : header.column.columnDef.header}</th>)}
				</tr>
			))}
		</thead>
		<tbody>
			{table.getRowModel().rows.map(row => (
				<tr key={row.id}>
					{row.getVisibleCells().map(cell => <td key={cell.id}>{cell.getValue()}</td>)}
				</tr>
			))}
		</tbody>
	</table>
);
  • TanStack Router
    • Enrutamiento declarativo para aplicaciones modernas.
    • Soporta rutas anidadas y lazy loading.
    • Integración sencilla con React y otros frameworks.
    • Ejemplo básico:

Ejemplo: TanStack Router

import { Router, Route } from '@tanstack/router';

const router = new Router({
	routes: [
		{
			path: '/',
			component: Home,
		},
		{
			path: '/about',
			component: About,
		},
	],
});

function App() {
	return <router.Provider />;
}

Beneficios de usar TanStack

  • Librerías ligeras y altamente optimizadas.
  • API consistente entre librerías.
  • Excelente documentación y comunidad activa.
  • Compatible con múltiples frameworks y librerías de UI.
  • Facilita la gestión de datos y estado sin recurrir a soluciones más pesadas.

Buenas prácticas

  • Separar la lógica de datos de la UI usando TanStack Query.
  • Usar memoización y virtualización en tablas grandes con TanStack Table.
  • Definir rutas de manera declarativa y centralizada con TanStack Router.
  • Mantener consistencia en nombres de queries y keys para facilitar refetching y cache.

tankstack mas

Estrategias avanzadas en TanStack Query

  • Caching y persistencia
    • Configuración de cacheTime y staleTime para optimizar rendimiento.
    • Persistencia en localStorage o IndexedDB para mantener datos entre sesiones.
    • Ejemplo de cache persistente:
	import { persistQueryClient } from '@tanstack/query-persist-client';
	import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister';
	import { QueryClient } from '@tanstack/react-query';

	const queryClient = new QueryClient();
	const persister = createSyncStoragePersister({ storage: window.localStorage });

	persistQueryClient({ queryClient, persister });
	```


- **Paginación y fetching infinito**
	- Soporta paginación automática y fetch de páginas siguientes según scroll o interacción.
	- Ejemplo de fetching infinito:
	
```javascript
	const { data, fetchNextPage, hasNextPage } = useInfiniteQuery(
		['posts'],
		({ pageParam = 0 }) => fetch(`/api/posts?page=${pageParam}`).then(res => res.json()),
		{
			getNextPageParam: lastPage => lastPage.nextCursor ?? undefined,
		}
	);
	```


- **Sincronización en tiempo real**
	- Refetching automático al volver a foco o reconectar la app.
	- Integración con websockets o SSE para actualizaciones instantáneas.

## Integración con TypeScript
- Todas las librerías TanStack están diseñadas para TypeScript.
- Permite tipado seguro en queries, mutaciones y tablas.
- Ejemplo con Tipos en TanStack Table:

```typescript
interface User {
	id: number;
	name: string;
	age: number;
}

const columns = [
	{ accessorKey: 'id', header: 'ID' },
	{ accessorKey: 'name', header: 'Nombre' },
	{ accessorKey: 'age', header: 'Edad' },
] as const;

const data: User[] = [{ id: 1, name: 'Eduardo', age: 30 }];

`

Testing y buenas prácticas

  • Usar mock de queries para pruebas unitarias y de integración.
  • Evitar lógica compleja dentro de componentes; delegar a hooks personalizados.
  • Separar la definición de tablas y columnas en archivos independientes para escalabilidad.
  • Mantener consistencia en nomenclatura de queries y rutas para debugging más sencillo.

Casos de uso reales

  • Dashboards con tablas y filtros complejos utilizando TanStack Table.
  • Apps con datos en tiempo real y sincronización offline con TanStack Query.
  • SPAs con rutas anidadas y lazy loading usando TanStack Router.
  • Aplicaciones que requieren tipado estricto y escalabilidad gracias a TypeScript.

Recursos adicionales

Recomendaciones finales

  • Evaluar qué librerías del stack se necesitan según el proyecto.
  • Usar TanStack Query para manejo de datos, Table para visualización y Router para navegación.
  • Combinar con buenas prácticas de caching, paginación y testing para proyectos escalables.

tankstack avanzado

  • Backend
  • TanStack High Quality Open-Source Software for Web Developers-

Tablas avanzadas con TanStack Table

  • Filtros dinámicos
    • Permite crear filtros que se aplican sobre múltiples columnas.
    • Ejemplo:
	const [globalFilter, setGlobalFilter] = useState('');
	const table = useReactTable({
		data,
		columns,
		state: { globalFilter },
		onGlobalFilterChange: setGlobalFilter,
		getFilteredRowModel: getFilteredRowModel(),
	});
	```


- **Sorting múltiple**
	- Ordenamiento por varias columnas con prioridad definida.
	
```javascript
	const table = useReactTable({
		data,
		columns,
		state: { sorting },
		onSortingChange: setSorting,
		getSortedRowModel: getSortedRowModel(),
	});
	```


- **Paginación controlada y virtualización**
	- Virtualización para manejar miles de filas sin impactar el rendimiento.
	
```javascript
	import { useVirtual } from '@tanstack/react-virtual';

	const rowVirtualizer = useVirtual({
		size: table.getRowModel().rows.length,
		parentRef,
		estimateSize: () => 35,
	});

	return (
		<div ref={parentRef} style={{ height: `300px`, overflow: 'auto' }}>
			<div style={{ height: `${rowVirtualizer.totalSize}px`, position: 'relative' }}>
				{rowVirtualizer.virtualItems.map(virtualRow => {
					const row = table.getRowModel().rows[virtualRow.index];
					return (
						<div key={row.id} style={{ position: 'absolute', top: 0, transform: `translateY(${virtualRow.start}px)` }}>
							{row.getVisibleCells().map(cell => <span key={cell.id}>{cell.getValue()}</span>)}
						</div>
					);
				})}
			</div>
		</div>
	);
	```


## Mutaciones optimistas con TanStack Query
- Actualiza la UI inmediatamente mientras la mutación se procesa.
- Manejo de errores y rollback en caso de fallo.

```javascript
const queryClient = useQueryClient();

const mutation = useMutation(addPost, {
	onMutate: async newPost => {
		await queryClient.cancelQueries(['posts']);
		const previousPosts = queryClient.getQueryData(['posts']);
		queryClient.setQueryData(['posts'], old => [...old, newPost]);
		return { previousPosts };
	},
	onError: (err, newPost, context) => {
		queryClient.setQueryData(['posts'], context.previousPosts);
	},
	onSettled: () => {
		queryClient.invalidateQueries(['posts']);
	},
});

`

Rutas anidadas y lazy loading con TanStack Router

  • Permite organizar aplicaciones grandes de manera escalable.
const router = new Router({
	routes: [
		{
			path: '/',
			component: Home,
			children: [
				{
					path: 'dashboard',
					component: lazy(() => import('./Dashboard')),
				},
				{
					path: 'profile/:id',
					component: Profile,
				},
			],
		},
	],
});

Suscripción a datos en tiempo real

  • Combina TanStack Query con WebSockets o SSE.
useEffect(() => {
	const ws = new WebSocket('wss://example.com/data');
	ws.onmessage = event => {
		const newData = JSON.parse(event.data);
		queryClient.setQueryData(['liveData'], newData);
	};
	return () => ws.close();
}, [queryClient]);

Estrategias de caching avanzadas

  • Cache con TTL por query.
  • Persistencia en localStorage o IndexedDB para offline.
  • Ejemplo de cache con expiración:
const queryClient = new QueryClient({
	defaultOptions: {
		queries: {
			staleTime: 1000 * 60 * 5, // 5 minutos
			cacheTime: 1000 * 60 * 60, // 1 hora
		},
	},
});

Buenas prácticas avanzadas

  • Separar hooks personalizados para queries y mutaciones complejas.
  • Usar TypeScript para tipado estricto de datos y columnas.
  • Organizar rutas y tablas en módulos independientes para escalabilidad.
  • Documentar keys de queries y rutas para mantener consistencia.

Recursos adicionales y útiles