Erinnern Sie sich an unsere vorherige Diskussion über das Ersetzen des traditionellen fetch useState useEffect
-Ansatzes durch React-TanStack-Query? Wenn Sie die Grundlagen verwendet haben – Einrichten von QueryProvider
, Schreiben grundlegender Abfragen und Umgang mit Mutationen – haben Sie die Vorteile wahrscheinlich bereits erlebt. Allerdings haben wir gerade erst begonnen, seine Fähigkeiten zu erkunden.
Lassen Sie uns tiefer in fortgeschrittene Techniken eintauchen, die Ihren Datenabruf erheblich verbessern und die Leistung Ihrer Anwendung von „gut“ in „außergewöhnlich schnell“ verwandeln.
Unser vorheriger Leitfaden zeigte eine einfache Filmauflistung mit React-TanStack-Query:
<code class="language-javascript">const { data: movies, error, isLoading } = useQuery(['movies'], fetchMovies);</code>
Das ist ein guter Ausgangspunkt, aber was wäre, wenn wir eine Reaktionsfähigkeit auf Netflix-Niveau anstreben? Lassen Sie uns unsere Techniken verbessern.
Unsere anfängliche Filmliste erforderte, dass Benutzer nach dem Klicken warten mussten. Wir können das drastisch verbessern:
<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>
Sobald Benutzer mit der Maus über einen Film fahren, werden die Details vorgeladen – sofortiger Zugriff beim Klicken! ✨
In unserem ersten Artikel ging es um grundlegende Mutationen. Optimieren wir sie mit optimistischen Updates:
<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>
Sequentielles Laden gehört der Vergangenheit an:
<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>
Lassen Sie uns unser paginiertes Beispiel auf nahtloses, unendliches Scrollen aktualisieren:
<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>
Dies ist eine Funktion, die in unserem ersten Artikel nicht verfügbar ist: Next.js 14-Serverkomponentenintegration:
<code class="language-javascript">const { data: movies, error, isLoading } = useQuery(['movies'], fetchMovies);</code>
<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>
<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>
<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>
Wir haben seit unserer ursprünglichen Einrichtung erhebliche Fortschritte gemacht! Diese Verbesserungen sind entscheidend für die Schaffung eines wirklich außergewöhnlichen Benutzererlebnisses.
Denken Sie daran, dass Sie nicht alles auf einmal umsetzen müssen. Beginnen Sie mit den Grundlagen und integrieren Sie diese Optimierungen nach Bedarf schrittweise.
Wenn sich das nächste Mal jemand zur Geschwindigkeit Ihrer Anwendung äußert, werden Sie genau wissen, warum sie so beeindruckend ist. ?
Viel Spaß beim Codieren! React-TanStack-Query bietet endlose Möglichkeiten. Was sollten wir als nächstes erkunden?
Das obige ist der detaillierte Inhalt vonBringen Sie React-TanStack-Query in Next.js auf die nächste Ebene. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!