Maison > interface Web > js tutoriel > Faire passer React-TanStack-Query au niveau supérieur dans Next.js

Faire passer React-TanStack-Query au niveau supérieur dans Next.js

Linda Hamilton
Libérer: 2025-01-22 20:40:10
original
549 Les gens l'ont consulté

Taking React-TanStack-Query to the Next Level in Next.js

Vous vous souvenez de notre discussion précédente sur le remplacement de l'approche traditionnelle fetch useState useEffect par React-TanStack-Query ? Si vous avez utilisé les principes fondamentaux (configuration de QueryProvider, rédaction de requêtes de base et gestion des mutations), vous en avez probablement déjà profité. Cependant, nous commençons tout juste à explorer ses capacités.

Approfondissons les techniques avancées qui amélioreront considérablement la récupération de vos données, transformant les performances de votre application de « bonnes » à « exceptionnellement rapides ».

Construire une fondation plus solide

Notre guide précédent présentait une liste de films de base à l'aide de React-TanStack-Query :

<code class="language-javascript">const { data: movies, error, isLoading } = useQuery(['movies'], fetchMovies);</code>
Copier après la connexion
Copier après la connexion

C'est un excellent point de départ, mais et si nous visions une réactivité de niveau Netflix ? Élevons nos techniques.

Techniques avancées pour des performances supérieures

1. Prélecture intelligente (atteinte d'une vitesse semblable à celle de Netflix)

Notre liste de films initiale obligeait les utilisateurs à attendre après avoir cliqué. Nous pouvons considérablement améliorer cela :

<code class="language-javascript">// components/MovieList.jsx
import { useQueryClient } from '@tanstack/react-query';

export default function MovieList() {
  const queryClient = useQueryClient();

  // Leveraging our existing fetchMovies function
  const prefetchMovie = async (movieId) => {
    await queryClient.prefetchQuery({
      queryKey: ['movie', movieId],
      queryFn: () => fetchMovieDetails(movieId),
      // Maintain freshness for 5 minutes
      staleTime: 5 * 60 * 1000,
    });
  };

  return (
    <div className="grid grid-cols-4 gap-4">
      {movies.map(movie => (
        <div key={movie.id} onMouseEnter={() => prefetchMovie(movie.id)}
          className="movie-card"
        >
          {movie.title}
        </div>
      ))}
    </div>
  );
}</code>
Copier après la connexion
Copier après la connexion

Désormais, lorsque les utilisateurs survolent un film, les détails sont préchargés : accès instantané en cliquant ! ✨

2. Amélioration des mutations (vous vous en souvenez ?)

Notre article initial couvrait les mutations fondamentales. Optimisons-les avec des mises à jour optimistes :

<code class="language-javascript">// hooks/useUpdateMovie.js
export function useUpdateMovie() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: updateMovie,
    // The key improvement
    onMutate: async (newMovie) => {
      // Halt ongoing refetches
      await queryClient.cancelQueries(['movie', newMovie.id]);

      // Store current state (for rollback if needed)
      const previousMovie = queryClient.getQueryData(['movie', newMovie.id]);

      // Immediate (optimistic) update
      queryClient.setQueryData(['movie', newMovie.id], newMovie);

      return { previousMovie };
    },
    // Error handling
    onError: (err, newMovie, context) => {
      queryClient.setQueryData(
        ['movie', newMovie.id],
        context.previousMovie
      );
    },
  });
}</code>
Copier après la connexion
Copier après la connexion

3. Chargement de données parallèle (élimine les attentes inutiles)

Le chargement séquentiel appartient au passé :

<code class="language-javascript">// pages/movie/[id].js
export default function MoviePage({ movieId }) {
  const results = useQueries({
    queries: [
      {
        queryKey: ['movie', movieId],
        queryFn: () => fetchMovie(movieId),
      },
      {
        queryKey: ['cast', movieId],
        queryFn: () => fetchCast(movieId),
      },
      {
        queryKey: ['reviews', movieId],
        queryFn: () => fetchReviews(movieId),
      },
    ],
  });

  if (results.some(result => result.isLoading)) {
    return <LoadingSpinner />;
  }

  const [movie, cast, reviews] = results.map(r => r.data);

  return <MovieDetails cast={cast} movie={movie} reviews={reviews} />;
}</code>
Copier après la connexion
Copier après la connexion

4. Implémentation du défilement infini (la manière efficace)

Améliorons notre exemple paginé vers un défilement infini transparent :

<code class="language-javascript">// components/InfiniteMovieList.jsx
import { useInfiniteQuery } from '@tanstack/react-query';
import { useInView } from 'react-intersection-observer';

export default function InfiniteMovieList() {
  const { ref, inView } = useInView();

  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery({
    queryKey: ['movies'],
    queryFn: fetchMoviePage,
    getNextPageParam: (lastPage) => lastPage.nextCursor,
  });

  useEffect(() => {
    if (inView && hasNextPage) {
      fetchNextPage();
    }
  }, [inView, hasNextPage]);

  return (
    <div>
      {data.pages.map((page) => (
        page.movies.map((movie) => (
          <MovieCard key={movie.id} movie={movie} />
        ))
      ))}

      <div ref={ref}>
        {isFetchingNextPage ? <LoadingSpinner /> : null}
      </div>
    </div>
  );
}</code>
Copier après la connexion

5. Tirer parti des composants du serveur Next.js 14

Il s'agit d'une fonctionnalité non disponible dans notre premier article : Intégration des composants serveur Next.js 14 :

<code class="language-javascript">const { data: movies, error, isLoading } = useQuery(['movies'], fetchMovies);</code>
Copier après la connexion
Copier après la connexion

Conseils de pro (leçons apprises)

  1. Clés de requête cohérentes : Affinez nos clés de requête de film :
<code class="language-javascript">// components/MovieList.jsx
import { useQueryClient } from '@tanstack/react-query';

export default function MovieList() {
  const queryClient = useQueryClient();

  // Leveraging our existing fetchMovies function
  const prefetchMovie = async (movieId) => {
    await queryClient.prefetchQuery({
      queryKey: ['movie', movieId],
      queryFn: () => fetchMovieDetails(movieId),
      // Maintain freshness for 5 minutes
      staleTime: 5 * 60 * 1000,
    });
  };

  return (
    <div className="grid grid-cols-4 gap-4">
      {movies.map(movie => (
        <div key={movie.id} onMouseEnter={() => prefetchMovie(movie.id)}
          className="movie-card"
        >
          {movie.title}
        </div>
      ))}
    </div>
  );
}</code>
Copier après la connexion
Copier après la connexion
  1. Récupération intelligente : améliorez notre récupération de base sur le focus de la fenêtre :
<code class="language-javascript">// hooks/useUpdateMovie.js
export function useUpdateMovie() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: updateMovie,
    // The key improvement
    onMutate: async (newMovie) => {
      // Halt ongoing refetches
      await queryClient.cancelQueries(['movie', newMovie.id]);

      // Store current state (for rollback if needed)
      const previousMovie = queryClient.getQueryData(['movie', newMovie.id]);

      // Immediate (optimistic) update
      queryClient.setQueryData(['movie', newMovie.id], newMovie);

      return { previousMovie };
    },
    // Error handling
    onError: (err, newMovie, context) => {
      queryClient.setQueryData(
        ['movie', newMovie.id],
        context.previousMovie
      );
    },
  });
}</code>
Copier après la connexion
Copier après la connexion
  1. Gestion robuste des erreurs : améliorez notre gestion des erreurs de base :
<code class="language-javascript">// pages/movie/[id].js
export default function MoviePage({ movieId }) {
  const results = useQueries({
    queries: [
      {
        queryKey: ['movie', movieId],
        queryFn: () => fetchMovie(movieId),
      },
      {
        queryKey: ['cast', movieId],
        queryFn: () => fetchCast(movieId),
      },
      {
        queryKey: ['reviews', movieId],
        queryFn: () => fetchReviews(movieId),
      },
    ],
  });

  if (results.some(result => result.isLoading)) {
    return <LoadingSpinner />;
  }

  const [movie, cast, reviews] = results.map(r => r.data);

  return <MovieDetails cast={cast} movie={movie} reviews={reviews} />;
}</code>
Copier après la connexion
Copier après la connexion

Choisir la bonne technique

  • Requêtes de base (extraites de notre premier article) : idéales pour une récupération de données simple.
  • Prélecture : idéale lorsque les actions de l'utilisateur sont prévisibles.
  • Requêtes parallèles : à utiliser lorsque plusieurs ensembles de données indépendants sont nécessaires.
  • Requêtes infinies : convient aux listes longues et déroulantes.
  • Mises à jour optimistes : utilisez-les pour cette expérience utilisateur instantanée.

Conclusion

Nous avons considérablement avancé par rapport à notre configuration initiale ! Ces améliorations sont cruciales pour créer une expérience utilisateur vraiment exceptionnelle.

N'oubliez pas que vous n'avez pas besoin de tout mettre en œuvre en même temps. Commencez par les bases, puis intégrez progressivement ces optimisations selon les besoins.

La prochaine fois que quelqu'un commentera la vitesse de votre application, vous saurez exactement pourquoi elle est si impressionnante. ?

Bon codage ! React-TanStack-Query offre des possibilités infinies. Que devrions-nous explorer ensuite ?

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal