Pourquoi TanStack Query avec Vue : guide complet ?
TanStack Query est une bibliothèque JavaScript de gestion d'état côté client conçue pour simplifier l'accès aux données et la mise à jour des états réactifs dans vos applications web. Avec un contexte réel, imaginez le cas où vous travaillez sur une application e-commerce, et vous avez besoin d'actualiser les prix en temps réel lorsque le marché financier change. TanStack Query peut être utilisé pour récupérer les données de l'API de marché financier et mettre à jour les états de votre application en conséquence.
Prerequis
- Connaissance de base de Vue.js
- Compréhension des concepts de gestion d'état (state management) en Vue.js
- Node.js v14 ou plus récent installé sur votre machine
- Vue CLI v4 ou plus récent installé
- Git pour le versionnement et la gestion du code
Concepts fondamentaux
1. useQuery
useQuery est l'un des hooks principaux de TanStack Query qui permet d'effectuer des requêtes asynchrones et de gérer leur état (loading, error, data).
<template>
<div v-if="isLoading">Loading...</div>
<div v-else-if="isError">Error: isError.message</div>
<div v-else>data</div>
</template>
<script setup>
import { useQuery } from '@tanstack/vue-query'
import axios from 'axios'
const fetchPosts = async () => {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts')
return response.data
}
const { isLoading, isError, data } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
})
</script>
2. useMutation
useMutation est utilisé pour effectuer des mutations (opérations CRUD) et gérer leur état.
<template>
<button @click="createPost">Create Post</button>
<div v-if="isSuccess">Post created!</div>
<div v-else-if="isError">Error: isError.message</div>
</template>
<script setup>
import { useMutation } from '@tanstack/vue-query'
import axios from 'axios'
const createPost = async () => {
const response = await axios.post('https://jsonplaceholder.typicode.com/posts', {
title: 'foo',
body: 'bar',
userId: 1,
})
return response.data
}
const { isLoading, isError, isSuccess } = useMutation({
mutationFn: createPost,
})
</script>
3. useInfiniteQuery
useInfiniteQuery est utilisé pour gérer les requêtes infinies en paginant automatiquement.
<template>
<div v-if="isLoading">Loading...</div>
<div v-else-if="isError">Error: isError.message</div>
<ul v-else>
<li v-for="post in data.pages.flatMap(page => page)" :key="post.id">post.title</li>
</ul>
</template>
<script setup>
import { useInfiniteQuery } from '@tanstack/vue-query'
import axios from 'axios'
const fetchPosts = async ({ pageParam = 1 }) => {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts', {
params: { _page: pageParam, _limit: 5 },
})
return response.data
}
const { isLoading, isError, data } = useInfiniteQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
getNextPageParam: lastPage => (lastPage.length < 5 ? undefined : lastPage.length + 1),
})
</script>
Mise en pratique : projet fil rouge
Étape 1 : Créer un nouveau projet Vue.js
npm init vue@latest my-tanstack-query-project
cd my-tanstack-query-project
npm install @tanstack/vue-query axios
Étape 2 : Configurer le projet
Créez un fichier src/api/postsApi.js pour gérer les requêtes à l'API de posts.
// src/api/postsApi.js
import axios from 'axios'
const fetchPosts = async ({ pageParam = 1 }) => {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts', {
params: { _page: pageParam, _limit: 5 },
})
return response.data
}
export default {
fetchPosts,
}
Étape 3 : Créer un composant pour afficher les posts
Créez un fichier src/components/PostsList.vue.
<template>
<div v-if="isLoading">Loading...</div>
<div v-else-if="isError">Error: isError.message</div>
<ul v-else>
<li v-for="post in data.pages.flatMap(page => page)" :key="post.id">post.title</li>
</ul>
</template>
<script setup>
import { useInfiniteQuery } from '@tanstack/vue-query'
import postsApi from '@/api/postsApi'
const { isLoading, isError, data } = useInfiniteQuery({
queryKey: ['posts'],
queryFn: postsApi.fetchPosts,
getNextPageParam: lastPage => (lastPage.length < 5 ? undefined : lastPage.length + 1),
})
</script>
Étape 4 : Intégrer le composant dans la page principale
Modifiez src/App.vue pour inclure le composant PostsList.
<template>
<div id="app">
<h1>Posts List</h1>
<PostsList />
</div>
</template>
<script setup>
import PostsList from './components/PostsList.vue'
</script>
Étape 5 : Exécuter le projet
npm run dev
Erreurs frequentes et debugging
1. TypeError: Cannot read properties of undefined (reading 'fetch')
Ce problème peut survenir si la fonction de requête n'est pas définie correctement.
## ❌ Mauvais
const { isLoading, isError, data } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
})
## ✅ Correct
const fetchPosts = async () => {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts')
return response.data
}
const { isLoading, isError, data } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
})
2. Error: Network Error
Si vous rencontrez cette erreur, vérifiez que l'URL de votre API est correcte et que le serveur répond bien.
## ❌ Mauvais
const { isLoading, isError, data } = useQuery({
queryKey: ['posts'],
queryFn: () => axios.get('http://localhost:3000/posts')
})
## ✅ Correct
const { isLoading, isError, data } = useQuery({
queryKey: ['posts'],
queryFn: () => axios.get('https://jsonplaceholder.typicode.com/posts')
})
3. Error: QueryObserver retry failed
Si vous rencontrez cette erreur, augmentez le nombre de tentatives de reconnexions.
## ❌ Mauvais
const { isLoading, isError, data } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
})
## ✅ Correct
const { isLoading, isError, data } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
retry: Infinity,
})
Pour aller plus loin
1. Utiliser useMutation pour créer et mettre à jour des données
Explorez comment utiliser useMutation pour ajouter de nouvelles tâches ou modifier les existantes.
2. Gérer les erreurs et le retry avec useQuery
Découvrez comment gérer les erreurs et configurer le nombre de tentatives de reconnexions avec useQuery.
3. Optimiser vos requêtes avec des hooks personnalisés
Apprenez à créer des hooks personnalisés pour optimiser votre code et la lisibilité.
Défi pratique : Créez un mini-projet où vous utilisez TanStack Query pour récupérer les données d'une API de géolocalisation et afficher la position de l'utilisateur sur une carte.